我是靠谱客的博主 微笑书本,这篇文章主要介绍设计模式 - 门面模式/适配器模式/装饰器模式,现在分享给大家,希望可以做个参考。

文章目录

    • 8. 门面/外观模式(Facade)
      • 目的
      • 类图
      • 实现
      • 设计原则
      • 应用场景
      • 优点
    • 9. 适配器(Adapter)
      • 模式定义
      • 类图
      • 实现
        • 场景一:对象适配器模式【组合】
        • 场景二:类的适配器模式【继承】
        • 场景三:对象适配器模式
      • 应用场景
      • 优点
    • 10. 装饰者(Decorator)
      • 目的
      • 模式定义
      • 类图
      • 实现
        • 场景一
        • 场景二
      • 设计原则
      • 应用场景
      • 优点

8. 门面/外观模式(Facade)

目的

提供了一个统一的接口,用来访问子系统中的一群接口,从而让子系统更容易使用。

类图


实现

观看电影需要操作很多电器,使用门面模式实现一键看电影功能。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SubSystem { public void turnOnTV() { System.out.println("turnOnTV()"); } public void setCD(String cd) { System.out.println("setCD( " + cd + " )"); } public void startWatching(){ System.out.println("startWatching()"); } }
复制代码
1
2
3
4
5
6
7
8
9
10
public class Facade { private SubSystem subSystem = new SubSystem(); public void watchMovie() { subSystem.turnOnTV(); subSystem.setCD("a movie"); subSystem.startWatching(); } }
复制代码
1
2
3
4
5
6
7
public class Client { public static void main(String[] args) { Facade facade = new Facade(); facade.watchMovie(); } }

设计原则

最少知识原则:只和你的密友谈话。也就是说客户对象所需要交互的对象应当尽可能少。

应用场景

  • 当需要使用复杂子系统的有限但直接的接口时
  • 当想要将子系统组织成层时

优点

简化客户端的使用

9. 适配器(Adapter)

模式定义

将一个类的接口转换成客户希望的另一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

类图


实现

场景一:对象适配器模式【组合】

