• 北风设计模式课程---31、开放封闭原则


    北风设计模式课程---31、开放封闭原则

    一、总结

    一句话总结:

    对类的扩展开放,对类的修改封闭

    1、整个宗门系统如何设计(大致思路)?

    1、鉴定装备的有鉴定装备的人,炼制装备的有炼制装备的人,发放装备的有发放装备的人
    2、宗门的这些职位是由这些人员来担任的,
    3、掌门负责统一调配,

    2、银行业务员要完成如何工作1.付款、2.取款、3.转账、4.申购基金、5.其他业务,我们应该如何设计类?

    每个银行业务员负责一个工作:比如专门负责付款的银行业务员,专门负责取款的银行业务员

    3、怎样做到开放封闭原则?

    初期就设计好:不然后期因为牵扯太多修改就会比较麻烦


    实际上,绝对封闭的系统是不存在的。无论模块是怎么封闭,到最后,总还是有一些无法封闭的变化。而我们的思路就是:既然不能做到完全封闭,那我们就应该对那些变化封闭,那些变化隔离做出选择。我们做出选择,然后将那些无法封闭的变化抽象出来,进行隔离,允许扩展,尽可能的减少系统的开发。当系统变化来临时,我们要及时的做出反应。


    我们并不害怕改变的到来。当变化到来时,我们首先需要做的不是修改代码,而是尽可能的将变化抽象出来进行隔离,然后进行扩展。面对需求的变化,对程序的修改应该是尽可能通过添加代码来实现,而不是通过修改代码来实现。

    实际上,变化或者可能的变化来的越早,抽象就越容易,相对的,代码的维护也就越容易;而当项目接近于完成而来的需求变化,则会使抽象变得很困难——这个困难,并不是抽象本身的困难,抽象本身并没有困难,困难在于系统的架构已经完成,修改牵扯的方面太多而使得抽象工作变得很困难。

    4、开放封闭原则的优越性?

    1.扩展:通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,是变化中的软件有一定的适应性和灵活性。
    2.稳定性和延续性:已有的软件模块,特别是最重要的抽象模块不能再修改,这就使变化中的软件系统有一定的稳定性和延续性。

    5、开放封闭原则使用建议?

    1、可以通过Template Method模式和Strategy模式进行重构:实现对修改封闭、对扩展开放的设计思路。
    2、封装变化:是实现开放封闭原则的重要手段,对于经常发生变化的状态一般将其封装为一个抽象,例如银行业务中的IBankProcess接口。
    3、拒绝滥用抽象:只将经常变化的部分进行抽象,这种经验可以从设计模式的学习与应用中获得。

    二、内容在总结中

    1、初始

    BankWorker.java

    /*
     * 银行业务员
     */
    public class BankWorker {
        //负责存款业务
        public void saving() {
            System.out.println("进行存款操作");
        }
        
        //负责取款业务
        public void drawing() {
            System.out.println("进行取款操作");
        }
        
        //负责转账业务
        public void zhuanzhang() {
            System.out.println("进行转账操作");
        }
        
        //负责基金的申购
        public void jijin() {
            System.out.println("进行基金申购操作");
        }
    }

    MainClass.java

    public class MainClass {
        public static void main(String[] args) {
            BankWorker bankWorker = new BankWorker();
            //存款
            bankWorker.saving();
            
            //取款
            bankWorker.drawing();
            
            //转账
            bankWorker.zhuanzhang();
            
            //基金
            bankWorker.jijin();
        }
    }

    2、改进后

    接口:BankWorker.java

    package com.ibeifeng.ex2;
    /*
     * 银行业务员接口,是所有银行业务员的抽象父类。
     */
    
    public interface BankWorker {
        public void operation();
    }

    DrawingBankWorker.java

    package com.ibeifeng.ex2;
    /*
     * 负责取款业务的业务员
     */
    public class DrawingBankWorker  implements BankWorker{
    
        public void operation() {
            System.out.println("进行取款操作");
        }
        
    }

    JiJinBankWorker.java

    package com.ibeifeng.ex2;
    
    public class JiJinBankWorker implements BankWorker {
    
        public void operation() {
            System.out.println("进行基金申购操作");
        }
    
    }

    SavingBankWorker.java

    package com.ibeifeng.ex2;
    /*
     * 负责存款业务的业务员
     */
    
    public class SavingBankWorker implements BankWorker {
    
        public void operation() {
            System.out.println("进行存款操作");
        }
        
    }

    ZhuanZhangBankWorker.java

    package com.ibeifeng.ex2;
    
    /*
     * 负责转账业务的业务员
     */
    public class ZhuanZhangBankWorker implements BankWorker {
    
        public void operation() {
            System.out.println("进行转账操作");
        }
    
    }

    客户端调用:MainClass.java

    package com.ibeifeng.ex2;
    
    public class MainClass {
        public static void main(String[] args) {
            BankWorker bankWorker = new SavingBankWorker();
            bankWorker.operation();
            
            BankWorker bankWorker2 = new DrawingBankWorker();
            bankWorker2.operation();
            
            BankWorker bankWorker3 = new ZhuanZhangBankWorker();
            bankWorker3.operation();
            
            BankWorker bankWorker4 = new JiJinBankWorker();
            bankWorker4.operation();
        }
    }

    三、面向对象五大原则-----开放封闭原则

    转自或参考:面向对象五大原则-----开放封闭原则
    https://www.cnblogs.com/xiaobai1226/p/8663101.html

      什么是开放封闭原则

      开放封闭原则(OCP,Open Closed Principle)是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。其他的设计原则,很多时候是为实现这一目标服务的,例如以Liskov替换原则实现最佳的、正确的继承层次,就能保证不会违反开放封闭原则。 

      关于开放封闭原则,其核心的思想是:软件实体应该是可扩展,而不可修改的。也就是说,一个软件实体应当对扩展是开放的,而对修改是封闭的。 

      因此,开放封闭原则主要体现在两个方面:对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

      在设计一个模块时,应当使得这个模块可以在不被修改的前提下被扩展。也就是说,应当可以在不必修改源代码的情况下修改这个模块的行为。

      设计的目的便在于面对需求的改变而保持系统的相对稳定,从而使得系统可以很容易的从一个版本升级到另一个版本。

      “需求总是变化”、“世界上没有一个软件是不变的”,这些言论是对软件需求最经典的表白。从中透射出一个关键的意思就是,对于软件设计者来说,必须在不需要对原有的系统进行修改的情况下,实现灵活的系统扩展。而如何能做到这一点呢?

      只有依赖于抽象。实现开放封闭的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以对修改就是封闭的;而通过面向对象的继承和对多态机制,可以实现对抽象体的继承,通过覆写其方法来改变固有行为,实现新的扩展方法,所以对于扩展就是开放的。这是

    实施开放封闭原则的基本思路,同时这种机制是建立在两个基本的设计原则的基础上,这就是Liskov替换原则和合成/聚合复用原则。

      对于违反这一原则的类,必须进行重构来改善,常用于实现的设计模式主要有Template Method模式和Strategy模式。而封装变化,是实现这一原则的重要手段,将经常发生变化的状态封装为一个类。

      怎样做到开放封闭原则

      实际上,绝对封闭的系统是不存在的。无论模块是怎么封闭,到最后,总还是有一些无法封闭的变化。而我们的思路就是:既然不能做到完全封闭,那我们就应该对那些变化封闭,那些变化隔离做出选择。我们做出选择,然后将那些无法封闭的变化抽象出来,进行隔离,允许扩展,尽可能的减少系统的开发。当系统变化来临时,我们要及时的做出反应。

          我们并不害怕改变的到来。当变化到来时,我们首先需要做的不是修改代码,而是尽可能的将变化抽象出来进行隔离,然后进行扩展。面对需求的变化,对程序的修改应该是尽可能通过添加代码来实现,而不是通过修改代码来实现。

          实际上,变化或者可能的变化来的越早,抽象就越容易,相对的,代码的维护也就越容易;而当项目接近于完成而来的需求变化,则会使抽象变得很困难——这个困难,并不是抽象本身的困难,抽象本身并没有困难,困难在于系统的架构已经完成,修改牵扯的方面太多而使得抽象工作变得很困难。

      我们举个银行业务的例子

      银行有四项业务,存款,取款,转账和买基金

      如果用普通的方式来写

     1 /*
     2  * 银行业务员
     3  */
     4 public class BankWorker {
     5     //负责存款业务
     6     public void saving() {
     7         System.out.println("进行存款操作");
     8     }
     9     
    10     //负责取款业务
    11     public void drawing() {
    12         System.out.println("进行取款操作");
    13     }
    14     
    15     //负责转账
    16     public void zhuanzhang() {
    17         System.out.println("进行转账操作");
    18     }
    19     
    20     //负责基金的申购
    21     public void jijin() {
    22         System.out.println("进行基金申购操作");
    23     }
    24 }

      这样等同于一个业务员负责了所有的业务,站在银行窗口焦急等待的用户,在长长的队伍面前显得无奈。所以,将这种无奈迁怒到银行的头上是理所当然的,因为银行业务的管理显然有不当之处。银行的业务人员面对蜂拥而至的客户需求,在排队等待的人们并非只有一种需求,有人存款、有人转账,

    也有人申购基金,繁忙的业务员来回在不同的需求中穿梭,手忙脚乱的寻找各种处理单据,电脑系统的功能模块也在不同的需求要求下来回切换,这就是一个发生在银行窗口内外的无奈场景。而我每次面对统一排队的叫号系统时,都为前面长长的等待人群而叫苦,从梳理银行业务员的职责来看,在管理上

    他们负责的业务过于繁多,将其对应为软件设计来实现,这种拙劣的设计就上面例子中的方式。

      这样,如果要修改的话,如果银行新添加了一项业务,这个业务员就得新增这项业务,这样扩展行就很差,而且,只要新增业务就要修改源码。

      所以下面我们用符合开放封闭原则的方式来编写代码

      把不同的业务分配给不同的业务员,所以先编写抽象业务员父类

    1 /*
    2  * 银行业务员接口,是所有银行业务员的抽象父类
    3  */
    4 public interface BankWorker {
    5     public void operation();
    6 }

       然后,在编写各个负责各个业务的业务员

     1 /*
     2  * 负责存款业务的业务员
     3  */
     4 public class SavingBankWorker implements BankWorker {
     5 
     6     public void operation() {
     7         System.out.println("进行存款操作");
     8     }
     9     
    10 }
     1 /*
     2  * 负责取款业务的业务员
     3  */
     4 public class WithdrawalsBankWorker  implements BankWorker{
     5 
     6     public void operation() {
     7         System.out.println("进行取款操作");
     8     }
     9     
    10 }
     1 /*
     2  * 负责转账业务的业务员
     3  */
     4 public class ZhuanZhangBankWorker implements BankWorker {
     5 
     6     public void operation() {
     7         System.out.println("进行转账操作");
     8     }
     9 
    10 }
     1 /*
     2  * 负责基金业务的业务员
     3  */
     4 public class JiJinBankWorker implements BankWorker {
     5 
     6     public void operation() {
     7         System.out.println("进行基金申购操作");
     8     }
     9 
    10 }

      可以看到,这样的形式就可以做到,增加业务只需新增业务员即可,不必对原有业务进行任何的修改,也符合了开放封闭原则 

      开放封闭原则的优越性

      1.通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,是变化中的软件有一定的适应性和灵活性。

      2.已有的软件模块,特别是最重要的抽象模块不能再修改,这就使变化中的软件系统有一定的稳定性和延续性。

       使用建议

      1、开放封闭原则,是最为重要的设计原则,Liskov替换原则和合成/聚合复用原则为开放封闭原则的实现提供保证。

      2、可以通过Template Method模式和Strategy模式进行重构,实现对修改封闭、对扩展开放的设计思路。

      3、封装变化,是实现开放封闭原则的重要手段,对于经常发生变化的状态一般将其封装为一个抽象,例如银行业务中的IBankProcess接口。

      4、拒绝滥用抽象,只将经常变化的部分进行抽象,这种经验可以从设计模式的学习与应用中获得。

     
  • 相关阅读:
    引用类型构造器
    正则指引量词
    Ajax的XMLHttpRequest对象
    正则指引字符组
    方法可变数量的参数
    不使用XMLHttpRequest实现异步加载:Iframe和script
    可选参数、命名参数
    常量和字段
    正则指引括号
    值类型实例构造器
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/11106205.html
Copyright © 2020-2023  润新知