0
点赞
收藏
分享

微信扫一扫

重温HeadFirst设计模式

一世独秀 2022-02-21 阅读 99

1.策略模式

定义: 策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

实例:鸭子的飞行行为委托给行为类实现,鸭子在构造时需要传入flyable接口的实现类实例,还可以通过set方法改变,自己的fly方法委托给行为类实现,“有一个”可能比“是一个”更好,更灵活;多用组合,少用继承。

2.观察者模式
定义:定义了对象之间的一对多依赖,这样一来,当一个对象改变时,它的所有依赖者都会收到通知并更新。

角色:Observer观察者,Observerable被观察对象

实例:weatherData类有modified()方法,当天气数据变化时该方法中的代码会被调用。weatherData类中维护一个公告板接口类的集合,同时对外提供订阅和取消订阅两个接口。在modified方法中遍历调用公告板接口类的update(),将所有订阅的公告板数据刷新。

好处:当新增公告板时,不需要修改weatherData类,只需要让公告板使用registerObserver()订阅weatherData即可。

3.装饰者模式

定义:装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

实例:购买咖啡时,可以加入各种调料,如:蒸奶、豆浆、摩卡等,加入调料后咖啡的cost()方法返回的价格就要加上调料的价格。这些调料有无数种组合,如果把每种组合的咖啡都写单独的类,将会类爆炸。用装饰者模式可以解决,把咖啡、蒸奶、豆浆、摩卡都当成饮品类(Beverage),都有cost()方法,该类有带参构造方法:new Beverage(new Beverage());构造方法中传入的对象是被包装的对象,包装类在计算cost()时将自己的价格加上被包装类的价格。

角色:装饰者和被装饰者;该两个类实现了同样的类型,在用户看来,区分不了该类是不是被包装过。装饰者的方法是在委托给被装饰者后加入了自己的改造。

4.工厂模式

a.简单工厂,将创建对象放在工厂类中,如果工厂类中的方法是静态方法,那么就叫静态工厂。静态工厂使用方便,缺陷是不能通过继承改变创建方法的行为。
简单工厂的好处:当有多个客户使用简单工厂时,如果需要修改创建的对象,在简单工厂这一处修改即可。

b.工厂方法模式

定义:工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类。

实例:PizzaStore的orderPizza()对外创建披萨需要有多个步骤,首先createPizza()得到pizza对象,然后pizza.prepare()、pizza.bake()、pizza.cut()、pizza.box(),然后返回该pizza给客户。不同工厂风味的披萨只是createPizza()得到的pizza对象不一样,而后续的prepare等方法需要都保持一样。故定义一个抽象的工厂类:PizzaStore,包含抽象方法createPizza(String type), 在其orderPizza()方法中的第一步就调用了该抽象方法,然后再调用pizza.prepare()、pizza.bake()、pizza.cut()、pizza.box(),将pizza对象返回。 新建工厂如纽约工厂,NYPizzaStore需要实现createPizza(String type)这个抽象方法,其orderPizza()就会使用该字类的createPizza()抽象方法的具体实现。而其他流程如prepare()等等都不需要也无法改动。工厂方法模式就通过在工厂方法中调用抽象方法来达到将类的实例化推迟到子类的。
这里也是依赖倒置原则的很好体现: PizzaStore是高层类,不应该依赖于具体的NYPizza或者是ChicagoPizza,而是只依赖于他们的高层Pizza。

c.抽象工厂模式
定义: 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

实例: 在Pizza类的prepare()方法中准备pizza的原料,不同风味的原料不同;如NYPizza需要NY面团、NY酱料和NY奶油,而ChicagoPizza需要Chicago面团、Chicago酱料和Chicago奶油。现在的做法是:在Pizza抽象类构造方法中有IngredientFactory抽象类做为参数,prepare方法中就使用该抽象类的系列抽象方法dough = factory.createDough(); sauce = factory.createSauce();cheese = factory.createCheese();而不同的pizza子类,如NYPizza传入的原料工厂就是原料工厂子类NYIngredientFactory。
抽象工厂和工厂方法的区别: 抽象工厂使用对象的组合实现,而工厂方法使用类实现。

比较点抽象工厂工厂方法
实现方式客户端在上层抽象中自身组合了抽象工厂的实例,使用对象调用抽象工厂的生产方法抽象类中的其他方法先使用了该由子类实现的抽象方法,这样子类实现该抽象方法时,就完成了将具体实现推迟到子类实现的目标
作用创造一族相关的产品将产品的具体实例化推迟到子类中完成

设计原则:
1.找出程序中会变化的方面,然后将其和固定不变的方面相分离:这是设计模式的总目标
2.针对接口编程,不针对实现编程
3.多用组合,少用继承;如策略模式
4.类应该对扩展开放,对修改关闭(好的代码应该是在不修改代码的前提下可扩展的)
5.要依赖抽象,不要依赖具体类

举报

相关推荐

0 条评论