设计模式复习小结一(Strategy Pattern/Observer Pattern/Decorator Patter/Factory Pattern)
目录:
前言:
因为在学习过程中总是不断忘记,很多东西也是一知半解,所以学一点就又倒回来再复习一次,第一次学习的时候我主要以实现书中的代码为主,而现在复习的时候我就以弄清楚逻辑为主了,毕竟第一次基本都是只要能实现功能就大吉大利了。所以这次小阶段的复习,我就没有再在文章中写代码了,以画UML图为主,边弄清楚逻辑,边搞懂那些知识点。
复习果然是温故而知新,确实了解到了之前比较迷茫的点,但是还是有很多不明确之处,我觉得应该还需要等把设计模式全部学完一次后再重新倒过来再看一次,可能会有其他收获吧。虽然文中全是UML图,但是所有的例子,在最后我的github中都已经上传了源代码,欢迎指教(#^.^#)。
ppps:在复习的过程我记录下来整理成博客来分享,但是我觉得我还是说的不是很清楚,只是自己能靠着UML图和实例能大概了解到自己需要了解的知识点,但是介绍出来老是感觉哪里欠缺,我确实需要好好学习一下,怎么正确表述我的观点了。当然,这也是需要坚持写博客的原因了ヾ(◍°∇°◍)ノ゙,要是我的表述让您无法理解,请不吝赐教,让我慢慢了解到应该怎么和别人交谈。
1. Stratrgy Pattern 策略模式
策略模式定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
解析:
策略模式的主要组成部分主要包括Context/Strategy这两个部分。
策略类定义了所有支持的算法的公共接口。
其实StrategyPattern就是将代码尽量的变小,各部分功能尽量单一化,将相似的功能放进同一个函数或者接口里,这个函数或者接口也就是ConcreteStrategyABC了。
实例解析1:
详细解释:C#学习笔记-策略模式
这里将优惠的方式分为三种,1:正常收费;2:折扣;3.满减活动;题目中所提到的优惠方式不外乎这三种,所以将优惠方式做成一个接口CashSuper,然后往下再分支成三种具体的优惠方式,这样我们要是某一种优惠方式有变动,直接去具体的那种优惠方式中修改即可,同时,要是添加了新的优惠方式,直接继承CashSuper这个接口,然后添加新的实现方式就好了,这样保证了原来代码的安全,也添加了新的功能。这也是我们的设计原则:封装变化
。
实例解析2:
我们设计一些鸭子,这些鸭子有:绿头鸭、红头鸭、橡皮鸭、诱饵鸭等,他们有各自的外貌特征,同时有各自不同的叫声,有的鸭子例如绿头鸭可以飞行,但是橡皮鸭这些却不能飞行。请设计出这些鸭子。
解析:
鸭子的外貌可以设定为属性,但是叫声和飞行就是两种动作,且有不同种情况:飞行FlyBehavior有两种(FlyWithWings/FlyNoWay两种具体的不同的实现行为),叫声QuackBehavior有很多种情况(例如:Quack/Squeak/MuteQuack),所以我们将飞行行为和叫声这两种行为封装起来,这样保证了不同的鸭子调用自己不同的行为即可,同时保证了如果添加了新的鸭子又有新的行为时,方便添加新的具体的行为进来。
具体实现:
小结:
好的代码就是让代码变得易维护,而这就是策略模式最大的优点。
2. Observer Pattern 观察者模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使他们能够自动更新自己。
解析:
观察者模式重要的是Subject/Observer这两个接口。
Subject:他把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供了一个接口,可以删除和增加观察者对象。
Observer:抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。
抽象模式有两个方面,其中一个人方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立的改变和复用。
实例解析1:
详细解释:C#学习笔记-观察者模式
对于具体的Observer而言(也就是MemberOne和MemberTwo),具体的Subject是谁,他们并不需要知道,只要作为Subject的那个人将有用的信息传递给他们就好了。同理,作为具体的Subject而言,不需要知道每一个Observer是谁,只需要在信息更新的时候,将有用的信息传递给在他那注册了的成员就好了。这就实现了软件设计的一个重要原则:为交互对象之间的松耦合设计而努力。
实例解析2:
现在需要建立气象观测站的一个应用:目前有三种布告板,分别显示目前的状况、气象统计即简单的预报。当WeatherObject对象获得最新的测量数据时,三种布告板必须实时更新。
解析:
这个题目很明显符合了OberverPattern要求,三个布告板理所当然地就是具体的Observer了,获取各种信息的WeatherData就是具体的Subject了。
具体实现:
小结:
松耦合设计更加有弹性,更能应对变化。
3. Decorator Pattern 装饰模式
装饰模式,动态地给一个对象添加一些额外的职责。
解析:
不管是ConcreteComponent还是Decorator,亦或是ConcreteDecoratorABC,他们都继承来自于Component,所以所有的一切都相当于是对Component功能的扩展,这也就是装饰模式的意义。
实例解析1:
解析:
详细解释:C#学习笔记-装饰模式
只需要注意一点:服饰作为装饰品,需要专门记住他需要装饰的对象,不然装饰就没有任何意义了。
实例解析2:
我们现在来做饮料,每一种饮料有不同的配料,每一种配料价格不一样,名字不一样,例如:现在顾客想要一杯加了奶泡和摩卡的深烘焙,我们需要得到各种搭配的饮料的价格。
解析:
首先具体的饮料例如上面说的“深烘焙”在这里就是具体的Component了,那些奶泡或者摩卡都是为了修饰他而存在的,所以同理,奶泡和摩卡之类就是ConcereteDecoratorABC了。仍然要注意的是奶泡那些不许携带他们需要修饰的对象Beverage,不用指定具体修饰的哪一种Beverage,但是必须有需要修饰的对象。
具体实现:
小结:
好的代码是对扩展开放,对修改关闭。
4. Factory Pattern 工厂模式
4.1 FactoryPattern工厂模式
工厂模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。
解析:
需要注意的是:工厂方法必须要返回一个Product类型的对象,因为工厂方法的唯一的作用就是实例化一个Product。
实例解析1:
写一个简单的计算机。
解析:
将计算中的加减乘除分为四个类,这样可以相互不干扰,但是都继承于计算这个类,然后建立OperationFactory来通过用户传输进来的符号来判断到底我们需要调用那种计算方式,也就是实例化哪一种类。
具体实现:
详细解释:C#学习笔记-工厂模式
实例解析2:
我们现在开披萨连锁店,在纽约、芝加哥和加州开披萨连锁店,不同的地区根据当地人的口味设计不同味道的同披萨。
解析:
现在作为客人的我们要选择披萨的时候,店家首先需要根据我们的选择来确定是哪个地区的哪种风味的披萨,所以这个时候需要实例化的就是根据选择的披萨来实例化该地区的那种风味的披萨。
具体实现:
小结:
设计原则:依赖抽象,不要依赖具体类。
4.2 AbstractFactoryPattern抽象工厂模式
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指出具体类。
解析:
抽象工厂模式与工厂模式的区别在于,工厂模式只是创建一个产品,而抽象工厂模式是创建产品家族,并让制造的产品集合起来使用。
所以抽象工厂模式需要一个大的接口AbstractFactory,而他具体的实现ConcreteFactory12345里面的具体实例化可以调用工厂模式。
实例分析1:
解析:
这里的数据库不定,表单数不定,但是彼此之间都可能存在关系,所以可以调用抽象工厂模式将这一系列的产品想关联起来。
具体实现:C#学习笔记-抽象工厂模式
实例分析2:
现在我们建立一个工厂来生产原料;这个工厂将负责创建原料家族中的每一种原料,为披萨店提供原材料
解析:
我们订购了pizza后,商店自己根据当前订购的pizza获得当前需要在哪家店订购披萨,然后当地的pizza在从当地的原料工厂获得制作pizza 的原料,如此来制作披萨。
具体实现:
这里的原料家族生成各种各样的产品,再通过不同的组合组成,组成我们所需要的披萨,所以这个部分我们需要调用抽象工厂模式。
小结:
抽象工厂模式创建产品家族,工厂模式创建一个产品。
总结:
温故而知新
成长就是不断发现以前的自己是个傻逼
备注:源代码示例My Github