开闭原则
即Open Closed Principle,它是最基础也是最重要的设计原则,我们遵循其它的设计原则如单一职责原则、依赖倒置原则、里氏替换原则等最终都是为了开闭原则。
开闭原则要求一个软件实体,如类、函数或模块,要对扩展开放(提供方),对修改关闭(使用方)。当有一个新的功能或需求来了时,我们应该是通过增加新的类、函数、模块等手段来代替直接修改原来的类或函数。
总之一句话就是用抽象构建框架,用实现扩展细节。
案例
重构前UML图
代码1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * 统计各个电商平台的商户销售情况 */ public class Statistics { /** * 统计某商户的年销售额 * @param platformType 平台类型 1天猫 2淘宝 3京东 * @param merchantId 商户id */ public void yearSales(int platformType, String merchantId){ if (platformType == 1){ System.out.println("商户"+merchantId+"在天猫的年销售额是1000万"); }else if(platformType == 2){ System.out.println("商户"+merchantId+"在淘宝的年销售额是800万"); }else if(platformType == 3){ System.out.println("商户"+merchantId+"在京东的年销售额是850万"); } } } |
1 2 3 4 5 6 7 8 |
public class Client { public static void main(String[] args) { Statistics statistics = new Statistics(); statistics.yearSales(1, "123456789"); statistics.yearSales(2, "123456789"); statistics.yearSales(3, "123456789"); } } |
现在若要增加一个统计平台拼多多,那就需要在yearSales方法里增加if else判断分支,另外调用方的客户端也要跟着修改,这就违背了开闭原则。根据对修改关闭,对扩展开放的宗旨,我们需要这样改。
代码2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/** * 统计各个电商平台的商户销售情况 */ public abstract class PlatformStatistics { /** * 平台类型 1天猫 2淘宝 3京东 4拼多多 */ abstract int getType(); /** * 统计某商户的年销售额 * @param merchantId 商户id */ abstract void yearSales(String merchantId); } |
1 2 3 4 5 6 7 8 9 10 11 |
public class TmallStatistics extends PlatformStatistics { @Override int getType() { return 1; } @Override void yearSales(String merchantId) { System.out.println("商户"+merchantId+"在天猫的年销售额是1000万"); } } |
1 2 3 4 5 6 7 8 9 10 11 |
public class TaobaoStatistics extends PlatformStatistics { @Override int getType() { return 2; } @Override void yearSales(String merchantId) { System.out.println("商户"+merchantId+"在淘宝的年销售额是800万"); } } |
1 2 3 4 5 6 7 8 9 10 11 |
public class JdStatistics extends PlatformStatistics { @Override int getType() { return 3; } @Override void yearSales(String merchantId) { System.out.println("商户"+merchantId+"在京东的年销售额是850万"); } } |
1 2 3 4 5 6 7 8 9 10 11 |
public class PinduoduoStatistics extends PlatformStatistics { @Override int getType() { return 4; } @Override void yearSales(String merchantId) { System.out.println("商户"+merchantId+"在拼多多的年销售额是1050万"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class PlatformFactory { private ConcurrentHashMap<Integer, PlatformStatistics> statisticsMap = new ConcurrentHashMap<>(5); public PlatformFactory(){ TmallStatistics tmallStatistics = new TmallStatistics(); statisticsMap.put(tmallStatistics.getType(), tmallStatistics); TaobaoStatistics taobaoStatistics = new TaobaoStatistics(); statisticsMap.put(taobaoStatistics.getType(), taobaoStatistics); JdStatistics jdStatistics = new JdStatistics(); statisticsMap.put(jdStatistics.getType(), jdStatistics); PinduoduoStatistics pinduoduoStatistics = new PinduoduoStatistics(); statisticsMap.put(pinduoduoStatistics.getType(), pinduoduoStatistics); } public PlatformStatistics getInstance(int platformType){ return statisticsMap.get(platformType); } } |
1 2 3 4 5 6 7 |
public class Client { static PlatformFactory factory = new PlatformFactory(); public static void main(String[] args) { PlatformStatistics instance = factory.getInstance(4); instance.yearSales("123456789"); } } |
0