zoukankan      html  css  js  c++  java
  • 设计模式六大原则(二)

    依赖倒置原则

    依赖倒置的核心是高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。具体一点说:安排一件事给某一个人做,我们不应该限制是某一种人,比如小孩、青年、老人等,而是限制为人,这样做的好处就是如果有不同的事情,可以不同的人完成。比如跨栏,就用青年人完成。这个例子中的高层模块是“事”,依赖的模块是“人”,底层模块是“小孩、青年、老人等”,“人”是底层模块的抽象,当然,“事”也是一个抽象,“跨栏”则是底层模块的细节。

    <?php
    
    
    namespace FactoryReplaceModel;
    
    /**
     * Class WrongClassYoung
     * @package FactoryReplaceModel
     */
    class WrongClassYoung
    {
        /**
         *
         */
        public function run()
        {
            echo 'biu';
        }
    }
    
    /**
     * Class WrongClassHurdle
     * @package FactoryReplaceModel
     */
    class WrongClassHurdle
    {
        /**
         * @param WrongClassYoung $wrongClassYoung
         */
        public function do(WrongClassYoung $wrongClassYoung)
        {
            $wrongClassYoung->run();
        }
    }
    
    $wrongClassYoung = new WrongClassYoung();
    $wrongClassHurdle = new WrongClassHurdle();
    // 此种方式限制很多,只能做跨栏运动,也只能青年人参加。
    // 如果需要添加一项运动,则需要重新添加新的类,由于没有对类的限制,可能实现方法不同,比如,赛跑start(),拔河start(),
    // 这就需要我们知道每一项运动的开始方法,工作量大,且容易混乱
    $wrongClassHurdle->do($wrongClassYoung);
    
    
    // 优化后的类
    // 运动员
    /**
     * Interface Sportsman
     * @package FactoryReplaceModel
     */
    interface Sportsman
    {
        /**
         * @return mixed
         */
        public function start();
    }
    
    /**
     * Class YoungSportsman
     * @package FactoryReplaceModel
     */
    class YoungSportsman implements Sportsman
    {
        /**
         * @return mixed|void
         */
        public function start()
        {
            echo 'biu';
        }
    }
    
    /**
     * Class ChildrenSportsman
     * @package FactoryReplaceModel
     */
    class ChildrenSportsman implements Sportsman
    {
        /**
         * @return mixed|void
         */
        public function start()
        {
            echo 'biu biu';
        }
    }
    
    /**
     * 运动项目
     * Interface SportEvent
     * @package FactoryReplaceModel
     */
    interface SportEvent
    {
        /**
         * @param Sportsman $sportsman
         * @return mixed
         */
        public function do(Sportsman $sportsman);
    }
    
    /**
     * 跨栏运动
     * Class HurdleSportEvent
     * @package FactoryReplaceModel
     */
    class HurdleSportEvent implements SportEvent
    {
        /**
         * @param Sportsman $sportsman
         * @return mixed|void
         */
        public function do(Sportsman $sportsman)
        {
            $sportsman->start();
        }
    }
    
    /**
     * 拔河运动
     * Class TugOfWar
     * @package FactoryReplaceModel
     */
    class TugOfWar implements SportEvent
    {
        /**
         * @param Sportsman $sportsman
         * @return mixed|void
         */
        public function do(Sportsman $sportsman)
        {
            $sportsman->start();
        }
    }
    
    $tugOfWar = new TugOfWar();
    
    // 青年拔河比赛
    $youngSportMan = new YoungSportsman();
    $tugOfWar->do($youngSportMan);
    
    // 儿童拔河比赛
    $childrenSportsman = new ChildrenSportsman();
    $tugOfWar->do($childrenSportsman);
    
    // 优化后的类中,运动员可以灵活替换,不会改动代码内部构造,也不会对已有的内容造成影响。
    //其中运动项目也可以再进行优化,优化至项目可以灵活更换
    

    接口隔离原则

    这里的接口并不是“interface”,接口隔离原则的核心是只用自己需要的接口。比如:我们吃饭的时候,有套餐,套餐一般会便宜一些,且已经搭配合理。但是如果套餐中有我们不喜欢的,那么套餐对我们而言就是不好的,这个时候我们就需要单点(隔离),我们可以根据自己需要的去自由搭配。接口隔离原则就如同吃饭单点一样,我们只获取自己需要的,不需要的一概不要

    迪米特法则

    之和直接朋友交流是迪米特法则的核心思想,比如B是A的朋友,C是B的朋友,则A不能直接和C交际。程序中最容易出现这种情况,为了方便,直接调用一个毫不相关的类。比如:A(PeopleClass),属于一个俱乐部(ClubClass),俱乐部老板(ClubBossClass),当我们需要获取A所属俱乐部老板的手机号时,很可能会直接调用老板的类,而跳过俱乐部。但俱乐部老板和A没有直接关系的,它们的关系是俱乐部维持的。

    <?php
    
    
    namespace FactoryReplaceModel;
    
    
    /**
     * Class ClubClass
     * @package FactoryReplaceModel
     */
    class ClubClass
    {
        /**
         * @return ClubBossClass
         */
        public function getBoss()
        {
            return new ClubBossClass();
        }
    }
    
    /**
     * Class ClubBossClass
     * @package FactoryReplaceModel
     */
    class ClubBossClass
    {
        /**
         * @return string
         */
        public function getPhone()
        {
            return 'phone';
        }
    }
    
    /**
     * false
     * Class AFalseClass
     * @package FactoryReplaceModel
     */
    class AFalseClass
    {
        /**
         * @param ClubBossClass $clubBossClass
         * @return string
         */
        public function getClubBossPhone(ClubBossClass $clubBossClass)
        {
            return $clubBossClass->getPhone();
        }
    }
    
    /**
     * true
     * Class ATrueClass
     * @package FactoryReplaceModel
     */
    class ATrueClass
    {
        /**
         * @param ClubClass $clubClass
         * @return string
         */
        public function getClubBossPhone(ClubClass $clubClass)
        {
            return $clubClass->getBoss()->getPhone();
        }
    }
    
    
  • 相关阅读:
    Windows平台下Glade+GTK开发环境的搭建
    uCOSII移植STM32F10x_Keil
    C语言中的内存管理与双向链表
    Windows平台下Glade+GTK实现多线程界面的探讨
    C语言中可变形参个数的函数实现
    从STM32的位带操作重谈嵌入式中寻址与对齐的理解
    uCOSII的中断ARM7实现中断嵌套的方法探究
    uCOSII中的内存管理C语言构建完整的微型动态内存管理机制
    uCOSII中的任务切换图解多种任务调度时机与问题
    uCOSII中的任务切换机制
  • 原文地址:https://www.cnblogs.com/it-abel/p/11546652.html
Copyright © 2011-2022 走看看