天天看點

設計模式 之 開閉原則(OCP) 詳解

開閉原則(OCP) 詳解

基本介紹:

1)開閉原則(Open Close Principle)是程式設計中最基礎,最重要的設計原則

2)一個軟體實體如類,子產品和函數應該對拓展開放(對提供方),對修改關閉(對使用方)。用抽象建構架構,用實作擴充細節。

3)當軟體需要變化時,盡量通過擴充軟體實體的行為來實作變化,而不是通過修改已有的代碼來實作變化。

4)程式設計中遵循其它原則,以及使用設計模式的目的就是遵循開閉原則。

案例舉例:

public interface MailService {
	void sendMsg(String msg);
}
           

首先我們定義一個功能性接口,表示資訊服務,裡面有個發送資訊的方法。

public class DefaultMailService implements MailService{
	@Override
	public void sendMsg(String msg) {
		// TODO Auto-generated method stub
		System.out.println("message:"+msg);
	}
}

           

以及它的測試類:

public class MailServiceTest {
	static MailService mailService;
	public static void main(String[] args) {
		mailService=new DefaultMailService();
		mailService.sendMsg("nihao");
	}
}
           

接着我們在它的實作類中實作發送資訊的方法。

假如說我們已經将其功能實作完畢。等過一段時間,我們需要對此業務進行擴充,要求顯示出發送資訊的時間。其中的一種寫法便是在DefaultMailService類中直接修改:

public class DefaultMailService implements MailService{
	@Override
	public void sendMsg(String msg) {
		// TODO Auto-generated method stub
		long start = System.currentTimeMillis();
		System.out.println("message:"+msg);
		long end = System.currentTimeMillis();
		System.out.println("time:"+(end-start));
	}
}
           

但是很顯然,根據開閉原則,這種做法在實際的項目中是不可取的,應當滿足對拓展開放,對修改關閉。

對于此,我們有兩種解決辦法:

第一種:通過寫一擴充類繼承實作類進行實作類功能的擴充:

建立一LogMailService類繼承DefaultMailService類并重寫其方法:

public class LogMailService extends DefaultMailService{
	DefaultMailService defaultMailService;
	public LogMailService(DefaultMailService defaultMailService) {
		this.defaultMailService=defaultMailService;
	}
	@Override
	public void sendMsg(String msg) {
		// TODO Auto-generated method stub
		long start = System.currentTimeMillis();
		super.sendMsg(msg);
		long end = System.currentTimeMillis();
		System.out.println("time:"+(end-start));
	}
}
           

在其子類中對sendMsg功能進行了擴充

測試類修改:

public class MailServiceTest {
	static MailService mailService;
	public static void main(String[] args) {
		mailService=new LogMailService(new DefaultMailService());
		mailService.sendMsg("nihao");
	}
}
           

但是這種方法在某些情況下不能使用,比如當defaultMailService用final修飾時,此類便不能被繼承。

第二種方法:通過寫擴充類組合于實作類進行功能的擴充

建立一Log2MailService擴充類實作MailService接口:

public class Log2MailService implements MailService{
	DefaultMailService defaultMailService;
	public Log2MailService(DefaultMailService defaultMailService) {
		this.defaultMailService=defaultMailService;
	}
	@Override
	public void sendMsg(String msg) {
		// TODO Auto-generated method stub
		long start = System.currentTimeMillis();
		defaultMailService.sendMsg(msg);
		long end = System.currentTimeMillis();
		System.out.println("time:"+(end-start));
	}
}
           

實作類修改:

public class MailServiceTest {
	static MailService mailService;
	public static void main(String[] args) {
		mailService=new Log2MailService(new DefaultMailService());
		mailService.sendMsg("nihao");
	}
}
           

思路解析圖:

設計模式 之 開閉原則(OCP) 詳解

繼續閱讀