外观 + 桥接模式 + 观察者模式 + 中介者模式

[Musings]
学习是一件持久的事,但是也是一件会遗忘的事,所以得不停的学习

外观模式

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//BluRayPlayer.class
class BluRayPlayer {
public void on() {
System.out.println("蓝光播放器打开");
}

public void off() {
System.out.println("蓝光播放器关闭");
}

public void play(String movie) {
System.out.println("播放电影: " + movie);
}
}

//Lighting.class
class Lighting {
public void dim() {
System.out.println("灯光调暗");
}

public void bright() {
System.out.println("灯光调亮");
}

public void off() {
System.out.println("灯光关闭");
}
}

//Projector.class
class Projector {
public void on() {
System.out.println("投影仪打开");
}

public void off() {
System.out.println("投影仪关闭");
}

public void setInput(String input) {
System.out.println("投影仪输入源设置为: " + input);
}
}

//Screen.class
class Screen {
public void down() {
System.out.println("屏幕降下");
}

public void up() {
System.out.println("屏幕升起");
}
}

//SoundSystem.class
class SoundSystem {
public void on() {
System.out.println("音响系统打开");
}

public void off() {
System.out.println("音响系统关闭");
}

public void setVolume(int volume) {
System.out.println("音响音量设置为: " + volume);
}
}

//HomeTheaterFacade.class
public class HomeTheaterFacade {
private BluRayPlayer bluRayPlayer;
private Lighting lighting;
private Projector projector;
private Screen screen;
private SoundSystem soundSystem;

public HomeTheaterFacade(BluRayPlayer bluRayPlayer, Lighting lighting, Projector projector, Screen screen, SoundSystem soundSystem) {

this.bluRayPlayer = bluRayPlayer;
this.lighting = lighting;
this.projector = projector;
this.screen = screen;
this.soundSystem = soundSystem;
}

public void watchMovie(String movie){
System.out.println("准备观看电影...");
lighting.dim(); // 1. 调暗灯光
screen.down(); // 2. 降下屏幕
projector.on(); // 3. 打开投影仪
projector.setInput("HDMI"); // 4. 设置输入源
soundSystem.on(); // 5. 打开音响
soundSystem.setVolume(20); // 6. 设置音量
bluRayPlayer.on(); // 7. 打开蓝光播放器
bluRayPlayer.play(movie); // 8. 播放电影
System.out.println("电影开始!");
}
}

//Main.class
public class Main {
public static void main(String[] args) {
Projector projector = new Projector();
BluRayPlayer bluRayPlayer = new BluRayPlayer();
Lighting lighting = new Lighting();
Screen screen = new Screen();
SoundSystem soundSystem = new SoundSystem();

HomeTheaterFacade homeTheaterFacade = new HomeTheaterFacade(bluRayPlayer, lighting, projector, screen, soundSystem);
homeTheaterFacade.watchMovie("Iron Man");
}
}


提供一个统一的简化接口,来隐藏子系统的复杂性

桥接模式

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

public interface PaymentMethod {
void pay();
void refund();
void query();
}

public class AliPay implements PaymentMethod {
@Override
public void pay() {
}
@Override
public void refund() {
}
@Override
public void query() {
}
}

public class CardPay implements PaymentMethod{
@Override
public void pay() {
}
@Override
public void refund() {
}
@Override
public void query() {
}
}

public class WeChatPay implements PaymentMethod{
@Override
public void pay() {
}
@Override
public void refund() {
}
@Override
public void query() {
}
}

public class AppPayment extends Payment {
String appname;
public AppPayment(int amount, PaymentMethod paymentMethod, String appname) {
super(amount, paymentMethod);
this.appname = appname;
}
@Override
void pay() {
paymentMethod.pay();
}
@Override
void refund() {
System.out.println("AppPayment");
}
@Override
void query() {
System.out.println("AppPayment");
}
}

