开闭原则(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");
}
}
思路解析图: