精华内容
下载资源
问答
  • 依赖倒置原则(设计模式原则)

    千次阅读 2018-01-14 00:02:27
    两个类有依赖关系,只要指定两者之间的接口(或抽象类)就可以独立开发了,而且项目之间的单元测试也可以独立的运行,而TDD( Test-Driven Development,测试驱动开发) 开发模式就是依赖倒置原则的最高级应用。...

    (Dependence Inversion Principle)定义: 高层模块不应该依赖底层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。//“抽象”指“接口或抽象类”,“细节”指“实现类”

    在语言中表现:

       模块间的依赖是通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;

    ”A依赖B“指 什么?依赖传递的3种方式?

    问题(不好的情况):

    概述: 再 “依赖” 关系中,程序要依赖于抽象接口,不要依赖于具体实现。这样降低了客户与实现模块间的耦合。

    谁依赖谁要抽象的合理。

    采用依赖倒置原则的好处?  可以减少类间的耦合性,提高系统的稳定性,减少并行开放引起的风险,提高代码的可读性和可维护性

    3  举例说明: 司机驾驶奔驰如3-1图:


    3-1  司机源码

    public class Driver{
       public void drive(Benz benz){
           benz.run();
       }
    }
    3-2 奔驰车源代码

    public class Bez{
        public void run(){
            System.out.println("奔驰开始运行...")   
        }
    }

    3-3 场景类源代码

    public class Client{
        public static void main(Sting[] args){
            Driver zhangsan = new Driver();
            
            Benz benz = new Benz();
    
            zhangsan.drive(benz);
        }
    }

    以上代码也算是完成了任务或者基本需求,现在又来新需求了,张三不仅要开奔驰车,还要开宝马车,又该怎么办呢?

    3-4  宝马车源代码

    public class BMW{
        public void run(){
             System.out.println("宝马车开始运行....");
        }
    }


    问题来了,宝马车也产生了,张三没法开?因为张三没有开宝马车的方法!(除非要改driver类的方法),一个有驾照的司机竟然只能开奔驰车,而不能开宝马车(要开宝马车改动driver类代码),这也不合理,在现实世界也不合理。 问题关键点在什么地方?就是司机类和奔驰车类之间是一个紧耦合关系,这里新增加一个车类就要修改司机类,这是不稳定性!被依赖者的变更或增加(新增宝马车类)竟然要依赖者(司机类)来承担修改的成本,不好呀!!!

     这样的代码类关系还会引起并行开发的风险; 什么是并行开发风险? 并行开发最大的风险就是风险扩散,本来只是一段程序的错误或异常,逐步波及一个功能,一个模块,甚至最后毁坏整个项目! 为什么风险可能如此大呢? 一个团队,20人开发,个人负责不同的功能模块,甲负责汽车类,乙负责司机类, 在甲没有完成的情况,乙是不能完全编写代码的,缺少汽车类,编译器根本不会让你通过,更不要说单元测试了! 在上面那种不使用依赖倒置原则环境中,所有的开发工作都是单线程的,甲做完,乙再做,然后是丙....,   在小项目中是可以的一个人完成所有的代码开发工作,但是在现在的大中型项目中已经是完全不能胜任了;要协作就要并行开发,要并行开发就要解决模块之间的项目依赖关系,依赖倒置原则就可以做到!!!

    引入了依赖倒置原则后的类如图3-2


    建立两个接口:IDriver 和 ICar 

    3-5 司机接口

    public interface IDriver{
       public void drive(ICar car);
    }

    3-6  司机类的实现

    public class Driver implements IDriver{
         public void drive(ICar car){
                car.run();
         }
    }

    3-7  汽车类及两个实现类

    public interface ICar{
        public void run();
    }
    
    public class Benz implements  ICar{
         public void run(){
               System.out.println("奔驰骑车开始运行....");
         }
    }
    
    public class BMW implements ICar{
         public void run(){
             System.out.println("宝马骑车开始运行....");
         }
    }
    
    3-8 业务场景代码

    public class Client{
        public static  void main(String[] args){
              IDriver zhangsan = new Driver();
             ICar benz = new Benz();
    
             zhangsan.drive(benz);
        }
    }


    Client 属于高层业务逻辑,它对底层模块的依赖(关联)都建立在抽象上,zhangsan 的显示类型是IDriver, benz的显示类型是ICar, 也许你要问,在这个高层模块中也调用了底层模块,比如 new Driver()  和 new Benz()等,怎么解释? 确实如此,zhangsan的显示类型是IDriver,是一个接口,是抽象的,非实体化的,在后续的操作中zhangsan 都是以IDriver类型进行操作,屏蔽了细节对抽象的影响。当然,张三如果要开宝马,很容易,只要修改业务场景类就可以了。如下:

    3-9 张三驾驶宝马车过程

    public class Client {
     
          public static void main(String[] args) {
     
                 IDriver zhangSan = new Driver();
     
                  ICar bmw = new BMW();
     
                  //张三开奔驰车
     
                  zhangSan.drive(bmw);
     
          }
     
    }
    点评: 在新增加底层模块时,只修改了业务场景类,也就是高层模块,对其他模块如Driver类不需要做任何修改,把”变更“的风险降到最低。

    依赖倒置对并行开发的影响。两个类有依赖关系,只要指定两者之间的接口(或抽象类)就可以独立开发了,而且项目之间的单元测试也可以独立的运行,而TDD( Test-Driven Development,测试驱动开发) 开发模式就是依赖倒置原则的最高级应用。甲程序员负责IDriver 的开发,乙程序员负责ICar的开发,两个人只要制定好了接口就可以独立开发了,甲开发的快,完成了IDriver以及相关实现类Driver的开发工作,而乙开发滞后,那么甲是否可以进行单元测试(Unit Test)答案是可以的,我们引入一个JMock工具。todo.....


    抽象是对实现的约束,对依赖者而言,也是一种契约,不仅仅约束自己,还同时约束自己与外部的关系,其目的是保证所有的细节不逃脱契约的范畴,确保约束双方按照既定的契约(抽象)共同发展。

    依赖的三种写法,或者依赖传递的三种方式?

    依赖是可以传递的,A对象依赖B对象,B依赖C,C依赖D....生生不息;记住只要做到依赖 抽象,即使是多层的依赖传递也无所谓!

    1. 构造函数传递依赖对象

    public interface IDriver{
         public void drive();
    }
    
    public class Driver implements IDriver{
        private  ICar car;
       
        public Driver(ICar _car){
              this.car = _car;
        }
    
         public void drive(){
               this.car.run();
         }
    }
    2. setter方法传递依赖对象

    public interface IDriver{
         public void setCar(ICar car);
         public void drive();
    }
    
    public class Driver implements IDriver{
          private  ICar car;
          public void setCar(ICar car){
                 this.car = car;
          }
    
           public void drive(){
                 this.car.run();
           }
    }

     3. 接口声明依赖对象,也叫 接口注入。

    3.4 编码最佳实践

          依赖倒置的本质原则就是 :通过抽象(接口或抽象类)使各个类或模块实现彼此独立,互不影响,实现模块间的松耦合。

    1.  每个类尽量都要有接口或抽象类,或者抽象类和接口两者都具备。

    2. 变量的显示类型 尽量是接口或者抽象类。

    3. 任何类都不应该从具体类派生。  这样不是绝对的如,在项目开发阶段要遵从此原则。要是做维护老项目,基本就是做扩展开发,通过继承关系,覆写一个方法就可以修改一个bug,何必要去继承最高的基类内容

    4. 尽量不要覆写基类的方法

    5.     结合里氏替换原则。  父类出现的地方子类就能出现


    ”倒置“怎么理解 ? 依赖正置 ,我要开奔驰就依赖奔驰,面向实现编程,估计这也是90年代主要思想,后来这种方式有很大问题 所以要”倒置“即依赖抽象。

    现实世界中,有些必须依赖细节 如:法律,”杀人偿命” 这个算依赖抽象,实际上,要具体情况(依赖细节)才能判决是否要偿命

    参考博客http://www.cnblogs.com/cbf4life/archive/2009/12/15/1624435.html

    展开全文
  • 设计模式原则

    千次阅读 热门讨论 2014-03-22 09:35:46
    设计模式是在根据原则来优化代码的。设计模式中的原则,可以用来判断设计模式水平。设计模式中体现的准则越多,那么这个模式越优。下面来介绍一下,设计模式中六大原则。   一、单一职责原则  与标题意思相同,...

          设计模式是在根据原则来优化代码的。设计模式中的原则,可以用来判断设计模式水平。设计模式中体现的准则越多,那么这个模式越优。下面来介绍一下,设计模式中六大原则。

     

    一、单一职责原则

          与标题意思相同,功能要单一,切忌添加不相关的功能。准确的解释是,就一个类而言,应该仅有一个引起它变化的原因。

          如果一个类承担的职责过多,就相当于把这些职责耦合在一块。一个职责的变化可能会对另一个职责造成影响。

          软件设计要做的内容,就是发现职责,并把这些职责相互分离

     

      分离职责,降低耦合。

    二、开放封闭原则

          特点:对于扩展是开放的,对于更改是封闭的

     

          对于做系统来说,系统的需求是肯定会发生变化的。既然需求变化,肯定是要修改代码的。

          开闭原则告诉我们,切忌修改已经完成的程序,在原有基础上进行扩展。

     

          看到上面是不是有点迷糊。扩展但是不修改原程序?这就要求,在设计程序的时候,不能做死。要留有接口。扩展,就是在原有接口的基础上进行开发。

     

          开放封闭,是面向对象的核心所在。遵循这个原则可以带来面向对象中的巨大好处。也就是可维护、可扩展、可复用、灵活性好。

     

    三、依赖倒转原则

          抽象不应该抽象细节,细节应该依赖于抽象

          简单来说,就是针对接口编程的时候,不要对实现编程。

          通俗来讲,就是当你设计U鼠标 键盘等产品的时候,要根据接口(USB)来设计。不能设计完之后,在去选择具有该接口的电脑产品。

     

          1、高层模块不应该依赖低层模块。两个都应该依赖抽象。

          2、抽象不应该依赖细节。细节应该依赖抽象。

     

          依赖倒转原则可以说是面向对象设计的标志,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止与抽象类或者是接口。那就是面向对象的设计,否则只是过程话的设计。

     

    四、里氏代换原则

          一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类和子类对象的区别,也就是说,在软件里面,父类和子类可以替换,而程序没有变化。

     

          子类型必须能够替换掉他们的父类型

     

    五、迪米特法则

          如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

          迪米特法则,在类的结构设计上,每一个类都应当降低成员之间的访问权限。即封装。归根到底还是要降低类之间的耦合。类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改的时候,不会对其他有关系的类造成波及。促进了软件的复用。

          迪米特法则,也称为 最少知道原则。

     

    六、合成/聚合复用原则

          尽量使用合成/聚合,尽量不要使用类继承。

          应对情况:对象的继承关系是在编译的就定义好了,无法在运行时改变从父类继承的实现。子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中德任何变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。

          把抽象部分与实现部分分离,使得他们可以独立的变化。通过组合的方式,把两个角色之间的继承关系改为组合的关系,从而使这两者可以应对各自独立的变化。

     


          设计模式的学习,就是在面向对象三大特性的基础上,去组合原则,来获得可维护、可扩展、可复用、灵活性好的代码。

    展开全文
  • OO的五大设计模式原则

    千次阅读 2017-11-28 00:27:45
    OO的五大原则是指SRP、OCP、LSP、DIP、ISP。... Open for Extension)现将近期整理的文档提供给大家,这里对LSP做重点的介绍,望对大家有帮助,在学习和使用OO设计的时候,我们应该明白:OO的出现使得软件工程师们能够

    OO的五大原则是指SRP、OCP、LSP、DIP、ISP。

    SRP – (Single Responsibility Principle 单一职责原则)

    OCP——开闭原则(Closed for Modification; Open for Extension)

    现将近期整理的文档提供给大家,这里对LSP做重点的介绍,望对大家有帮助,在学习和使用OO设计的时候,我们应该明白:OO的出现使得软件工程师们能够用更接近真实世界的方法描述软件系统。然而,软件毕竟是建立在抽象层次上的东西,再怎么接近真实,也不能替代真实或被真实替代。
    OO设计的五大原则之间并不是相互孤立的。彼此间存在着一定关联,一个可以是另一个原则的加强或是基础。违反其中的某一个,可能同时违反了其余的原则。因此应该把这些原则融会贯通,牢记在心!
    OO的五大原则是指SRP、OCP、LSP、DIP、ISP。
    1. SRP(Single Responsibility Principle 单一职责原则)
    单一职责很容易理解,也很容易实现。所谓单一职责,就是一个设计元素只做一件事。什么是“只做一件事”?简单说就是少管闲事。现实中就是如此,如果要你专心做一件事情,任何人都有信心可以做得很出色。
    OCP作为OO的高层原则,主张使用“抽象(Abstraction)”和“多态(Polymorphism)”将设计中的静态结构改为动态结构,维持设计的封闭性。
    2. OCP :开闭原则,很简单,一句话:“Closed for Modification; Open for Extension”——“对变更关闭;对扩展开放”。开闭原则其实没什么好讲的,我将其归结为一个高层次的设计总则。OCP的动机很简单:软件是变化的。不论是优质的设计还是低劣的设计都无法回避这一问题。OCP说明了软件设计应该尽可能地使架构稳定而又容易满足不同的需求。 为什么要OCP?答案也很简单——重用。
    3.LSP——里氏替换原则
    OCP作为OO的高层原则,主张使用“抽象(Abstraction)”和“多态(Polymorphism)”将设计中的静态结构改为动态结构,维持设计的封闭性“抽象”是语言提供的功能。“多态”由继承语义实现。 如此,问题产生了:“我们如何去度量继承关系的质量?”
    Liskov于1987年提出了一个关于继承的原则“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.”——“继承必须确保超类所拥有的性质在子类中仍然成立。”也就是说,当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系。
    该原则称为Liskov Substitution Principle——里氏替换原则。
    我们来研究一下LSP的实质。学习OO的时候,我们知道,一个对象是一组状态和一系列行为的组合体。状态是对象的内在特性,行为是对象的外在特性。LSP所表述的就是在同一个继承体系中的对象应该有共同的行为特征。
    这一点上,表明了OO的继承与日常生活中的继承的本质区别。举一个例子:生物学的分类体系中把企鹅归属为鸟类。我们模仿这个体系,设计出这样的类和关系。

    类“鸟”中有个方法fly,企鹅自然也继承了这个方法,可是企鹅不能飞阿,于是,我们在企鹅的类中覆盖了fly方法,告诉方法的调用者:企鹅是不会飞的。这完全符合常理。但是,这违反了LSP,企鹅是鸟的子类,可是企鹅却不能飞!需要注意的是,此处的“鸟”已经不再是生物学中的鸟了,它是软件中的一个类、一个抽象。
    有人会说,企鹅不能飞很正常啊,而且这样编写代码也能正常编译,只要在使用这个类的客户代码中加一句判断就行了。但是,这就是问题所在!首先,客户代码和“企鹅”的代码很有可能不是同时设计的,在当今软件外包一层又一层的开发模式下,你甚至根本不知道两个模块的原产地是哪里,也就谈不上去修改客户代码了。客户程序很可能是遗留系统的一部分,很可能已经不再维护,如果因为设计出这么一个“企鹅”而导致必须修改客户代码,谁应该承担这部分责任呢?(大概是上帝吧,谁叫他让“企鹅”不能飞的。^_^)“修改客户代码”直接违反了OCP,这就是OCP的重要性。违反LSP将使既有的设计不能封闭!

    修正后的设计如下:

    LSP并没有提供解决这个问题的方案,而只是提出了这么一个问题。 于是,工程师们开始关注如何确保对象的行为。1988年,B. Meyer提出了Design by Contract(契约式设计)理论。DbC从形式化方法中借鉴了一套确保对象行为和自身状态的方法,其基本概念很简单:

    每个方法调用之前,该方法应该校验传入参数的正确性,只有正确才能执行该方法,否则认为调用方违反契约,不予执行。这称为前置条件(Pre-condition)。
    一旦通过前置条件的校验,方法必须执行,并且必须确保执行结果符合契约,这称之为后置条件(Post-condition)。
    对象本身有一套对自身状态进行校验的检查条件,以确保该对象的本质不发生改变,这称之为不变式(Invariant)。
    以上是单个对象的约束条件。为了满足LSP,当存在继承关系时,子类中方法的前置条件必须与超类中被覆盖的方法的前置条件相同或者更宽松;而子类中方法的后置条件必须与超类中被覆盖的方法的后置条件相同或者更为严格。

    4.DIP 依赖倒置原则
    依赖倒置(Dependence Inversion Principle)原则讲的是:要依赖于抽象,不要依赖于具体。
    简单的说,依赖倒置原则要求客户端依赖于抽象耦合。原则表述:
    抽象不应当依赖于细节;细节应当依赖于抽象;
    要针对接口编程,不针对实现编程。

    5.ISP 接口隔离原则
    使用多个专门的接口比使用单一的总接口要好。广义的接口:一个接口相当于剧本中的一种角色,而此角色在一个舞台上由哪一个演员来演则相当于接口的实现。因此一个接口应当简单的代表一个角色,而不是一个角色。,如果系统设计多个角色的话,则应当每一个角色都由一个特定的接口代表。狭义的接口(Interface):接口隔离原则讲的就是同一个角色提供宽、窄不同的接口,以对付不同的客户端。这里写链接内容

    展开全文
  • 设计模式原则详解

    万次阅读 多人点赞 2012-05-17 10:39:21
    我们在应用程序开发中,一般要求尽量两做到可维护性和可复用性。 应用程序的复用可以提高应用程序的开发效率和质量,节约开发成本,恰当的复用还可以改善系统的可维护性。...面向对象设计原则设计模式也是对系统...

            我们在应用程序开发中,一般要求尽量两做到可维护性和可复用性。
            应用程序的复用可以提高应用程序的开发效率和质量,节约开发成本,恰当的复用还可以改善系统的可维护性。而在面向对象的设计里面,
    可维护性复用都是以面向对象设计原则为基础的,这些设计原则首先都是复用的原则,遵循这些设计原则可以有效地提高系统的复用性,同时提高系统的可维护性。 面向对象设计原则和设计模式也是对系统进行合理重构的指导方针。

           常用的面向对象设计原则包括7个,这些原则并不是孤立存在的,它们相互依赖,相互补充。

           前5个原则组合称为:SOLID 固定原则

           

     

    1.单一职责原则


    类的职责要单一,不能将太多的职责放在一个类中。(高内聚、低耦合)

    定义:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。(Every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class.),即又定义有且仅有一个原因使类变更。

     

    原则分析:
    1)一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。 
    2)类的职责主要包括两个方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现。
    3)单一职责原则是
    实现高内聚、低耦合的 指导方针,在很多代码重构手法中都能找到它的存在,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。 
    例子:
    最简单例子是:一个数据结构职责类和算法行为都放在一个类User。我们应该把数据结构和行为分开。现使用单一职责原则对User类进行重构。
     
     
     
    优点:
    1、降低类的复杂性,类的职责清晰明确。比如数据职责和行为职责清晰明确。
    2、提高类的可读性和维护性,
    4、变更引起的风险减低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的类有影响,对其他接口无影响,这对系统的扩展性、维护性都有非常大的帮助。
    注意:单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否合理,但是“职责”和“变化原因”都是没有具体标准的,一个类到底要负责那些职责?这些职责怎么细化?细化后是否都要有一个接口或类?这些都需从实际的情况考虑。因项目而异,因环境而异。

     



    2.开闭原则( Open - ClosedPrinciple ,OCP )


    对扩展开放,对修改关闭(设计模式的核心原则是

     定义:一个软件实体(如类、模块和函数)应该对扩展开放,对修改关闭.  意思是,在一个系统或者模块中,对于扩展是开放的,对于修改是关闭的,一个 好的系统是在不修改源代码的情况下,可以扩展你的功能. 而实现开闭原则的关键就是抽象化.

    原则分析 :

    1)当软件实体因需求要变化时, 尽量通过扩展已有软件实体,可以提供新的行为,以满足对软件的新的需求,而不是修改已有的代码,使变化中的软件有一定的适应性和灵活性 。已有软件模块,特别是最重要的抽象层模块不能再修改,这使变化中的软件系统有一定的稳定性和延续性。

    2)实现开闭原则的关键就是抽象化 :在"开-闭"原则中,不允许修改的是抽象的类或者接口,允许扩展的是具体的实现类,抽象类和接口在"开-闭"原则中扮演着极其重要的角色..即要预知可能变化的需求.又预见所有可能已知的扩展..所以在这里"抽象化"是关键!

    3)可变性的封闭原则:找到系统的可变因素,将它封装起来这是对"开-闭"原则最好的实现. 不要把你的可变因素放在多个类中,或者散落在程序的各个角落. 你应该将可变的因素,封套起来..并且切忌不要把所用的可变因素封套在一起. 最好的解决办法是,分块封套你的可变因素!避免超大类,超长类,超长方法的出现!!给你的程序增加艺术气息,将程序艺术化是我们的目标!

    例子:我们前面提到的模板方法模式和观察者模式都是开闭原则的极好体现。

     

     

    3.里氏代换原则( Liskov Substitution Principle ,LSP )


    任何基类可以出现的地方,子类也可以出现

    定义:第一种定义方式相对严格:如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有变化,那么类型S是类型T的子类型。

    第二种更容易理解的定义方式: 所有引用基类(父类)的地方必须能透明地使用其子类的对象。即 子类能够必须能够替换基类能够从出现的地方。子类也能在基类 的基础上新增行为。
    里氏代换原则由 2008 年图灵奖得主、美国第一位计算机科学女博士、麻省理工学院教授 Barbara Liskov 和卡内基 . 梅隆大学 Jeannette Wing 教授于 1994 年提出。其原文如下: Let q(x) be a property provableabout objects x of type T. Then q(y) should be true for objects y of type Swhere S is a subtype of T.   )
     
    原则分析:
    1)讲的是基类和子类的关系,只有这种关系存在时,里氏代换原则才存在。正方形是长方形是理解里氏代换原则的经典例子。
    2)里氏代换原则可以通俗表述为:在 软件中如果能够使用基类对象,那么一定能够使用其子类对象 。把基类都替换成它的子类,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类的话,那么它不一定能够使用基类。
    3) 里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此 在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象
     
    例子:正方形不是长方形 在数学领域里,正方形毫无疑问是长方形,它是一个长宽相等的长方形。所以,我们开发的一个与几何图形相关的软件系统中,让正方形继承自长方形是顺利成章的事情。由于正方形的度和宽度必须相等,所以在方法setLength和setWidth中,对长度和宽度赋值相同。
    /**
     * 长方形类Rectangle:
     *
     */
    class Rectangle {
      double length;
      double width;
      public double getLength() { return length; } 
      public void setLength(double height) { this.length = length; }   
      public double getWidth() { return width; }
      public void setWidth(double width) { this.width = width; } 
    }


    正方形集成长方形:

    /**
     * 正方形类Square:
     */
    class Square extends Rectangle {
      public void setWidth(double width) {
        super.setLength(width);
        super.setWidth(width);   
     }
      public void setLength(double length) { 
        super.setLength(length);
        super.setWidth(length);   
      } 
    }

         由于正方形的度和宽度必须相等,所以在方法setLengthsetWidth中,对长度和宽度赋值相同。类TestRectangle是我们的软件系统中的一个组件,它有一个resize方法要用到基类Rectangleresize方法的功能是模拟长方形宽度逐步增长的效果 :
      
    测试类TestRectangle

     
    class TestRectangle {
      public void resize(Rectangle objRect) {
        while(objRect.getWidth() <= objRect.getLength()  ) {
            objRect.setWidth(  objRect.getWidth () + 1 );
        }
      }
    }

        我们运行一下这段代码就会发现,假如我们把一个普通长方形作为参数传入resize方法,就会看到长方形宽度逐渐增长的效果,当宽度大于长度,代码就会停止,这种行为的结果符合我们的预期;假如我们再把一个正方形作为参数传入resize方法后,就会看到正方形的宽度和长度都在不断增长,代码会一直运行下去,直至系统产生溢出错误。所以,普通的长方形是适合这段代码的,正方形不适合。
        我们得出结论:在resize方法中,Rectangle类型的参数是不能被Square类型的参数所代替,如果进行了替换就得不到预期结果。因此,Square类和Rectangle类之间的继承关系违反了里氏代换原则,它们之间的继承关系不成立,正方形不是长方形。

     
    优缺点:
    在面向对象的语言中,继承是必不可少的、非常优秀的语言机制,它有如下优点:
    1)代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;
    2)提高代码的重用性;
    3)子类可以形似父类,但又异于父类,“龙生龙,凤生凤,老鼠生来会打洞”是说子拥有父的“种”,“世界上没有两片完全相同的叶子”是指明子与父的不同;
    4)提高代码的可扩展性,实现父类的方法就可以“为所欲为”了,君不见很多开源框架的扩展接口都是通过继承父类来完成的;
    5)提高产品或项目的开放性。
     
    自然界的所有事物都是优点和缺点并存的,即使是鸡蛋,有时候也能挑出骨头来,继承的缺点如下:
    1)继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法;
    2)降低代码的灵活性。子类必须拥有父类的属性和方法,让子类自由的世界中多了些约束;
    3)增强了耦合性。当父类的常量、变量和方法被修改时,必需要考虑子类的修改,而且在缺乏规范的环境下,这种修改可能带来非常糟糕的结果——大片的代码需要重构
     
     

     

     

    4.接口隔离原则(Interface Segregation Principle,ISL):


    客户端不应该依赖那些它不需要的接口。(这个法则与迪米特法则是相通的

    定义:

    客户端不应该依赖那些它不需要的接口。

    另一种定义方法:一旦一个接口太大,则需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。
    注意 ,在该定义中的接口指的是所定义的方法。例如外面调用某个类的public方法。这个方法对外就是接口。
     
    原则分析:
     
    1) 接口隔离原则是指使 用多个专门的接口,而不使用单一的总接口 。每一个接口应该承担一种相对独立的角色,不多不少,不干不该干的事,该干的事都要干。
          (1) 一个接口就 只代表一个角色 ,每个角色都有它特定的一个接口,此时这个原则可以叫做“角色隔离原则”。 
          (2) 接口 仅仅提供客户端需要的行为 ,即所需的方法,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。 
    2) 使用接口隔离原则拆分接口时,首先必须满足 单一职责原则 ,将一组相关的操作定义在一个接口中,且在满足高内聚的前提下,接口中的方法越少越好。
    3) 可以在进行系统设计时采用 定制服务 的方式,即 为不同的客户端提供宽窄不同的接口 ,只提供用户需要的行为,而隐藏用户不需要的行为。

     

     

    例子:

    下图展示了一个拥有多个客户类的系统,在系统中定义了一个巨大的接口(胖接口) AbstractService 来服务所有的客户类。可以使用接口隔离原则对其进行重构。
     

    重构后:
     
     

    5.依赖倒转原则( Dependence Inversion Principle ,DIP ):


    要依赖抽象,而不要依赖具体的实现.

     

    定义:高层模块不应该依赖低层模块,它们都应该依赖抽象抽象不应该依赖于细节,细节应该依赖于抽象。简单的说,依赖倒置原则要求客户端依赖于抽象耦合。原则表述:

    1)抽象不应当依赖于细节;细节应当依赖于抽象;

    2)要针对接口编程,不针对实现编程。

    原则分析:

    1)如果说开闭原则是面向对象设计的目标,依赖倒转原则是到达面向设计"开闭"原则的手段..如果要达到最好的"开闭"原则,就要尽量的遵守依赖倒转原则. 可以说依赖倒转原则是对"抽象化"的最好规范! 我个人感觉,依赖倒转原则也是里氏代换原则的补充..你理解了里氏代换原则,再来理解依赖倒转原则应该是很容易的。

    2)依赖倒转原则的常用实现方式之一是在代码中使用抽象类,而将具体类放在配置文件中。 

     

    3) 类之间的耦合: 零耦合 关系, 具体耦合 关系, 抽象耦合 关系。 依赖倒转原则要求客户端依赖于抽象耦合 ,以抽象方式耦合是依赖倒转原则的关键。
     
    理解这个依赖倒置,首先我们需要明白依赖在面向对象设计的概念:
    依赖关系(Dependency): 是一种 使用关系 ,特定事物的改变有可能会影响到使用该事物的其他事物,在需要表示一个事物使用另一个事物时使用依赖关系。( 假设 A 类的变化引起了 B 类的变化,则说名 B 类依赖于 A 类。 )大多数情况下, 依赖关系体现在某个类的方法使用另一个类的对象作为参数 在UML中,依赖关系用带箭头的虚线表示, 由依赖的一方指向被依赖的一方。

    例子:某系统提供一个数据转换模块,可以将来自不同数据源的数据转换成多种格式,如可以转换来自数据库的数据(DatabaseSource)、也可以转换来自文本文件的数据(TextSource),转换后的格式可以是XML文件(XMLTransformer)、也可以是XLS文件(XLSTransformer)等。

    由于需求的变化,该系统可能需要增加新的数据源或者新的文件格式,每增加一个新的类型的数据源或者新的类型的文件格式,客户类 MainClass 都需要修改源代码,以便使用新的类,但违背了开闭原则。现使用依赖倒转原则对其进行重构。
     

    /**
     * 抽象接口
     * @author mo-87
     *
     */
    abstract public class AbstractSource {
    	abstract public  void getSource();
    }
    /**
     * 抽象接口
     * @author mo-87
     *
     */
    abstract public  class AbstractStransformer {
    	abstract public  void transform();
    }
    /**
     * 具体实现
     * @author mo-87
     *
     */
    public class DatabaseSource extends AbstractSource{
        
    	public  void getSource(){
    		 System.out.println("Get source data");  
    	}
    }
     
    /**
     * 依赖注入是依赖AbstractSource抽象注入的,而不是具体
     * DatabaseSource
     * 
     * @author mo-87
     *
     */
    public class XMLStransformer {
        /**
         * 
         */
    	private AbstractSource source; 
    	/**
    	 * 构造注入(Constructor Injection):通过构造函数注入实例变量。
    	 */
    	public void XMLStransformer(AbstractSource source){
    		this.source = source;         
    	}
    	                   
    	/**     
    	 * 设值注入(Setter Injection):通过Setter方法注入实例变量。
    	 * @param source : the sourceto set       
    	 */     
    	public void setSource(AbstractSource source) {          
    		this.source = source;           
    	}
    	/**
    	 * 接口注入(Interface Injection):通过接口方法注入实例变量。
    	 * @param source
    	 */
    	public void transform(AbstractSource source ) {  
    		source.getSource();
    		System.out.println("Stransforming ...");  
    	}    
    }
    依赖注入的三种写法:
    构造注入 (Constructor Injection) :通过 构造函数 注入实例变量。
    设值注入 (Setter Injection) :通过 Setter 方法 注入实例变量。
    接口注入(Interface Injection):通过 接口方法注入实例变量。
    public class XMLStransformer {
         /**
          * 
          */
    	private AbstractSource source; 
    	/**
    	 * 构造注入(Constructor Injection):通过构造函数注入实例变量。
    	 */
    	public void XMLStransformer(AbstractSource source){
    		this.source = source;         
    	}
    	                   
    	/**     
    	 * 设值注入(Setter Injection):通过Setter方法注入实例变量。
    	 * @param source : the sourceto set       
    	 */     
    	public void setSource(AbstractSource source) {          
    		this.source = source;           
    	}
    	/**
    	 * 接口注入(Interface Injection):通过接口方法注入实例变量。
    	 * @param source
    	 */
    	public void transform(AbstractSource source ) {  
    		source.getSource();
    		System.out.println("Stransforming ...");  
    	}    
    }

    优点:采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。

    依赖正置就是类间的依赖是实实在在的实现类间的依赖,也就是面向实现编程,这也是正常人的思维方式,我要开奔驰车就依赖奔驰车,我要使用笔记本电脑就直接依赖笔记本电脑,而编写程序需要的是对现实世界的事物进行抽象,抽象的结构就是有了抽象类和接口,然后我们根据系统设计的需要产生了抽象间的依赖,代替了人们传统思维中的事物间的依赖,“倒置”就是从这里产生的。


    6 .合成/聚合复用原则(Composite/Aggregate ReusePrinciple ,CARP):


    要尽量使用对象组合,而不是继承关系达到软件复用的目的

    定义:经常又叫做合成复用原则(Composite ReusePrinciple或CRP),尽量使用对象组合,而不是继承来达到复用的目的。

    就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新对象通过向这些对象的委派达到复用已有功能的目的。简而言之,要尽量使用合成/聚合,尽量不要使用继承。

    原则分析:

     

    1)在面向对象设计中,可以通过两种基本方法在不同的环境中复用已有的设计和实现,即通过 组合 / 聚合关系 或通过 继承
    继承复用 :实现简单,易于扩展。破坏系统的封装性;从基类继承而来的实现是静态的,不可能在运行时发生改变,没有足够的灵活性;只能在有限的环境中使用。( “白箱”复用
    组合/聚合复用 :耦合度相对较低,选择性地调用成员对象的操作;可以在运行时动态进行。( “黑箱”复用

    2)组合/聚合可以使系统更加灵活,类与类之间的耦合度降低,一个类的变化对其他类造成的影响相对较少,因此一般首选使用组合/聚合来实现复用;其次才考虑继承,在使用继承时,需要严格遵循里氏代换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统构建和维护的难度以及系统的复杂度,因此需要慎重使用继承复用

    3)此原则和里氏代换原则氏相辅相成的,两者都是具体实现"开-闭"原则的规范。违反这一原则,就无法实现"开-闭"原则,首先我们要明白合成和聚合的概念:
    什么是合成 ?
    合成(组合): 表示一个 整体与部分的关系, 指一个依托整体而存在的关系( 整体与部分 不可以分开 ),例如:一个人对他的房子和家具,其中他的房子和家具是不能被共享的,因为那些东西都是他自己的。并且人没了,这个也关系就没了。这个例子就好像,乌鸡百凤丸这个产品,它是有乌鸡和上等药材合成而来的一样。 也比如网络游戏中的武器装备合成一样,多种东西合并为一种超强的东西一样。
    虽然组合表示的是一个整体与部分的关系,但是组合关系中部分和整体具有统一的生存期。一旦整体对象不存在,部分对象也将不存在,部分对象与整体对象之间具有同生共死的关系。
    在组合关系中,成员类是整体类的一部分,而且整体类可以控制成员类的生命周期,即成员类的存在依赖于整体类。 在UML中,组合关系用带实心菱形的直线表示。
     
    源码:
    public class Head
    {
        private Mouth mouth;
        public Head() {
        	mouth = new Mouth();
        }
    }
    public class Mouth
    {
    }
      什么是聚合 ?
    聚合: 聚合是比合成关系的一种更强的依赖关系,也表示整体与部分的关系整体与部分可以分开,例如,一个奔驰S360汽车,对奔驰S360引擎,奔驰S360轮胎的关系..这些关系就是带有聚合性质的。因为奔驰S360引擎和奔驰S360轮胎他们只能被奔驰S360汽车所用,离开了奔驰S360汽车,它们就失去了存在的意义。在我们的设计中,这样的关系不应该频繁出现.这样会增大设计的耦合度。
    在面向对象中的聚合: 通常在定义一个整体类后,再去分析这个整体类的组成结构,从而找出一些成员类,该整体类和成员类之间就形成了聚合关系。 在聚合关系中, 成员类是整体类的一部分 ,即成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在。 在UML中,聚合关系用带空心菱形的直线表示。 
    比如汽车和汽车引擎:
     
     
    public class Car
    {
        private Engine engine;
        public Car(Engine engine) {
            this.engine = engine;
        }
        public void setEngine(Engine engine) {
            this.engine = engine;
        }
    }
    public class Engine
    {
    }
    明白了合成和聚合关系,再来理解合成/聚合原则应该就清楚了。要避免在系统设计中出现,一个类的继承层次超过3次。如果这样的话,可以考虑重构你的代码,或者重新设计结构. 当然最好的办法就是考虑使用合成/聚合原则。

     


    7.迪米特法则(Law of Demeter,LoD:


    系统中的类,尽量不要与其他类互相作用,减少类之间的耦合度

    定义又叫最少知识原则(Least Knowledge Principle或简写为LKP)几种形式定义:

    (1) 不要和“陌生人”说话。英文定义为:Don't talk to strangers.

    Ÿ(2) 只与你的直接朋友通信。英文定义为:Talk only to your immediatefriends.

    (3) 每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位

    简单地说,也就是,一个对象应当对其它对象有尽可能少的了解。一个类应该对自己需要耦合或调用的类知道得最少,你(被耦合或调用的类)的内部是如何复杂都和我没关系,那是你的事情,我就知道你提供的public方法,我就调用这么多,其他的一概不关心。

    法则分析:

     

    1)朋友类:
    在迪米特法则中,对于一个对象,其朋友包括以下几类:
    Ÿ (1) 当前对象本身 (this)
    Ÿ (2) 以参数形式传入到当前对象方法中的对象;
    Ÿ (3) 当前对象的成员对象;
    Ÿ (4) 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;
    Ÿ (5) 当前对象所创建的对象。
    任何一个对象,如果满足上面的条件之一,就是当前对象的“朋友”,否则就是“陌生人”。
     
    2)狭义法则和广义法则:
    在狭义的迪米特法则中,如果两个类之间不必彼此直接通信 那么这两个类就不应当发生直接的相互作用 ,如果其中的一个类需要调用另一个类的某一个方法的话,可以通过 第三者转发这个调用 。 

     

     
    狭义的迪米特法则 :可以 降低类之间的耦合 ,但是会在系统中增加大量的小方法并散落在系统的各个角落,它可以使一个系统的局部设计简化,因为每一个局部都不会和远距离的对象有直接的关联,但是也会 造成系统的不同模块之间的通信效率降低 ,使得系统的不同模块之间不容易协调。
    广义的迪米特法则 指对对象之间的信息流量、流向以及信息的影响的控制 ,主要是 对信息隐藏的控制 。信息的隐藏可以使各个子系统之间脱耦,从而允许它们独立地被开发、优化、使用和修改,同时可以促进软件的复用,由于每一个模块都不依赖于其他模块而存在,因此每一个模块都可以独立地在其他的地方使用。一个系统的规模越大,信息的隐藏就越重要,而信息隐藏的重要性也就越明显。
    3)迪米特法则的主要用途:在于控制信息的过载。
    在类的划分上,应当尽量 创建松耦合的类 ,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及;
    在类的结构设计上,每一个类都应当 尽量降低其成员变量和成员函数的访问权限
    在类的设计上,只要有可能, 一个类型应当设计成不变类
    在对其他类的引用上, 一个对象对其他对象的引用应当降到最低
     
     
     
    例子: 外观模式
     
     
     

    迪米特法则与设计模式Facade模式、Mediator模式使民无知

    系统中的类,尽量不要与其他类互相作用,减少类之间的耦合度,因为在你的系统中,扩展的时候,你可能需要修改这些类,而类与类之间的关系,决定了修改的复杂度,相互作用越多,则修改难度就越大,反之,如果相互作用的越小,则修改起来的难度就越小..例如A类依赖B类,则B类依赖C类,当你在修改A类的时候,你要考虑B类是否会受到影响,而B类的影响是否又会影响到C类. 如果此时C类再依赖D类的话,呵呵,我想这样的修改有的受了。

     

     

     
    米特法则是目的,而接口隔离法则是对迪米特法则的规范. 为了做到尽可能小的耦合性,我们需要使用接口来规范类,用接口来约束类.要达到迪米特法则的要求,最好就是实现接口隔离法则,实现接口隔离法则,你也就满足了迪米特法则。
     
     

    原文地址:hguisu 面向对象设计模式原则详解  http://blog.csdn.net/hguisu/article/details/7571617

     

    展开全文
  • 设计模式原则SOLID

    千次阅读 2015-11-16 14:50:03
    设计模式五大原则: 单一职责原则SRP告诉我们实现类要职责单一; 里氏替换原则LSP告诉我们不要破坏继承体系; 依赖倒置原则DIP告诉我们要面向接口编程; 接口隔离原则ISP告诉我们在设计接口的时候要精简单一; 开闭...
  • 设计模式六大原则——SOLID

    万次阅读 多人点赞 2018-08-12 20:34:32
    设计模式的六大原则有: Single Responsibility Principle:单一职责原则 Open Closed Principle:开闭原则 Liskov Substitution Principle:里氏替换原则 Law of Demeter:迪米特法则 Interface Segregation ...
  • 一什么是设计模式?  设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计 模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,...
  • 设计模式-七大原则(图解一目了然)

    千次阅读 多人点赞 2020-09-30 20:32:44
    你是不是还在这样写代码?当头一棒,看完本文快回去检查检查你的代码吧! 单一职责原则 接口隔离原则 依赖倒转原则 里氏替换原则 开闭原则 迪米特法则 合成复用原则
  • Java设计模式6大原则

    千次阅读 2019-03-01 18:50:45
    设计模式的6大原则,单一职责原则,开放封闭原则,里式替换原则,依赖导致原则,迪米特原则和接口隔离原则
  • 学习6大设计原则、23种设计模式

    万次阅读 多人点赞 2018-03-14 17:35:57
    了解设计模式的朋友们,想必都听说过“六大设计原则”吧。其实最经典的 23 种设计模式中或多或少地都在使用这些设计原则,也就是说,设计模式是站在设计原则的基础之上的。所以在学习设计模式之前,很有必要对这些...
  • 补充一下面对对象设计八大原则:前五大原则设计模式的前五大原则相同,为: 1、单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,...
  • 设计模式的总结有助于构建软件开发知识体系,为后期软件的架构设计、重构打下夯实基础,所以开设了Android设计模式专栏,... 本文重在总结设计模式和设计原则,后期会结合具体实例代码来说明常用的设计原则设计模式
  • 设计模式是软件大师们根据多年来的软件开发经验,对软件开发领域包括合理复用、提高健壮性、减少BUG等各方面作的抽象总结,不同的设计模式方法适合于不同的应用场景,是汇结了他们最宝贵的经验总结。最早的开发模式...
  • 依赖倒置原则和接口隔离原则的记录。 依赖倒置原则:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象; 接口隔离原则:建立单一接口,不要建立臃肿庞大的接口;
  • 设计模式七大原则

    千次阅读 多人点赞 2020-04-26 18:14:33
    设计模式遵循的原则设计模式七大原则1 设计模式的目的2 设计模式七大原则2-1 单一职责原则(Single Responsibility Principle, SRP)2-2 接口隔离原则(Interface Segregation Principle, ISP)2-3 依赖倒转原则...
  • 设计模式原则
  • java设计模式七大原则

    千次阅读 2018-06-05 10:26:33
    导图设计: 1.开闭原则 (Open Close Principle)   - 对扩展开放,对更改关闭     - 保证以前代码的准确性,使开发者更专注于新扩展的代码上 2. 单一职责原则 ( Single Responsibility Principle )   - 一个...
  • Java设计模式

    千次阅读 多人点赞 2019-09-03 23:20:31
    Java设计模式 1.工厂模式 工厂模式一般分为简单工厂、工厂、抽象工厂3钟情况,属于创建型设计模式。 2.生成器模式 3.观察者模式 4.桥接模式 5.代理模式 6.状态模式 7.访问者模式 ...
  • 设计模式之面向对象七大基本原则

    万次阅读 2015-04-27 16:25:48
    概述在运用面向对象的思想进行软件设计时,需要遵循的原则一共有7个,他们是:1. 单一职责原则(Single Responsibility Principle)每一个类应该专注于做一件事情。2. 里氏替换原则(Liskov Substitution Principle...
  • 软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。...
  • 简介: c++ 设计模式(8大设计原则、23中设计模式)李建忠 笔记总结 文章目录本博文的简述or解决问题?重要提示:重新认识面向对象面向对象设计原则(一共八种)将设计原则提升为设计经验C++设计模式(一共23种)本...
  • 设计模式之类之间的关系和六大原则1 类之间的关系1.1 继承关系1.2 实现关系1.3 依赖关系1.4 关联关系1.5 聚合关系1.6 组合关系1.7 总结2 六大原则2.1 单一职责原则2.2 开放-封闭原则2.3 依赖倒转原则2.4 里氏代换...
  • 里氏替换原则 开闭原则 依赖倒置原则 接口分离原则 迪米特法则 记忆方法: 一个单身(单一职责)的里氏(里氏替换原则)拿着一把颠倒(依赖倒置)的半开半闭(开闭原则)的扇子,在看接口分离(接口分离)问题,...
  • PHP设计模式——六大原则

    千次阅读 2015-04-06 23:18:54
    声明:本系列博客参考资料《大话设计模式》,作者程杰...这六大原则任何面向对象的语言都应该遵守的,要想让你的代码易扩展高服用就尽量去满足这六大原则吧,不一定严格按照某种设计模式,但是如果你的代码符合这六大原
  • 设计模式的六大原则

    万次阅读 多人点赞 2019-05-16 17:50:03
    一、单一职责原则(Single Responsibility Principle) 二.开闭原则(Open-Closed Principle, OCP) 三、里氏代换原则(Liskov Substitution Principle, LSP) 四、依赖倒置原则(Dependence Inversion Principle,...
  • 软件设计模式、目标、原则

    万次阅读 2016-05-27 19:10:52
    软件设计模式 一、设计目标: ⑴、软件设计目标:正确性、健壮性、灵活性、可重用性、高效性 1、正确性:也就是满足应用程序的需求。 2、健壮性:是指软件对于规范要求以外的输入情况的处理能力。也就是说,在...
  • 设计模式面试题(总结最全面的面试题!!!)

    万次阅读 多人点赞 2020-04-11 23:26:21
    文章目录设计模式什么是设计模式为什么要学习设计模式设计模式分类设计模式的六大原则开放封闭原则(Open Close Principle)里氏代换原则(Liskov Substitution Principle)依赖倒转原则(Dependence Inversion ...
  • 设计模式的六大基本原则

    千次阅读 2017-07-21 22:36:43
    1.开闭原则:开闭原则就是说对扩展...2.里氏替换原则:里氏替换原则是面向对象设计的基本原则之一。里氏替换原则说,任何基类出现的地方,子类一定可以出现。LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单
  • 设计模式总结及软件设计七大原则前言软件设计7大原则开闭原则(Open-Closed Principle,OCP)里氏替换原则(Liskov Substitution Principle,LSP)依赖倒置原则(Dependence Inversion Principle,DIP)单一职责原则...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 377,578
精华内容 151,031
关键字:

设计模式原则