public class WebPayment extends Payment {
String url;
public WebPayment(int amount, PaymentMethod paymentMethod, String url) {
super(amount, paymentMethod);
this.url = url;
}
@Override
void pay() {
System.out.println("Webpayment");
}
@Override
void refund() {
System.out.println("Webpayment");
}
@Override
void query() {
System.out.println("Webpayment");
}
}


public class Main {
public static void main(String[] args){
// 测试1: APP场景 + 支付宝
AppPayment appWithAli = new AppPayment(100, new AliPay(), "淘宝APP");
appWithAli.pay();
appWithAli.refund();
System.out.println();

// 测试2: 网页场景 + 微信支付
WebPayment webWithWechat = new WebPayment(200, new WeChatPay(), "https://shop.com");
webWithWechat.pay();
webWithWechat.query();
System.out.println();

// 测试3: APP场景 + 银行卡支付
AppPayment appWithCard = new AppPayment(150, new CardPay(), "银行APP");
appWithCard.pay();
appWithCard.refund();
System.out.println();

// 测试4: 网页场景 + 支付宝
WebPayment webWithAli = new WebPayment(300, new AliPay(), "https://mall.com");
webWithAli.pay();
webWithAli.query();
System.out.println();

// 测试5: 演示多态特性
System.out.println("=== 多态测试 ===");
Payment[] payments = {
new AppPayment(50, new WeChatPay(), "小程序"),
new WebPayment(75, new CardPay(), "https://pay.com"),
new AppPayment(120, new AliPay(), "外卖APP")
};

for (Payment payment : payments) {
payment.pay();
payment.query();
System.out.println("---");
}

// 测试6: 退款流程测试
System.out.println("=== 退款流程测试 ===");
WebPayment refundTest = new WebPayment(500, new AliPay(), "https://refund.com");
refundTest.pay();
refundTest.refund();
}
}


桥接模式和核心就是把多维度的因素抽象出来,减少排列组合,避免类爆炸
实际价值就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 维度1:支付方式(M个)
interface PaymentMethod { ... }
class AliPay implements PaymentMethod { ... }
class WeChatPay implements PaymentMethod { ... }
class CardPay implements PaymentMethod { ... }

// 维度2:支付场景(N个)
abstract class PaymentScene { ... }
class AppPayment extends PaymentScene { ... }
class WebPayment extends PaymentScene { ... }
class PosPayment extends PaymentScene { ... }

// 通过组合获得 M×N 种可能
new AppPayment(new AliPay()) // APP+支付宝
new WebPayment(new WeChatPay()) // 网页+微信
new PosPayment(new CardPay()) // POS+银行卡
// ... 所有组合

到此总结:

创建型模式:
🏭 工厂方法:一个产品,多种实现(子类决定创建什么)
🏭 抽象工厂:一套产品,整体替换(产品族的概念)
🔨 建造者:复杂对象,分步构建(避免构造函数参数过多)
📋 原型:已有对象,复制使用(克隆代替new)
👑 单例:全局唯一,严格控制(一个类只有一个实例)

结构型模式:
🌳 组合:部分-整体,统一对待(树形结构,一致处理父子关系)
🎁 装饰器:相同接口,功能叠加(动态添加职责,像俄罗斯套娃)
🏷️ 享元:共享内在,传递外在(共享不变部分,分离变化部分,像活字印刷)
🌉 桥接:提取抽象维度,排列组合(多维度独立变化,避免类爆炸)
🕶️ 代理:控制访问,功能增强(像经纪人,控制对真实对象的访问)
🔌 适配器:接口转换,兼容协作(像电源转接头,让不兼容的接口协同工作)
🏢 外观:接口封装,统一调用(简化复杂子系统,提供统一入口)

到这就结束了所有创建型和结构型模式了,我们开始研究行为型模式,上点难度:

观察者模式

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public interface Publisher {
void notify(int count, String info);
void subscribe(Observer observer);
void unsubscribe(Observer observer);
}

