软件对象(类、模块、方法等)应该对于扩展是开放的,对修改是关闭的。就是程序可以拓展,但是拓展程序不可以修改原有的代码,就像你想给什么东西写一个插件,你肯定不能修改那个东西的源码。
我认为开闭原则就是,用接口或抽象类来打造软件的整体架构,实现接口和抽象类来拓展业务。如果要拓展新的业务我们只需要重新写一个接口实现类来扩展就好了。所以软件的整体的架构要设计好,接口和抽象类设计的合理,对软件的稳定性和后期维护是非常重要的。
一个工厂生产两种杯子,猫爪杯和星空杯。
/** * 杯子接口 */ public interface Cup { } /** * 猫爪杯 */ public class CatCup implements Cup { public CatCup() { System.out.println("猫爪杯"); } } /** * 星空杯 */ public class StarCup implements Cup { public StarCup() { System.out.println("星空杯"); } } /** * 杯子工厂类 */ public class CupFactory { public enum CupType { CAT,STAR } public Cup createCup(CupType cupType){ switch (cupType){ case CAT: return new CatCup(); case STAR: return new StarCup(); } return null; } } public class Program { public static void main(String[] args) { //创建杯子工厂对象 CupFactory factory = new CupFactory(); //生产猫爪杯 factory.createCup(CupFactory.CupType.CAT); //生产星空杯 factory.createCup(CupFactory.CupType.STAR); } }
随着业务的发展,需要生产大肚杯,要对原有的工厂(CupFactory )进行改造,再加一种被子吗?当然不能加,加了你就违背了开闭原则的对于扩展是开放的,对修改是关闭的,拓展程序不可以对原有代码进行修改的。于是:
public class Program { public static void main(String[] args) { //创建猫爪杯工厂对象 CatCupFactory catCupFactory = new CatCupFactory(); //调用工厂方法 catCupFactory.createCup(); StarCupFactory starCupFactory = new StarCupFactory(); starCupFactory.createCup(); } } /** * 杯子接口 */ interface Cup { } /** * 猫爪杯 */ class CatCup implements Cup { public CatCup() { System.out.println("猫爪杯"); } } /** * 星空杯 */ class StarCup implements Cup { public StarCup() { System.out.println("星空杯"); } } /** * 杯子工厂接口 */ interface CupFactory { Cup createCup(); } //星空杯工厂 class StarCupFactory implements CupFactory { @Override public Cup createCup() { return new StarCup(); } } //猫爪杯工厂 class CatCupFactory implements CupFactory { @Override public Cup createCup() { return new CatCup(); } }
调整后的结构设计,如果拓展业务生产大肚杯只需要新加一个大肚杯的工厂,而不用修改原来的代码,是符合开闭原则的。
感悟:仔细了解了开闭原则,我认为软件的接口要设计的越细越好,功能不可再分。就是一个接口只做一件事情。不要出现实现类实现了这个接口,却对于接口的两个方法,只需要其中的一个方法,这样就会造成代码的冗余
本文参考:https://www.cnblogs.com/az4215/p/11489712.html