zoukankan      html  css  js  c++  java
  • 面向对象五大原则_基石_开闭原则


    1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作《面向对象软件构造(Object Oriented Software Construction)》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。

    翻译过来就是:“软件实体应当对扩展开放。对改动关闭”。

    这句话说得稍微有点专业,我们把它讲得更通俗一点,也就是:软件系统中包括的各种组件,比如模块(Modules)、(Classes)以及功能(Functions)等等。应该在不改动现有代码的基础上,引入新功能。

    开闭原则中“开”。是指对于组件功能的扩展是开放的,是同意对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的改动是封闭的,即不应该改动原有的代码。

    ----百度百科

    为什么没有说是面向对象6大原则,为什么没有将开闭原则包含进去?  

    开闭原则是最基础的一个原则,前面5个原则就是它的详细形态,开闭原则才是他们的接口。


    IBook作为一个接口。里面有三个方法,而小说NovelBook是一个详细的实现类,是全部小说的总称,BookStore指的是书店。


    public interface IBook {
     public String getName();
     public int getPrice();
     public String getAuthor();
    }
    public class NovelBook implements IBook {
     private String name;
     private int price;
     private String autor;
     
     public NovelBook(String name,int price,String autor){
      this.name=name;
      this.price=price;
      this.autor=autor;
     }
     
     public String getAuthor() {
      return this.autor;
     }
    
     public String getName() {
      return this.name;
     }
    
     public int getPrice() {
      return this.price;
     }
    }
    public class Store {
    
     private final static ArrayList<IBook> booklist = new ArrayList<IBook>();
    
     static { // 静态模块载入数据,实际项目一般由持久层完毕
      booklist.add(new NovelBook("巴黎圣母院", 3200, "雨果"));
      booklist.add(new NovelBook("悲慘世界", 5600, "雨果"));
      booklist.add(new NovelBook("天龙八部", 4800, "金庸"));
      booklist.add(new NovelBook("挪威的森林", 2200, "村上春树"));
     }
    
     public static void main(String[] args) {
      NumberFormat format = NumberFormat.getCurrencyInstance();
      format.setMaximumFractionDigits(2);
    
      System.out.println("-------------书店卖出去的书籍记录例如以下---------------");
      for (IBook book : booklist) {
       System.out.println("书籍名称:" + book.getName() + "	书籍作者:"
         + book.getAuthor() + "	书籍价格:"
         + format.format(book.getPrice() / 100.0) + "元");
      }
     }
    }


    程序员最害怕的需求变化来了: 由于俺们村近期炒股,都赔了,书卖不出去,须要打折来促销。40块以上的9折,下面的8折。

    思考怎样改动: 
        1.一了百了,改动接口,假设这个需求变化在设计的时候就想到了就好了。这样改动的话以下的NovelBook类要改。书店类也要改。接口对外是承诺。一旦确认不能改动。不能常常变化。否定!
        2.改动NovelBook中的getPrice方法,替换class文件,这个可行。可是还要结合实际情况。

    待定! 

        3.扩展一个子类,重写getPrice方法。   能够!  

    public class OffNovelBook extends NovelBook {
     
     public OffNovelBook(String name, int price, String autor) {
      super(name, price, autor);
     }
     @Override
     public int getPrice() {
      int price=super.getPrice();
      int oprice=0;
      if(price>4000){
       oprice= price*90/100;
      }else{
       oprice= price*80/100;
      }
      return oprice;
     }
    }

    static { // 静态模块载入数据。实际项目一般由持久层完毕
      booklist.add(new NovelBook("巴黎圣母院", 3200, "雨果"));
      booklist.add(new NovelBook("悲慘世界", 5600, "雨果"));
      booklist.add(new NovelBook("天龙八部", 4800, "金庸"));
      booklist.add(new NovelBook("挪威的森林", 2200, "村上春树"));
      booklist.add(new OffNovelBook("唐诗三百首", 4500, "谁写的"));
     }

    或许有人会觉得高层业务代码已经改动了。可是这是不可避免的,有的时候甚至会连界面也会改动的。 变化或许是逻辑变化,或许是子模块变化,那么对应的对于其它模块必定会造成影响。视图变化也须要扩展。
    再说了。假设你改动了曾经写好的代码。要知道。在实际开发中,投入的代码都是经过測试MM的千锤百炼的。假设你这一改,測试MM的笑脸你是别想再看到了。不改的话我们还是好朋友。

    开闭原则的优点:
        1.測试
        2.复用性
        3.可维护性
    总之中的一个句话,拥抱变化。拒绝改动,提倡扩展。系统的稳定性得到了保证。

    程序员最害怕的需求又变化来了: 如今俺们村文化程度提高了,书店须要扩展。前几天张家的儿子和李家的女儿都考上了计算机专业,一个是大数据,一个是嵌入式,我们要加这俩个领域的书 。 
    怎样思考: 须要添加一个属性领域,还得在原来的基础上扩展。不能改动原有的抽象层。那么我再加一个不即可了吗? 让IComputer接口继承IBook接口,然后再写详细类。通过构造传參。

    public interface IComputerBook extends IBook {
     public String getScope();
    }
    public class ComputerBook implements IComputerBook {
     private String name;
     private int price;
     private String autor;
     private String scope;
     
     public ComputerBook(String name, int price, String autor, String scope) {
      this.name = name;
      this.price = price;
      this.autor = autor;
      this.scope = scope;
     }
    
     public String getScope() {
      return this.scope;
     }
    
     public String getAuthor() {
      return this.autor;
     }
    
     public String getName() {
      return this.name;
     }
    
     public int getPrice() {
      return this.price;
     }
    }

    static { // 静态模块载入数据,实际项目一般由持久层完毕
      booklist.add(new NovelBook("巴黎圣母院", 3200, "雨果"));
      booklist.add(new NovelBook("悲慘世界", 5600, "雨果"));
      booklist.add(new NovelBook("天龙八部", 4800, "金庸"));
      booklist.add(new NovelBook("挪威的森林", 2200, "村上春树"));
      booklist.add(new OffNovelBook("下架的书", 4500, "谁写的"));
      booklist.add(new ComputerBook("大数据入门", 8500, "李老师", "大数据"));
      booklist.add(new ComputerBook("嵌入式精髓", 2600, "吴老师", "嵌入式"));
     }

    这种设计遵循抽象约束原则:   1.通过抽象层约束扩展。对扩展进行边界限定。


                                                 2.參数类型,引用对象尽量使用接口或者抽象类。
                                                 3.抽象层始终维持稳定,一旦确定不再改动。

    1.抽象约束    
    2.元数据控制模板
            元数据: 配置參数,变化的參数,比如登录时须要先检查IP地址。然后决定是否登录,SSH使用了拦截器,这在之前的博客有写过。

    控制反转,使用底层的反射来写的。

    3.制定项目章程
           全部成员必须遵守的约定。整齐划一。提高开发效率,这个眼下仅仅能是模拟幻想而已。。。
    4.封装变化
        (1).将同样的变化封装到一个接口或抽象类中。  (2).将不同的变化封装到不同的接口或者抽象类中。 

    參考书籍《设计模式之禅》


    我是菜鸟,我在路上。

  • 相关阅读:
    activiti--操作例子
    activiti--服务表
    spring--加载资源文件
    Day17
    Day15
    Day14
    Day13
    Day12
    Day16
    Day11
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5395061.html
Copyright © 2011-2022 走看看