public interface Observer {
void push(int count, String info);
}

public class Item implements Publisher {
private ArrayList<Observer> observerArrayList;
private String name;
private int count = 100;

public Item(String name, int count) {
this.observerArrayList = new ArrayList<>();
this.count = count;
this.name = name;
}

public void reduceCount(){
this.count--;
System.out.println("reduceCount -- ");
if(count<10){
this.notify(this.count,"薯片快卖完了");
}
}

@Override
public void notify(int count , String name) {
observerArrayList.forEach(observer -> observer.push(count,name));
}

@Override
public void subscribe(Observer observer) {
observerArrayList.add(observer);
}

@Override
public void unsubscribe(Observer observer) {
observerArrayList.remove(observer);
}
}

public class Shop implements Observer {
private String name;

public Shop(String name) {
this.name = name;
}

@Override
public void push(int count, String info) {
System.out.println(name + " received" + info + " info:" + count);
}
}

public class Main {
public static void main(String[] arg) {
Shop shop = new Shop("#1 Shop");
Shop shop1 = new Shop("#2 Shop");
Item crips = new Item("Crips", 12);
crips.subscribe(shop1);
crips.subscribe(shop);
crips.reduceCount();
crips.reduceCount();
crips.reduceCount();
}
}

中介者模式 Pattern

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
interface Publisher {
void notify(String itemName, int count);
}

public class Storage implements Publisher {
Mediator mediator;
private HashMap<String, Integer> storageMap;
private String name;

public Storage(String name, Mediator mediator) {
this.storageMap = new HashMap();
this.name = name;
this.mediator = mediator;
}

@Override
public void notify(String itemName, int count) {
mediator.notify(this, itemName, count);
}

public void add(String itemName, int count) {
storageMap.put(itemName, count);
}

public void reduce(String itemName) {
int currentVal = storageMap.get(itemName);
storageMap.put(itemName, currentVal - 1);
notify(itemName, currentVal - 1);
}
}

public abstract class Observer {
private String role;

public Observer(String role) {
this.role = role;
}

abstract void push(String info);

public String getRole() {
return role;
}
}

public class Shop extends Observer {
public Shop(String role) {
super(role);
}

@Override
void push(String info) {

}
}

public class ShunFenDelivery extends Observer {
@Override
void push(String info) {

}

public ShunFenDelivery(String role) {
super(role);
}
}

public class Procurement extends Observer {
public Procurement(String role) {
super(role);
}

@Override
void push(String info) {

}
}

public class Mediator {
private HashMap<Publisher, ArrayList<Observer>> hashMap;

public Mediator() {
this.hashMap = new HashMap<>();
}

public void notify(Publisher publish, String itemName, int count) {
ArrayList<Observer> observers = hashMap.get(publish);
// 添加逻辑基于count,itemName,也可以结合多个不同的item
if (observers != null && !observers.isEmpty()) {
for (Observer observer : observers) {
switch (observer.getRole()) {
case "Procure":
if (count > 5) {
observer.push("货物充足!");
} else {
observer.push("货物不足,准备补充");
}
break;
case "Shop":
if (count > 5) {
observer.push("货物充足!");
} else {
observer.push("货物不足,准备下架");
}
break;
case "Delivery":
if (count > 5) {
observer.push("货物充足,车辆平均分配!");
} else {
observer.push("货物不足,准备帮忙采购");
}
break;
}
}
}
}

public void subscribe(Publisher publisher, Observer observer) {
hashMap.computeIfAbsent(publisher, k -> new ArrayList<>()).add(observer);
}

public void unsubscribe(Publisher publisher, Observer observer) {
hashMap.computeIfPresent(publisher, (k, v) -> {
v.remove(observer);
return v.isEmpty() ? null : v;
});
}

}

中介者模式的核心逻辑就是Mediator, publisher和observer相对工作量小一点,符合全在mediator