精华内容
下载资源
问答
  • PHP常用六大设计模式

    万次阅读 多人点赞 2019-04-03 17:05:22
    单例模式 特点: 三私一公:私有的静态变量(存放实例),私有的构造方法(防止创建实例),私有的克隆方法(防止克隆对象),公有的静态方法(对外界提供实例) 应用场景: 程序应用中,涉及到数据库操作时,如果每次...

    单例模式

    特点:

    三私一公:私有的静态变量(存放实例),私有的构造方法(防止创建实例),私有的克隆方法(防止克隆对象),公有的静态方法(对外界提供实例)

    应用场景:

    程序应用中,涉及到数据库操作时,如果每次操作的时候连接数据库,会带来大量的资源消耗。可以通过单例模式,创建唯一的数据库连接对象。

    <?php
    class Singleton
    {
        private static $_instance;
        private function __construct(){}
        private function __clone(){}
        public static function getInstance()
        {
            if(self::$_instance instanceof Singleton){//instanceof 判断一个实例是否是某个类的对象
                self::$_instance = new Singleton();
            }
            return self::$_instance;
        }
    }
    

    工厂模式

    特点:

    将调用对象与创建对象分离,调用者直接向工厂请求,减少代码的耦合.提高系统的可维护性与可扩展性。

    应用场景:

    提供一种类,具有为您创建对象的某些方法,这样就可以使用工厂类创建对象,而不直接使用new。这样如果想更改创建的对象类型,只需更改该工厂即可。

    //假设3个待实例化的类
    class Aclass
    {
    
    }
    class Bclass
    {
    
    }
    class Cclass
    {
    
    }
    class Factory
    {
        //定义每个类的类名
        const ACLASS = 'Aclass';
        const BCLASS = 'Bclass';
        const CCLASS = 'Cclass';
        public static function getInstance($newclass)
        {
            $class = $newclass;//真实项目中这里常常是用来解析路由,加载文件。
            return new $class;
        }
    }
    //调用方法:
    Factory::getInstance(Factory::ACLASS);
    

    注册树模式

    特点:

    注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘的模式设计方法。

    应用:

    不管你是通过单例模式还是工厂模式还是二者结合生成的对象,都统统给我“插到”注册树上。我用某个对象的时候,直接从注册树上取一下就好。这和我们使用全局变量一样的方便实用。而且注册树模式还为其他模式提供了一种非常好的想法。 (如下实例是单例,工厂,注册树的联合使用)

    //创建单例
    class Single{
        public $hash;
        static protected $ins=null;
        final protected function __construct(){
            $this->hash=rand(1,9999);
        }
    
        static public function getInstance(){
            if (self::$ins instanceof self) {
                return self::$ins;
            }
            self::$ins=new self();
            return self::$ins;
        }
    }
    
    //工厂模式
    class RandFactory{
        public static function factory(){
            return Single::getInstance();
        }
    }
    
    //注册树
    class Register{
        protected static $objects;
        public static function set($alias,$object){
            self::$objects[$alias]=$object;
        }
        public static function get($alias){
            return self::$objects[$alias];
        }
        public static function _unset($alias){
            unset(self::$objects[$alias]);
        }
    }
    //调用
    Register::set('rand',RandFactory::factory());
    $object=Register::get('rand');
    print_r($object);
    

    策略模式

    定义:

    定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。

    特点:

    策略模式提供了管理相关的算法族的办法; 策略模式提供了可以替换继承关系的办法;使用策略模式可以避免使用多重条件转移语句。

    应用场景:

    多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。比如上学,有多种策略:走路,公交,地铁…

    abstract class Strategy
    {
        abstract function goSchool();
    }
    class Run extends Strategy
    {
        public function goSchool()
        {
            // TODO: Implement goSchool() method.
        }
    }
    class Subway extends Strategy
    {
        public function goSchool()
        {
            // TODO: Implement goSchool() method.
        }
    }
    class Bike extends Strategy
    {
        public function goSchool()
        {
            // TODO: Implement goSchool() method.
        }
    }
    class Context
    {
        protected $_stratege;//存储传过来的策略对象
        public function goSchoole()
        {
            $this->_stratege->goSchoole();
        }
    }
    //调用:
    $contenx = new Context();
    $avil_stratery = new Subway();
    $contenx->goSchoole($avil_stratery);
    

    适配器模式

    特点:

    将各种截然不同的函数接口封装成统一的API。

    应用:

    PHP中的数据库操作有MySQL,MySQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。

    abstract class Toy
    {
        public abstract function openMouth();
    
        public abstract function closeMouth();
    }
    
    class Dog extends Toy
    {
        public function openMouth()
        {
            echo "Dog open Mouth\n";
        }
    
        public function closeMouth()
        {
            echo "Dog close Mouth\n";
        }
    }
    
    class Cat extends Toy
    {
        public function openMouth()
        {
            echo "Cat open Mouth\n";
        }
    
        public function closeMouth()
        {
            echo "Cat close Mouth\n";
        }
    }
    
    
    //目标角色(红)
    interface RedTarget
    {
        public function doMouthOpen();
    
        public function doMouthClose();
    }
    
    //目标角色(绿)
    interface GreenTarget
    {
        public function operateMouth($type = 0);
    }
    
    
    //类适配器角色(红)
    class RedAdapter implements RedTarget
    {
        private $adaptee;
    
        function __construct(Toy $adaptee)
        {
            $this->adaptee = $adaptee;
        }
    
        //委派调用Adaptee的sampleMethod1方法
        public function doMouthOpen()
        {
            $this->adaptee->openMouth();
        }
    
        public function doMouthClose()
        {
            $this->adaptee->closeMouth();
        }
    }
    
    //类适配器角色(绿)
    class GreenAdapter implements GreenTarget
    {
        private $adaptee;
    
        function __construct(Toy $adaptee)
        {
            $this->adaptee = $adaptee;
        }
    
        //委派调用Adaptee:GreenTarget的operateMouth方法
        public function operateMouth($type = 0)
        {
            if ($type) {
                $this->adaptee->openMouth();
            } else {
                $this->adaptee->closeMouth();
            }
        }
    }
    
    
    
    class testDriver
    {
        public function run()
        {
            //实例化一只狗玩具
            $adaptee_dog = new Dog();
            echo "给狗套上红枣适配器\n";
            $adapter_red = new RedAdapter($adaptee_dog);
            //张嘴
            $adapter_red->doMouthOpen();
            //闭嘴
            $adapter_red->doMouthClose();
            echo "给狗套上绿枣适配器\n";
            $adapter_green = new GreenAdapter($adaptee_dog);
            //张嘴
            $adapter_green->operateMouth(1);
            //闭嘴
            $adapter_green->operateMouth(0);
        }
    }
    //调用
    $test = new testDriver();
    $test->run();
    

    观察者模式

    特点:

    观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。观察者模式实现了低耦合,非侵入式的通知与更新机制。

    应用:

    一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。

    // 主题接口
    interface Subject{
        public function register(Observer $observer);
        public function notify();
    }
    // 观察者接口
    interface Observer{
        public function watch();
    }
    // 主题
    class Action implements Subject{
        public $_observers=[];
        public function register(Observer $observer){
            $this->_observers[]=$observer;
        }
    
        public function notify(){
            foreach ($this->_observers as $observer) {
                $observer->watch();
            }
    
        }
    }
    
    // 观察者
    class Cat1 implements Observer{
        public function watch(){
            echo "Cat1 watches TV<hr/>";
        }
    }
     class Dog1 implements Observer{
         public function watch(){
             echo "Dog1 watches TV<hr/>";
         }
     }
     class People implements Observer{
         public function watch(){
             echo "People watches TV<hr/>";
         }
     }
    // 调用实例
    $action=new Action();
    $action->register(new Cat1());
    $action->register(new People());
    $action->register(new Dog1());
    $action->notify();
    
    展开全文
  • 设计模式六大原则

    2018-03-06 10:06:57
    设计模式六大原则的一点总结,欢迎免费下载。 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计...
  • 文档为23种设计模式中的15种设计模式设计模式六大原则,里面写的某种模式的优缺点,适用场景,具体代码,注意事项,典型应用。具体写的挺好,希望能帮助你。
  • 设计模式六大原则.doc

    2020-05-06 22:41:28
    设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大原则...
  • 软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。...

     

    目录

    1.什么设计模式

    2.设计模式的发展

    3.设计模式6大原则

     3.1 开闭原则

    3.2  里氏转换原则

    3.3 依赖倒转原则

    3.4  接口隔离原则

    3.5  合成/聚合复用原则 

    3.6 迪米特原则


    1.什么设计模式

    软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。设计模式使代码开发真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。只有夯实地基搭好结构,才能盖好坚壮的大楼。也是我们迈向高级开发人员必经的一步。即12字真言:设计模式是设计经验的总结

     

    2.设计模式的发展

    说起设计模式的发展,还要从四个男人的故事(注意此处没有女人)开始说起,这四个男人分别是 Erich Gamma, Richard Helm,Ralph Johnson,和John Vlissides,他们是软件设计领域的四位世界顶级大师,那软件设计水平真是不知道高到哪里去了,反正我是自愧不如。这四位大佬合著了一本书《设计模式:可复用面向对象软件的基础》, 提出了23种基本设计模式,从理论高度提炼并规范了设计模式,对面向对象设计,软件复用领域产生了巨大影响。现在设计模式已经被应用到各种各样的编程语言中,不管是后端的Java,C#还是前端的JavaScript, 你都能看到它的身影,设计模式最大的魅力在于,不管在那种编程语言中,它思想和表现都是一样的,只是代码语法略有不同而已。

     

    3.设计模式6大原则

    设计模式存在的根本原因是为了更好地复用代码,增加代码可维护性。所以有如下6大原则:

     3.1 开闭原则

           对扩展开放,对修改关闭, 即在程序需要进行拓展的时候,不能去修改原有的代码,只能增加新的代码。

    这样的例子在我们的生活中随处可见,比如在各种选秀比赛里,如果两个选手在比赛中打成了平手,我们不可能说通过穿越到过去,去改变过去的结果,让他们不打成平手,这是不可能实现的。但是我们可以通过添加附加的比赛,决定他们的胜负。即已经发生的已经不可以改变 ,我们只能改变那些事情对现在的影响。

    3.2  里氏转换原则

            子类继承父类,任何基类出现的地方,一定可以用子类替代出现。

    这怎么理解呢?比如说你的朋友u盘A中有一些小电影,一天你们像往常一样,把u盘A插入电脑准备一起欣赏小电影,却发现u盘A坏了。这给正在兴致勃勃的你们顿时浇了一盆凉水,这时候你灵机一动说,幸好老子有备份。原来之前你已经把朋友u盘A中的小电影复制到了你的 u盘B中,而且你的u盘B中除了从朋友哪儿复制的小电影,还有一些其它不可描述的内容,这时候你有点犹豫要不要用自己的U盘B,看着正在兴头上的朋友,你一咬牙一跺脚说算了,不管那么多了,淦。于是你拔下朋友的u盘A插入自己的u盘B,顺利打开电影,于是你们又兴致勃勃的观看起来。即子类是对父类的完全复制,父类可以被子类完全替代,子类可以增加新的内容,而且不影响父类。

    3.3 依赖倒转原则

             引用一个对象,如果这个对象有底层类型,直接引用底层类型。

    说到这里不得不吐槽一些博客的博主,好歹也是写代码的,写博客的时候真没有一点设计模式的原则。前几天在网上搜一个问题,打开一看给我贴了一个另外博客的链接,打开这个链接之后又贴了另外一个博客的链接。。。。。。,你引用别人的博客我不反对,你这引用引用的博客就过分了吧。  总结一句话:引用的时候禁止套娃,直接引用最底层的类型

    3.4  接口隔离原则

    使用多个隔离的接口,比使用单个接口要好,每一个接口应该是一种角色。

    比如我们的电脑上有多种不同类型的接口,像USB接口,电源接口,高清输出接口等等,它们各自有着不同的功能,那么为什么不用一个接口完成所有的功能呢,这是因为不同的设备,有不同的数据规格,而且数据带宽需求也是是不同的,然他们都使用同一个接口是不科学的,这从usb与hdmi设备的使用环境就能看出来差别。但你也不能每个设备都分一个接口,这是不现实的,应该把统一数据规格的设备分为一个接口,例如USB接口可以同时支持,鼠标键盘和U盘。即使用多个接口,比使用单个接口要好,但是小得要有限度。

    3.5  合成/聚合复用原则 

    新的对象应使用一些已有的对象,使之成为新对象的一部分。

    举个例子:周末天气晴朗,你和好朋友约好一起去爬山(不是张东升的那种爬山),这时候就需要有一个相机,但是不巧的是你的相机坏了,于是你就拿着相机来到了修理店。老板告诉你有一个零件坏了,问你是要更换零件,还是再买一个新的呢?你心里MMP了一句对老板说,当然是更换零件了,我这相机才买没多久还新着呢。即用已经有的东西合成新的东西,使原来的东西成为新东西的一部分。

    3.6 迪米特原则

          一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立,即一个对象应对其他对象有尽可能少得了解。

    这里的对象可以理解为对象(女朋友),假如你是一个时间管理大师,同时交往了多个对象,当然由于身经百战,你对这些对象应付自如,不像我们这些老实人,一个都应付不来。但是这是你的小秘密,为了不让她们发现这个秘密,你就应该使这些对象之间应该尽可能少的了解,甚至完全不了解,如果她们之间了解过多,在相互八卦或者看朋友圈的时候,发现了你的这个小秘密,那可是要出大事情的(喜欢多人运动的除外)。即多个对象之间应该尽量避免有任何关联。

    本文只对设计模式进行了简单的介绍,有些例子可能也不太合适。如果想对设计模式有更多的了解,推荐看上文中四位大佬的那本书:《设计模式:可复用面向对象软件的基础》。

    如果觉得不错的话欢迎点赞,转发,评论!

    展开全文
  • 设计模式六大原则详解 设计模式原则详解 设计模式原则详解
  • 设计模式六大原则
  • 设计模式六大原则(6):开闭原则

    万次阅读 多人点赞 2012-02-27 08:48:41
    定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。 问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,... 开闭原则是面向对象设计

    定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

    问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。

    解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。

             开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统。开闭原则可能是设计模式六项原则中定义最模糊的一个了,它只告诉我们对扩展开放,对修改关闭,可是到底如何才能做到对扩展开放,对修改关闭,并没有明确的告诉我们。以前,如果有人告诉我“你进行设计的时候一定要遵守开闭原则”,我会觉的他什么都没说,但貌似又什么都说了。因为开闭原则真的太虚了。

             在仔细思考以及仔细阅读很多设计模式的文章后,终于对开闭原则有了一点认识。其实,我们遵循设计模式前面5大原则,以及使用23种设计模式的目的就是遵循开闭原则。也就是说,只要我们对前面5项原则遵守的好了,设计出的软件自然是符合开闭原则的,这个开闭原则更像是前面五项原则遵守程度的“平均得分”,前面5项原则遵守的好,平均分自然就高,说明软件设计开闭原则遵守的好;如果前面5项原则遵守的不好,则说明开闭原则遵守的不好。

             其实笔者认为,开闭原则无非就是想表达这样一层意思:用抽象构建框架,用实现扩展细节。因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节,我们用从抽象派生的实现类来进行扩展,当软件需要发生变化时,我们只需要根据需求重新派生一个实现类来扩展就可以了。当然前提是我们的抽象要合理,要对需求的变更有前瞻性和预见性才行。

             说到这里,再回想一下前面说的5项原则,恰恰是告诉我们用抽象构建框架,用实现扩展细节的注意事项而已:单一职责原则告诉我们实现类要职责单一;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合。而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。

             最后说明一下如何去遵守这六个原则。对这六个原则的遵守并不是是和否的问题,而是多和少的问题,也就是说,我们一般不会说有没有遵守,而是说遵守程度的多少。任何事都是过犹不及,设计模式的六个设计原则也是一样,制定这六个原则的目的并不是要我们刻板的遵守他们,而需要根据实际情况灵活运用。对他们的遵守程度只要在一个合理的范围内,就算是良好的设计。我们用一幅图来说明一下。

     

     

            图中的每一条维度各代表一项原则,我们依据对这项原则的遵守程度在维度上画一个点,则如果对这项原则遵守的合理的话,这个点应该落在红色的同心圆内部;如果遵守的差,点将会在小圆内部;如果过度遵守,点将会落在大圆外部。一个良好的设计体现在图中,应该是六个顶点都在同心圆中的六边形。

     

            在上图中,设计1、设计2属于良好的设计,他们对六项原则的遵守程度都在合理的范围内;设计3、设计4设计虽然有些不足,但也基本可以接受;设计5则严重不足,对各项原则都没有很好的遵守;而设计6则遵守过渡了,设计5和设计6都是迫切需要重构的设计。

             到这里,设计模式的六大原则就写完了。主要参考书籍有《设计模式》《设计模式之禅》《大话设计模式》以及网上一些零散的文章,但主要内容主要还是我本人对这六个原则的感悟。写出来的目的一方面是对这六项原则系统地整理一下,一方面也与广大的网友分享,因为设计模式对编程人员来说,的确非常重要。正如有句话叫做一千个读者眼中有一千个哈姆雷特,如果大家对这六项原则的理解跟我有所不同,欢迎留言,大家共同探讨。

     下面是前面5项设计原则的链接

    1.  单一职责原则(Single Responsibility Principle)

    2.  里氏替换原则(Liskov Substitution Principle)

    3.  依赖倒置原则(Dependence Inversion Principle)

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

    5.  迪米特法则(Law Of Demeter)

    同时为了方便想收藏的朋友,下面给出word版本的下载。

    word版本下载链接:设计模式六大原则

     

     

    展开全文
  • 1. 设计模式分类 设计模式分为三种类型,共23类。(1)创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。(2)结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式...

    1. 设计模式三大分类  

    设计模式分为三种类型,共23类。

    1创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。

    2结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

    3行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。

     

    2.  六大原则

    2.1 单一职责原则

    单一职责原则是指,不要让一个类承担过多的职责。避免职责耦合在一起,避免一个职责的变化影响到其他职责。

    比如在Activity中存在网络请求的逻辑,导致Activity过于臃肿,导致引起这个Activity变化的原因太多,这样就违反了单一职责原则,不利于后续的版本维护。

    最后再来理解一下单一职责的定义——就一个类而言,应该仅有一个引起它变化的原因。

     

    2. 2 开放封闭原则

    在开发过程中,需求的变化如果要通过修改原有的代码来完成,那么就很可能将新的错误引入到旧的代码中。因此才有了开放封闭原则。就是说,需求改变时,我们应该尽量通过拓展的方式、即加入新代码来实现变化

    比如我们要实现一个银行业务的逻辑,如下所示:

    //By SEU_Calvin on 2017/03/27
    public class BankProcess {
    	public void Deposite() {//存款
    	}
    	public void Withdraw(){//取款
    	}
    }
    
    public class BankStaff {
    	private BankProcess bankpro = new BankProcess();
    	public void BankHandle(Client client) {
    		switch (client.Type) {
    		case "deposite": // 存款
    			bankpro.Deposite();
    			break;
    		case "withdraw": // 取款
    			bankpro.Withdraw();
    			break;
    		}
    	}
    }
    

    这样直接调用BankStaff.BankHandle()方法,通过传入的参数完成对应的存取款功能。

    但是这时加入了转账业务呢,就需要去修改BankProcess类,这样既违反了单一职责原则,也违反了我们的开放封闭原则,因为BankProcess职责不单一,且新需求需要修改已有的代码。因此可以使用的接口的方式进行优化:

    //By SEU_Calvin on 2017/03/27
    public interface IBankProcess {
    	void Process();
    }
    
    public class DeposiProcess implements IBankProcess {
    	public void Process(){ // 办理存款业务
    	}
    }
    
    public class WithDrawProcess implements IBankProcess{
    	public void Process(){ // 办理取款业务
    	}
    }
    
    public class TransferProcess implements IBankProcess{
    	public void Process(){        //办理转账业务
        }
    }
    
    public class BankStaff {
    	private IBankProcess bankpro = null;
    
    	public void BankHandle(Client client) {
    		switch (client.Type) {
    		case "Deposite": // 存款
    			bankpro = new DeposiProcess();
    			break;
    		case "WithDraw": // 取款
    			bankpro = new WithDrawProcess();
    			break;
    		case "Transfer": // 转账
    			bankpro = new TransferProcess();
    			break;
    		}
    		bankpro.Process();
    	}
    }
    

    这样如果我们再添加功能,你会发现我们不需要修改原有的类,只需要添加一个功能类的子类即可。

    最后再来理解一下开放封闭的定义——软件中的对象(类、模块、函数等)应该对于拓展是开放的,而对于修改是封闭的。


    2.3  里氏替换原则

    里氏代换原则告诉我们,只要父类出现的地方,子类就可以出现,替换为子类后不会产生任何错误和异常,当然反过来未必适应。

    我们在运用里氏代换原则时,尽量把父类设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,在运行时再确定其子类类型,用子类实例来替换父类实例。如2的例子中对bankpro的实例化。就可以很方便地扩展系统的功能,同时无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。因此说,里氏替换原则是开闭原则的具体实现手段之一。

    最后再来理解一下里氏替换原则的定义——所有引用基类(父类)的地方必须能透明地使用其子类的对象。

     

    2.4  依赖倒置原则

    依赖倒置原则在Java中是指接口或抽象类不依赖于实现类,而实现类依赖接口或抽象类。

    就是说如果类与类直接依赖细节,那么就会直接耦合,那么当修改时,就会同时修改依赖者代码,这样限制了可扩展性。依赖倒置就是为了解决耦合。让程序依赖于抽象。

    举个简单的例子:

    //By SEU_Calvin on 2017/03/27
    public class Fute {
    	public void run() {
    		System.out.println("福特汽车启动");
    	}
    
    	public void stop() {
    		System.out.println("福特汽车停止");
    	}
    }
    
    public class Bentian {
    	public void run() {
    		System.out.println("本田汽车启动");
    	}
    
    	public void stop() {
    		System.out.println("本田汽车停止");
    	}
    }
    
    public class AtuoRunSystem {
    
    	private String mType;
    	private Bentian bentian = new Bentian();
    	private Fute fute = new Fute();
    
    	public AtuoRunSystem(String type) {
    		mType = type;
    	}
    
    	public void AutoRun() {
    		if ("bentian".equals(mType)) {
    			bentian.run();
    		} else {
    			fute.run();
    		}
    	}
    
    	public void AutoStop() {
    		if ("bentian".equals(mType)) {
    			bentian.stop();
    		} else {
    			fute.stop();
    		}
    	}
    }
    

    代码很简单,但是缺点也很明显,扩展性特别差,现在只有两种车,if-else语句还算简单,假设以后有100种车

    //By SEU_Calvin on 2017/03/27
    public interface Icar {
    	void run();
    	void stop();
    }
    
    public class Fute implements Icar {
    
    	public void run() {
    		System.out.println("福特汽车启动");
    
    	}
    
    	public void stop() {
    		System.out.println("福特汽车停止");
    
    	}
    
    }
    
    public class Bentian implements Icar {
    
    	@Override
    	public void run() {
    		System.out.println("本田汽车启动");
    
    	}
    
    	@Override
    	public void stop() {
    		System.out.println("本田汽车停止");
    
    	}
    
    }
    
    public class AtuoRunSystem {
    
    	private Icar icar;
    
    	public AtuoRunSystem(Icar icar) {
    		this.icar = icar;
    	}
    
    	public void autoRun() {
    		icar.run();
    
    	}
    
    	public void autoStop() {
    		icar.stop();
    	}
    
    }
    

    经过改造,再加入新车我们也不怕了。这种设计也充分说明了,类与类不应该直接依赖细节,因为这样会导致耦合,限制了可扩展性,而是让类与类直接依赖抽象

     

    2.5  迪米特原则

    也称为最少知识原则,是指一个对象应该对其他对象有最少的了解

    通俗的讲,一个类对自己需要耦合的类应该知道的最少,你内部多么复杂和我没关系,我只对你提供的public方法感兴趣。这样的话,如果一个系统符合迪米特法则,那么当其中某一个类发生修改时,就会尽量少地影响其他模块,降低系统的耦合度,使类与类之间保持松散的耦合关系

    下面是老师让班长清点班级人数的例子:

    //By SEU_Calvin on 2017/03/27
    public class Teacher {
    	public void commond(Monitor monitor) {
    		List<Student> lists = new ArrayList();
    		// 初始化同学
    		for (int i = 0; i < 20; i++) {
    			lists.add(new Student());
    		}
    		// 告诉班长清点人数
    		monitor.count(lists);
    	}
    }
    
    public class Monitor {
    	// 有清查女生的工作
    	public void count(List<Student> lists) {
    		System.out.println(lists.size());
    	}
    }
    
    //调用时
    Teacher teacher= new Teacher();
    teacher.commond(new Monitor());
    

    我们看到Teacher类不仅与Monitor类产生了关系,还和Student类产生了关系。产生了不必要的耦合。这样Student类的变化不仅影响Monitor类,还会影响到Teacher类。程序优化修改后如下,调用方法不变:

    //By SEU_Calvin on 2017/03/27
    public class Teacher {
    	public void commond(Monitor monitor) {
    		monitor.count();
    	}
    }
    
    public class Monitor {
    	public void count() {
    		List<Student> lists = new ArrayList();
    		for (int i = 0; i < 20; i++) {
    			lists.add(new Student());
    		}
    		System.out.println(lists.size());
    	}
    }
    
    //调用时
    Teacher teacher= new Teacher();
    teacher.commond(new Monitor());
    

    2.6  接口隔离原则

    接口隔离原则的含义是:建立单一接口而不是建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

    比如说,定义了一个接口MyInterface

    public interface MyInterface{
        public void method1();  
        public void method2();  
        public void method3();  
    }
    

    但是实现类A只想实现接口中的method1方法,而实现类B只想实现接口中的method2method3方法。

    此时只写一个接口让AB都去实现该接口的话,会导致AB中会实现不需要的方法,这样设计接口会导致接口比较臃肿,因此我们应该要把这个接口拆分开来写

    很多人会觉的接口隔离原则跟之前的单一职责原则很相似,其实不然。单一职责原则注重的是职责,针对的是程序中的实现和细节;而接口隔离原则注重的是对接口依赖的隔离,主要针对抽象。

    最后理解一下接口隔离原则的定义:类间的依赖应该建立在最小的接口上


    展开全文
  • 设计模式六大原则

    万次阅读 多人点赞 2019-05-16 17:50:03
    、迪米特法则(Law of Demeter, LoD) 总结 一、单一职责原则(Single Responsibility Principle) 定义 :一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化...
  • 1.设计模式六大设计原则详解

    千次阅读 2016-05-09 11:22:58
    闲话开年做总结的时候说,今年要搞一搞phpunit、设计模式等。测试的坑我已经填了,今天开始来填设计模式的坑了。 之前看文章(不记得是哪儿了,对不起啊,作者)说:设计模式这个东西,是因为我们思维的局限,没...
  • android之设计模式六大原则

    千次阅读 2015-04-17 09:34:44
    设计模式六大原则1单一职责原则设计模式六大原则2里氏替换原则设计模式六大原则3依赖倒置原则设计模式六大原则4接口隔离原则设计模式六大原则5迪米特法则设计模式六大原则6开闭原则 本文转自:...
  • 设计模式六大原则

    千次阅读 2020-08-16 16:31:20
    设计模式六大基本原则 一、开闭原则 (一)定义:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。 (二)目的: 开闭原则是面向对象程序设计的终极...
  • 设计模式六大设计原则

    千次阅读 2018-09-01 23:03:28
    设计模式六大设计原则 面向对象的特征:封装、抽象、继承、多态 单一职责原则(功能拆分) 核心:提高程序的可重用性 一个类只能有一个引起它变化的原因 解决的问题:降低类的复杂度、降低部件的耦合度 里氏代换...
  • 设计模式-六大设计原则

    千次阅读 2018-07-31 00:01:19
    1. 单一职责原则(SRP) 定义:就一个类而言,应该仅有一个引起它变化的原因。...这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到破坏。  比如我经常看到一些Android开发在Activity中写Bean文...
  • 设计模式源码下载地址 设计模式源码下载地址 1 单一功能原则 单一功能原则(Single responsibility principle)规定每个类都应该有一个单一的功能,并且该功能应该由这个类完全封装起来。所有它的(这个类...
  • 设计模式分类以及六大设计原则(汇总篇)

    万次阅读 多人点赞 2018-05-22 22:36:28
    设计模式的分类 创建型模式,共五种: 单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。 结构型模式,共七种: 适配器模式、装饰者模式、代理模式、门面模式(外观模式)、桥梁模式、组合模式、享...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 258,303
精华内容 103,321
关键字:

六大设计模式