【设计原则】开闭原则
开闭原则,在面向对象编程领域中,规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。
主页传送门:💁 传送
1.开闭原则定义
开闭原则,英文名为Open Close Principle,又称OCP原则。
Software entities like classes, modules and functions should be open for extension but closed for modifications.
即:一个软件实体如类,模块和函数应该对拓展开放,对修改关闭。
2.开闭原则定义解读
开闭原则的核心思想是“开放-扩展,封闭-修改”。这意味着在系统设计时,我们应该将那些可能发生变化的部分抽象出来,然后针对这些抽象接口进行编程。当需求发生变化时,我们只需要扩展新的抽象接口,而不需要修改已有的代码。这样,我们就可以实现代码的可重用性和可维护性,减少系统中的耦合和潜在的错误。
3.开闭原则优缺点
开闭原则的优点包括:
- 提高软件实体的可复用性:使用抽象构建的框架,可以避免重复定义或编码,提高软件实体的可复用性。
- 提高软件实体的可拓展性:基于抽象框架进行拓展新的功能,不修改原来的代码即可完成拓展性。
- 提高软件实体的可维护性:所有的功能特性都是基于抽象框架拓展而成,各个功能特性独立且相互不影响,后期维护目标明确且方便。
然而,开闭原则也存在一些缺点:
- 面向对象的抽象难度大:在刚开始使用抽象构建的框架考虑不全,后期已经拓展了很多功能特性,一旦抽象的基础框架发生变动,下面的拓展部分都有可能受到影响,因此需要很强、很系统的抽象能力把基础框架抽象出来,才能减少后期带来的不必要影响。
4.开闭原则案例分析
我们举例说明什么是开闭原则,以书店销售书籍为例,类图如下:
代码如下:
书籍类接口(IBook):
public interface IBook {
public String getName();
public String getPrice();
public String getAuthor();
}
小说类书籍(NovelBook):
public class NovelBook implements IBook {
private String name;
private int price;
private String author;
public NovelBook(String name,int price,String author){
this.name = name;
this.price = price;
this.author = author;
}
public String getAutor() {
return this.author;
}
public String getName() {
return this.name;
}
public int getPrice() {
return this.price;
}
}
场景类(Client):
public class Client {
public static void main(Strings[] args){
IBook novel = new NovelBook("笑傲江湖",100,"金庸");
System.out.println("书籍名字:"+novel.getName()+"书籍作者:"+novel.getAuthor()+"书籍价格:"+novel.getPrice());
}
}
项目投产生,书籍正常销售,但是我们经常因为各种原因,要打折来销售书籍,这是一个变化,我们要如何应对这样一个需求变化呢?
我们有下面三种方法可以解决此问题:
-
修改接口
在IBook接口中,增加一个方法getOffPrice(),专门用于进行打折处理,所有的实现类实现此方法。但是这样的一个修改方式,实现类NovelBook要修改,同时IBook接口应该是稳定且可靠,不应该经常发生改变,否则接口作为契约的作用就失去了。因此,此方案否定。 -
修改实现类
修改NovelBook类的方法,直接在getPrice()方法中实现打折处理。此方法是有问题的,例如我们如果getPrice()方法中只需要读取书籍的打折前的价格呢?这不是有问题吗?当然我们也可以再增加getOffPrice()方法,这也是可以实现其需求,但是这就有二个读取价格的方法,因此,该方案也不是一个最优方案。 -
通过扩展实现变化
我们可以增加一个子类OffNovelBook,覆写getPrice方法。此方法修改少,对现有的代码没有影响,风险少,是个好办法。
下面是修改后的类图:
代码如下:
打折类(OffNovelBook):
public class OffNovelBook extends NovelBook{
public OffNovelBook(String name,int price,String author){
super(name,price,author);
}
//覆写价格方法,当价格大于40,就打8析,其他价格就打9析
public int getPrice(){
if(this.price > 40){
return this.price * 0.8;
}else{
return this.price * 0.9;
}
}
}
现在打折销售开发完成了,我们只是增加了一个OffNovelBook类,我们修改的代码都是高层次的模块,没有修改底层模块,代码改变量少,可以有效的防止风险的扩散。
5.个人总结
实现开闭原则的关键在于抽象化和模块化。通过抽象化,我们可以将系统中的复杂部分简化为一些简单的抽象接口,从而降低系统的耦合性和复杂性。通过模块化,我们可以将系统划分为一些独立的模块,每个模块都具有明确的功能和接口,从而提高了系统的可重用性和可维护性。
开闭原则的应用场景非常广泛,它可以应用于各种类型的应用程序和系统设计。实现开闭原则的步骤包括定义抽象接口、实现具体类、实现适配器以及扩展新的抽象接口。
总之,开闭原则是面向对象设计中的一项重要原则,它可以帮助我们设计出更加灵活、可维护和可重用的软件系统。通过遵循开闭原则,我们可以降低系统中的耦合性和复杂性,提高代码的可重用性和可维护性。
如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论
你的支持就是我✍️创作的动力! 💞💞💞
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)