美文网首页
设计模式六大原则之依赖倒置原则

设计模式六大原则之依赖倒置原则

作者: lattr | 来源:发表于2017-12-01 13:23 被阅读106次

    定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

    问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

    解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率。

    以上内容来源于这里

    再来说一下几个概念:接口,抽象基类。

    在java中,类(Class)、接口(Interface)、实现类(Implement)分别是三个东西。

    在OC中类(Class)由.h文件(Interface)和.m文件(Implement)组成。

    所以OC中的Interface并不是java中的Interface。真正java中的接口对应于OC中的协议(Procotol)。

    OC中的并没有提供直接创建抽象基类的方式,一般都是通过在协议中定义方法属性等,再由一个类去遵守该协议的方式得到抽象基类。或者你不实现协议,直接定义一个类,规定几个方法,在实现文件里写这几个空方法,也可以把它当做抽象基类。

    何时使用抽象基类何时使用接口关键还是取决于待继承之间的联系。侧重于它们之间的个性差异还是共性联系。

    当个性大于共性。差异较大的个性间具有某些相同的行为,相同行为的实现方式有较大的区别,使用接口。

    当共性大于个性,共性相同的个体间必然具备相同的属性与行为,相同行为的实现方式具有一定区别,使用抽象基类。

    总结如下:

    当在差异较大的对象间寻求功能上的共性时,使用接口。

    当在共性较多的对象间寻求功能上的差异时,使用抽象基类。

    下面进入正题。

    需求,有一个VIP学员,比如我,想要学习设计模式的课程,于是我就依赖于这个课程,但是学完之后,我又想学机器学习的课程,我还得依赖于机器学习的课程,如果我想学习其他的比如安全攻防的课程,还得继续依赖,但是我学完这些后,我还想学其他的,因为我的心里只有学习,学习使我快乐。不过,打游戏也很快乐。我还得改动我自己的方法,怎么样不改动我自己,就能学习很多的课程呢?

    这时,我学习了依赖倒置原则,我应该学以致用,那么说来就来。

    依赖倒置说的是不依赖其他的类,只依赖接口(抽象类不依赖实现类,实现类依赖抽象类),就是OC中的协议,那么我就创建一个协议,协议里有一个方法叫学习。

    #ifndef StudyProtocol_h

    #define StudyProtocol_h

    @protocol StudyProtocol

    - (NSString *)study;

    @end

    #endif /* StudyProtocol_h */

    我通过协议来获取不同的课程

    #import <Foundation/Foundation.h>

    #import "StudyProtocol.h"

    @interface VIPStudent : NSObject

    - (void)studyCourse:(id<StudyProtocol> )course;

    @end

    再定义一个DesignPattern类,遵守StudyProtocol。

    #import <Foundation/Foundation.h>

    #import "StudyProtocol.h"

    @interface DesignPattern : NSObject<StudyProtocol>

    @end

    #import "DesignPattern.h"

    @implementation DesignPattern

    - (NSString *)study

    {

        return @"学习设计模式知识";

    }

    @end

    James老师的口头禅,这里有一个点(要是Hank老师,就是,解释一波):就是参数id<StudyProtocol>.

    那么id<StudyProtocol>和id有什么区别呢?

    普通id指针能指向任何对象,带协议的id只能指向遵从协议的类的对象。

    这样就可以将遵守该协议的课程类传给我了。

    调用:

    VIPStudent *vip = [[VIPStudent alloc] init];

    [vip studyCourse:[DesignPattern new]];

    [vip studyCourse:[CoreML new]];

    [vip studyCourse:[Safety new]];

    打印结果:

    s = 学习设计模式知识

    s = 学习机器学习知识

    s = 学习安全攻防班知识

    一个很简单的Demo,但是用到了面向协议编程。这里多说一点,使用继承中的多态,也能实现该需求,但是,到底该需求使用什么方式去写,判断的依据还是个性大于共性还是共性大于个性。

    大功告成,打完收工,奉上Demo

    相关文章

      网友评论

          本文标题:设计模式六大原则之依赖倒置原则

          本文链接:https://www.haomeiwen.com/subject/jmeibxtx.html