在lab3实验报告撰写中我写到:
复习时看到一句话"委托发生在对象层面,通过接口实现"
联想到实验报告中我的表述,感觉很是混乱。
后来再次阅读ppt并查阅相关资料,大致明白了其含义。
参考文章链接如下:
https://www.runoob.com/w3cnote/delegate-mode.html
https://www.runoob.com/design-pattern/adapter-pattern.html
对于委托,可以分为三种:
(其中第三种可以看为第二种的两种具体形态)
一.Dependency(临时性的委托,A use B)
其中Duck委托Flyable f实现fly,但是仅在参数中出现,甚至都没实例化,仅仅是用use用了一下,建立了临时性的委托。
二. Association(A has B)
一个类有另一个作为属性/实例变量(注意与第一个的区别),但是彼此仍可区分。
二.(1) Compositon(B is part of A) Association的强形态
(个人认为将其看作Association的强形态更易于理解也比较合理)
现在委托的B已经成为A的一部分属性,彼此不可区分,在内部创建
二.(2)Aggregation(A has B) Association的弱形态
(个人认为将其看作Association的弱形态更易于理解也比较合理)
注意,此时B是由外部创建作为参数传入A的,彼此之间可以区分
下面看一个例子区分一下:
其中,二者内部均有private HttpListener listener的委托,但第一个的listener是在外部创建传入WebServer的,可以动态变化,属于弱形态Aggregation, 第二个则是在其内部创建成为他的属性,属于强形态Composition
而对于最初的委托发生在对象层面,通过接口实现是什么意思呢?
是因为使用委托而不是继承,主要问题在于每个对象的具体方法不同,而不是类之间的不同。
个人理解为:这句话中的对象层面,通过接口实现,仅仅是区别于委托与类之间的继承,而通过接口实现,并不是指上述类之间的委托没有通过接口实现不算委托,而是代表一种更普适的实现方法(但也是通过接口implement到具体类),看下面两个例子:
其中,委托是通过接口I i实现的,只不过被implement为了具体类A,通过接口实现的方法更为普适,比如在适配器中:
我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。AdapterPatternDemo 类使用 AudioPlayer 类来播放各种格式。
其中适配器MediaPlayer就是通过接口AdvancedMediaPlayer实现的,对于传入的音频格式选择具体类VlcPlayer还是MP4Player,否则,需要在适配器MediaPlayer内部委托多个类(VlcPlayer与MP4Player)才可以实现同样的功能。
通过接口实现委托:
1.使用接口定义系统必须对外展示的不同侧面行为;
2.接口之间可以通过extends实现行为扩展;
3.类通过implements可以组合使用接口;
4.规避了复杂的继承关系,也让委托做到类型安全并且更加灵活。
以上仅是个人在软构学习过程中的心得与体会,如有错误欢迎及时指正!