设计模式基础学习一之设计原则

一、设计目标

    ① 恰当的体改系统的可复用性,可以提高系统的可扩展性。允许一个具有同样的接口的新类代替旧类,是对抽象接口的复用。客户端依赖于一个抽象的接口,而不是一个具体实现的类,使得这个具体类可以被另一个具体类所取代,而不影响到客户端。

      系统可扩展性是由“开-闭”原则(OCP)、里氏代换原则(LSP)、依赖倒置原则(DIP)和组合/聚合复用原则(CARP)所保证的。

    ② 恰当的提高系统的可复用性,可以提高系统的灵活性。在一个系统中,每一个模块相对独立,并只保持与其他模块尽可能少的通信。这样可使代码发生变化的模块不会影响到其他模块。

      系统灵活性是由“开-闭”原则(OCP)、迪米特法则(LoD)、接口隔离原则(ISP)所保证的。

    ③ 恰当的提高系统的可复用性,可以提高系统可插入性。在一个符合“开-闭”原则的系统中,抽象层封装了与商业逻辑有关的重要行为,这些行为的具体实现由实现层给出。

      系统的可插入性是由“开-闭”原则(OCP)、里氏代换原则(LSP)、组合/聚合复用原则(CARP)以及依赖倒置原则(DIP)保证的。


二、设计原则

  1、开-闭原则(OCP)

      “开-闭”原则:软件实体对扩展是开放的,修改是关闭的。即再设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,也就是应当可以不必修改源代码的情况下改变这个模块的行为。

      优点:

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

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

      对可变性的封装原则:

         “开-闭”原则如果从另一个角度讲述,就是所谓的“对可变性的封装原则”(EVP)。“对可变性的封装原则”讲的是找到一个系统的可变因素,将之封装起来。

         考虑设计中什么可能发生变化。与通常将焦点放到什么会导致设计改变的思考方式正好相反,这一思路考虑的不是什么会导致设计改变,而是考虑你允许什么发生变化而不让这一变化导致重新设计。

     “对可变性的封装原则”意味着两点:

        ① 一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里。同一种可变性的不同表象意味着同一个继承等级结构中的具体子类,因此,读者可以期待在设计模式中看到继承关系。

       继承应当被看做是封装变化的方法,而不是被认为是从一般的对象生成特殊对象的方法。

        ② 一种可变性不应当与另一种可变性混合在一起。所有类图的继承结构一般不会超过两层,不然就意味着将两种不同的可变性混合在一起。

      接口:第一种是指Java接口,这是一种Java语言中存在的结构,有特定的语法和结构;第二种仅仅是指一个类所具有的方法的特征集合,是一种逻辑上的抽象。前者叫作“Java接口”,后者叫作“接口”。

        在Java语言中,Java接口还可以定义public的常量。Java接口本身没有任何实现,因为Java接口不涉及表象,而只描述public行为,所以Java接口比Java抽象类更为抽象化。

        接口和类的最终要区别是,接口仅仅描述方法的特征,而不给出方法的实现;而类不仅给出方法的特征,而且还有方法的实现。因此,接口把方法的特征和方法的实现分割开来。这种分割,体现在接口常常代表一个角色,他包装与该角色相关的操作和属性,而实现这个接口的类便是扮演这个角色的演员。一个角色可以由不同的演员来演,而不同的演员之间除了扮演一个共同角色之外,并不要求有任何其他的共同之处。

      接口是对可插入性的保证:

         关联的可插入性:动态的将一个关联从一个具体类转换到另一个具体类,而这样做的唯一条件是他们都可以实现某个接口。

         调用的可插入性:一个对象不可避免地需要调用其他对象的方法,这种调用不一定非得是某一个具体类,而可以是一个接口。

      在理想情况下,一个具体Java类应当只实现java接口和抽象Java类生命过的方法,而不应当给出多余的方法。一些“相当有经验”的Java有一个使用Java接口的绝招:常量接口。所谓常量接口,是指用Java接口来声明一些常量,然后由实现这个接口的类使用这些常量。(Structs2中的ActionSupport类就是使用这种方式)

      抽象类:可以有实例变量,以及一个或多个构造方法,抽象类可以同时具有抽象方法和具体方法。

      类的继承关系:

          ① 子类是超类的一个特殊种类,而不是超类的一个角色,也就是要区分“Has-A”与“Is-A”两种关系的不同。Has-A关系应当使用聚合关系描述,而只有Is-A关系才符合继承关系。

          ② 永远不会出现需要子类换成另一个类的子类的情况。

          ③ 子类具有扩展超类的责任,而不是具有置换掉或注销超类的责任。如果子类需要大量地置换超类的行为,那么这个子类不应当成为这个超类的子类。

          ④ 只有在分类学角度上有意义时,才可以使用继承,不要从工具类继承。

  2、里氏代换原则(LSP)

      里氏代换原则是继承复用的基石。只用当衍生类可以替换掉基类,软件单位的功能不会受到影响时,基类才能真正被复用,而衍生类也才能够在基类的基础上增加新的行为。(反过来代换是不成立的)

  3、依赖倒置原则(DIP)

      依赖倒置原则是要依赖于抽象,不要依赖于具体。

  在面向对象的系统中,类与类之间三种耦合关系:

      ① 零耦合关系(Nil Coupling):如果两个类没有耦合关系,就称为零耦合关系

      ② 具体耦合关系(Concrete Coupling):具体性耦合关系发生在两个具体的(可实例化的)类之间,经由一个类对另一个具体类的直接引用造成。

      ③ 抽象耦合关系(Abstract Coupling):抽象耦合关系发生在一个具体类和一个抽象类(或者Java接口)之间,是两个必须发生关系之间存有最大的灵活性。

  4、接口隔离原则(ISP)

      接口隔离原则:使用多个专门的接口比使用单一的总接口要好。换言之,从一个客户端的角度来说,一个类对另外一个类的依赖性应当使建立在最小的接口上的。

      ① 角色的合理划分:一个接口相当于剧本中的一个角色,而此角色在一个舞台上由哪一个演员来演则相当与接口的实现。因此,一个接口应当简单地代表一个角色,而不是多个角色。如果系统涉及到多个角色,那么没一个角色都应当由一个特定的接口代表。

      ② 定制服务:将接口理解成为狭义的Java接口,接口隔离原则则讲的就是为同一个角色提供宽、窄不同的接口,以对付不同的客户端,这种方法在服务行业中叫作定制服务。根据响应的接口可以提供不同的服务。

      ③ 接口污染:过于臃肿的接口是对接口的污染(Interface Contamination),由于每一个接口都代表一个角色,实现一个接口的对象,在它的整个生命周期中都扮演这个角色,因此将角色区分清楚就是系统设计的一个重要工作。因此,一个逻辑的推断,不应当将几个不同的角色都交给同一个接口,而应当交给不同的接口。

  5、合成/聚合复用原则(CARP)

      合成/聚合复用原则经常又叫合成复用原则(CRP)。合成/聚合复用原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象 的一部分,新的对象通过向这些对象的委派达到复用已有功能的目的。(即尽量使用合成/聚合,尽量不使用继承)

  6、迪米特法则(Lod)

      迪米特法则又叫做最少知识原则(LKP),就是说,一个对象应当对其他对象有尽可能少的了解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拥有必珍惜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值