zoukankan      html  css  js  c++  java
  • 设计模式笔记 设计原则

      上篇说到设计模式的精髓是原则和思想,这篇文章就详细介绍一下设计模式的原则。

    一、单一职责原则

    定义:就一个类而言,应该仅有一个引起它变化的原因。

      人都说,这个原则太普通了,和名字一样简单。不是说大道至简嘛,这个原则在程序设计中所占的份量还是很重的。

      一个类涉及的多项功能,如果其中一个功能发生改变需要修改,同类中就有可能会影响到其他已经实现好的功能。为了避免此类情况,可以将实现的功能单独出类来。当修改功能时是修改不同的类,就不会使其他类出现问题。

      话虽如此,在实际应用中往往会出现让人始料未及的情况。比如一个类实现了一个功能,在项目初期是符合单一职责原则的。但随着项目的开展,需求的改变,这个功能可能分化成两个或者多个功能(职责扩散),而部分功能代码已经完成,我们该如何呢?这是个现实的问题,是选择重构代码,还是在基础代码上进行修改(会违背单一职责原则),这就得看程序员们怎么把握这个度了。

    二、开放-封闭原则

    定义:软件实体(类、模块、方法等)应该可以扩展,但不可以修改。

      对于理解这个原则,实际上只要搞清楚开放的是什么,封闭的是什么。

      在实际开发中,我们的需求并不是一尘不变的。这就极大的挑战了在项目初期的设计,对后期的维护与需求的增加难度具有重大意义。

      然而这个原则取十分模糊。如果上司要求你设计个项目结构,要遵循开闭原则,你就会感觉仿佛什么都没说,却又好像什么都说了。笔者认为,如果很好的遵循了其他几个原则,开闭原则也就在不知不觉中实现。

    三、里氏代换原则

    定义:子类型必须能够替换掉它们的父类型。

      面向对象编程中,继承是非常重要的概念。里氏这个命名是因为这个原则是Barbara Liskov女士1988年发表的。名字并不重要,重要的是思想。

      简而言之,这个原则就是在程序设计的世界里,“爸爸能做的事情儿子一定能做”。在程序中,把所有的父类替换成子类并不影响程序的正常运行。只有这样,父类才能被真正复用,而子类也能够在父类的基础上增加新的行为。

      举个例子:

    Parent parent = new elderSon();
    parent.mathod1();
    parent.mathod2();
    parent.mathod3();
    

      如果需求改变了,程序扩展,只需要修改实例化时的子对象即可,如

    Parent parent = new youngerSon();//只修改此处
    parent.mathod1();
    parent.mathod2();
    parent.mathod3();
    

     程序单元不会起任何变化。

    四、依赖倒转原则

    定义:高层模块不应该依赖底层模块。两个都应该依赖抽象。抽象不应该依赖细节,细节应该依赖抽象。

      实际项目中,为了使常用的代码得到复用,会把常用的方法函数写成程序库。在新项目时,就可以调用底层程序库来实现简化程序的目的。如此做,便会出现高层模块依赖底层模块的问题。

      而由于需求的不同,会导致底层的实现有所差异,比如数据库连接,不同的数据库有不同的方法连接。这样在维护或拓展功能带来隐患。如果遵循依赖倒转原则便不会出现这种状况。如图:

    设计成

      如此便谁也不依赖谁,只有约定的接口,程序便可灵活的修改或复用。 

    五、迪米特法则(最少知识原则)

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

      一个对象对其他对象了解的最少,类的复用性才可以越高。迪米特法则的核心便是解耦合,只关心公开的方法,只调用公开的方法,其他的我不关心。那句话叫“不要和陌生人说话”。

      举个例子: 

    class A {
        public void doSomething() {
            System.out.println("do something over.");
        }
    }
    
    class B {
        private A a = new A();
    
        public A getA() {
            return a;
        }
    }
    
    class C {
        private B b = new B();
    
        public void doSomething() {
            A a = b.getA();
            a.doSomething();
        }
    }
    public class Client {
        public static void main(String[] args) {
            new C().doSomething();
        }
    
    }
    

     上面的设计便违反了迪米特法则。类C和类A并不是朋友(成员变量),在类C方法中出现类A是不合适的。应改为:

    class A {
        public void doSomething() {
            System.out.println("do something over.");
        }
    }
    
    class B {
        private A a = new A();
    
        public void doSomething() {
            a.doSomething();
        }
    }
    
    class C {
        private B b = new B();
    
        public void doSomething() {
            b.doSomething();
        }
    }
    public class Client {
        public static void main(String[] args) {
            new C().doSomething();
        }
    
    }
    

     如此,便符合了原则。

    六、接口隔离原则

    定义:客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上。

      俗话说,“狗拿耗子,多管闲事”。每一个接口都应该承担一种相对独立的角色,应该为客户端提供独立功能的小接口,不是总接口。

      网上看到两张图片,很好的阐释了这一原则

  • 相关阅读:
    DoubleAnimation
    Android 图片浏览器 从原来位置放大至全屏显示
    类似qq的左滑菜单栏简单实现
    UITableView去掉section的header的粘性
    swift 闭包循环引用
    AFNetworking3.0使用
    IOS线程学习(一)
    CIImage实现滤镜效果
    UIImage学习
    可滑动的ExpandableListView
  • 原文地址:https://www.cnblogs.com/adamJin/p/6889409.html
Copyright © 2011-2022 走看看