天天看点

设计模式 之 开闭原则(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) 详解

继续阅读