220v到5v的变压器

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class AdapyerTest1 { public static void main(String[] args){ new adaptee = new Adaptee(); Target target = new Adapter(adaptee); target.output5v(); } } class Adaptee { public int output200v(){ return 220; } } interface Target{ int output5v(); } class Adapter implements Target{ Adaptee adaptee; public Adapter(Adaptee adaptee){ this.adaptee=adaptee; } @Override public int output5v(){ int i=adaptee.output220v(); //模拟一系列复杂的转换工作 System.out.println(String.format("原始点呀:%d v -> 输出电压:%d v ",i,5))return 5} }
场景二:类的适配器模式【继承】

220v到5v的变压器

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class AdapyerTest1 { public static void main(String[] args){ Adapter adapter = new Adapter(); adapter.output5v(); } } class Adaptee { public int output200v(){ return 220; } } interface Target{ int output5v(); } class Adapter extends Adaptee implements Target{ @Override public int output5v(){ int i= this.output220v(); //模拟一系列复杂的转换工作 System.out.println(String.format("原始点呀:%d v -> 输出电压:%d v ",i,5))return 5} }

类的适配器的缺点:对代码有污染,我们只需要5v的电压,但是也可以输出220v的电压了。

场景三:对象适配器模式

鸭子(Duck)和火鸡(Turkey)拥有不同的叫声,Duck 的叫声调用 quack() 方法,而 Turkey 调用 gobble() 方法。

要求将 Turkey 的 gobble() 方法适配成 Duck 的 quack() 方法,从而让火鸡冒充鸭子!

复制代码
1
2
3
4
public interface Duck { void quack(); }
复制代码
1
2
3
4
public interface Turkey { void gobble(); }
复制代码
1
2
3
4
5
6
7
public class WildTurkey implements Turkey { @Override public void gobble() { System.out.println("gobble!"); } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
public class TurkeyAdapter implements Duck { Turkey turkey; public TurkeyAdapter(Turkey turkey) { this.turkey = turkey; } @Override public void quack() { turkey.gobble(); } }
复制代码
1
2
3
4
5
6
7
8
public class Client { public static void main(String[] args) { Turkey turkey = new WildTurkey(); Duck duck = new TurkeyAdapter(turkey); duck.quack(); } }

应用场景

  • 当希望使用某些现有类,但其借口与你的其他代码不兼容时
  • 当希望重用几个现有的子类,这些子类缺少一些不能添加到超类中的公共功能时

优点

  • 符合单一职责原则
  • 符合开闭原则

10. 装饰者(Decorator)

目的

为对象动态添加功能。

模式定义

在不改变原有对象的基础上,将功能附加到对象上。

类图

装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者或者具体组件。所谓装饰,就是把这个装饰者套在被装饰者之上,从而动态扩展被装饰者的功能。装饰者的方法有一部分是自己的,这属于它的功能,然后调用被装饰者的方法实现,从而也保留了被装饰者的功能。可以看到,具体组件应当是装饰层次的最低层,因为只有具体组件的方法实现不需要依赖于其它对象。


实现

场景一

相机具备拍照功能,添加美颜等其他功能。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class DecoratorTest { public statuc void main(String[] args){ Component component = new ConreteDecorator(new ConcreteComponent() ); component.opeartion(); Component component = new ConreteDecorator2(new ConreteDecorator(new ConcreteComponent() ) ); component.opeartion(); } } interface Component { void operation(); } class ConcreteComponent implements Component{ @Override public void operation(){ system.out.println("拍照."); } } //装饰者抽象类 abstract class Decorator implements Component{ Component component; public Decorator(Component component){ this.component = component; } } //装饰者具体实现:添加美颜效果 class ConreteDecorator extends Decorator{ public ConreteDecorator(Component component){ super(component); } @Override public void operation(){ system.out.println("添加美颜."); component.operation(); } } //装饰者具体实现:添加滤镜效果 class ConreteDecorator2 extends Decorator{ public ConreteDecorator2(Component component){ super(component); } @Override public void operation(){ system.out.println("添加滤镜."); omponent.operation(); } }

最后输出
在这里插入图片描述

场景二

设计不同种类的饮料,饮料可以添加配料,比如可以添加牛奶,并且支持动态添加新配料。每增加一种配料,该饮料的价格就会增加,要求计算一种饮料的价格。

下图表示在 DarkRoast 饮料上新增新添加 Mocha 配料,之后又添加了 Whip 配料。DarkRoast 被 Mocha 包裹,Mocha 又被 Whip 包裹。它们都继承自相同父类,都有 cost() 方法,外层类的 cost() 方法调用了内层类的 cost() 方法。


复制代码
1
2
3
4
public interface Beverage { double cost(); }
复制代码
1
2
3
4
5
6
7
public class DarkRoast implements Beverage { @Override public double cost() { return 1; } }
复制代码
1
2
3
4
5
6
7
public class HouseBlend implements Beverage { @Override public double cost() { return 1; } }
复制代码
1
2
3
4
public abstract class CondimentDecorator implements Beverage { protected Beverage beverage; }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
public class Milk extends CondimentDecorator { public Milk(Beverage beverage) { this.beverage = beverage; } @Override public double cost() { return 1 + beverage.cost(); } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
public class Mocha extends CondimentDecorator { public Mocha(Beverage beverage) { this.beverage = beverage; } @Override public double cost() { return 1 + beverage.cost(); } }
复制代码
1
2
3
4
5
6
7
8
9
10
public class Client { public static void main(String[] args) { Beverage beverage = new HouseBlend(); beverage = new Mocha(beverage); beverage = new Milk(beverage); System.out.println(beverage.cost()); } }
复制代码
1
2
3.0

设计原则

类应该对扩展开放,对修改关闭:也就是添加新功能时不需要修改代码。饮料可以动态添加新的配料,而不需要去修改饮料的代码。

不可能把所有的类设计成都满足这一原则,应当把该原则应用于最有可能发生改变的地方。

应用场景

  • 扩展一个类的功能或者给一个类添加附加职责

优点

  • 不改变原有对象的情况下给一个对象扩展功能
  • 使用不同的组合可以实现不同的效果
  • 符合开闭原则

最后

以上就是微笑书本最近收集整理的关于设计模式 - 门面模式/适配器模式/装饰器模式的全部内容,更多相关设计模式内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部