本文最后更新于:2024年9月5日 早上
大话设计模式
此文为我学习大话设计模式时的笔记,代码样例也是书里的。这本书对学习理解设计模式还是挺有帮助,推荐大家可以看看~
第 0 章 面向对象基础
1. 类与实例
万物皆对象,对象是一个自包含的实体,用一组可识别的特性和行为来标识。
类就是具有相同的属性和功能的对象的抽象的集合。
实例,就是一个真实的对象。而实例化就是创建对象的过程,使用new关键字来创建。
2. 构造方法
构造方法,又叫构造函数,其实就是对类进行初始化。构造方法与类同名,无返回值,也不需要void,在 new 的使用调用。
所有类都有构造方法,如果你不编码则系统默认生成空的构造方法,若你有定义的构造方法,那么默认的构造方法就会失效了。
3. 方法重载
方法重载提供了创建同名的多个方法的能力,但这些方法需使用不同的参数类型。
方法重载时,需方法名相同,但参数类型或个数必须要有所不同。
方法重载可在不改变原方法的基础上,新增功能。
4. 属性与修饰符
属性是一个方法或一对方法,即属性适合于以字段的方式使用方法调用的场合。
字段是存储类要满足其设计所需要的数据,字段是与类相关的变量。
5. 封装
每个对象都包含它能进行操作所需要的所有信息,这个特性称为封装,因此对象不必依赖其他对象来完成自己的操作。
封装有多个好处:
- 良好的封装能够减少耦合。
- 类内部的实现可以自由地修改。
- 类具有清晰的对外接口。
6. 继承
对象的继承代表了一种‘is-a’的关系,如果两个对象A和B,可以描述为‘B是A’,则表明B可以继承A。
继承者还可以理解为是对被继承者的特殊化,因为它除了具备被继承者的特性外,还具备自己独有的个性。
继承定义了类如何相互关联,共享特性。
继承的工作方式是:定义父类和子类,或叫作基类和派生类,其中子类继承父类的所有特性。
子类不但继承了父类的所有特性,还可以定义新的特性。
如果子类继承与父类:
- 子类拥有父类非 private 的属性和功能
- 子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能
- 子类还可以以自己的方式实现父类的功能(方法重写)
第 1 章 简单工厂模式
题目:请用C++、Java、C#或Python等任意一种面向对象语言实现一个计算器控制台程序,要去输入两个数和运算符号,得到结果。
![](https://cdn.gumengyo.top//image-20230424201833506.png)
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
| import java.util.*;
public class SimpleFactory { public static void main(String[] args) { Scanner sc = new Scanner(System.in);
System.out.println("请输入数字A: "); double numberA = Double.parseDouble(sc.nextLine()); System.out.println("请选择运算符号(+、-、*、/): "); String strOperate = sc.nextLine(); System.out.println("请输入数字B: "); double numberB = Double.parseDouble(sc.nextLine());
Operation operate = OperationFactory.createOperate(strOperate); double result = operate.getResult(numberA, numberB);
System.out.println("结果是: " + result); } }
class OperationFactory { public static Operation createOperate(String operate) { Operation oper = null; switch (operate) { case "+": oper = new Add(); break; case "-": oper = new Sub(); break; case "*": oper = new Mul(); break; case "/": oper = new Div(); break; } return oper; } }
abstract class Operation { public double getResult(double numberA, double numberB) { return 0d; } }
class Add extends Operation { @Override public double getResult(double numberA, double numberB) { return numberA + numberB; } }
class Sub extends Operation { @Override public double getResult(double numberA, double numberB) { return numberA + numberB; } }
class Mul extends Operation { @Override public double getResult(double numberA, double numberB) { return numberA * numberB; } }
class Div extends Operation { @Override public double getResult(double numberA, double numberB) { if (numberB == 0) { System.out.println("除数不能为0"); throw new ArithmeticException(); } return numberA / numberB; } }
|
第 2 章 策略模式
策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
![](https://cdn.gumengyo.top//image-20230428085826966.png)
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
| import java.util.*;
public class StrategyPattern { public static void main(String[] args) {
double price = 0d; int num = 0; double totalPrices = 0d; double total = 0d;
Scanner sc = new Scanner(System.in); do { System.out.println("请输入商品销售模式 1.原价 2.八折 3.满300返100"); int discount = Integer.parseInt(sc.nextLine()); System.out.println("请输入商品单价:"); price = Double.parseDouble(sc.nextLine()); System.out.println("请输入商品数量:"); num = Integer.parseInt(sc.nextLine()); System.out.println();
if (price > 0 && num > 0){ CashContext cc = new CashContext(discount); totalPrices = cc.getResult(price, num); total = total + totalPrices;
System.out.println(); System.out.println("单价:" + price +"元,数量:" + num + " 合计:" + totalPrices + "元"); System.out.println(); System.out.println("总计:" + total + "元"); System.out.println(); }
}while (price > 0 && num > 0);
} }
abstract class CashSuper{
public abstract double acceptCash(double price,int num); }
class CashNormal extends CashSuper{
@Override public double acceptCash(double price, int num) { return price * num; } }
class CashRebate extends CashSuper{
private double moneyRebate = 1d;
public CashRebate(double moneyRebate){ this.moneyRebate = moneyRebate; }
@Override public double acceptCash(double price, int num) { return price * num * this.moneyRebate; } }
class CashReturn extends CashSuper{
private double moneyCondition = 0d; private double moneyReturn = 0d;
public CashReturn(double moneyCondition, double moneyReturn) { this.moneyCondition = moneyCondition; this.moneyReturn = moneyReturn; }
@Override public double acceptCash(double price, int num) { double result = price * num; if (moneyCondition > 0 && price >= moneyCondition){ result = result - Math.floor(result / moneyCondition) * moneyReturn; } return result; } }
class CashContext{ private CashSuper cs;
public CashContext(int cashType){ switch (cashType){ case 1: this.cs = new CashNormal(); break; case 2: this.cs = new CashRebate(0.8d); break; case 3: this.cs = new CashReturn(300d,100d); break; } }
public double getResult(double price, int num) { return this.cs.acceptCash(price, num); } }
|
第 3 章 单一职责原则
单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因。
- 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。
- 软件设计真正要做的许多内容,就是发现职责并把那么些职责相互分离。
- 如果你能够想到多于一个的动机去改变一个类,那么这个类就是具有多于一个的职责。
第 4 章 开放-封闭原则
开放-封闭原则,是说软件实体(类、模块、函数等)应该可以扩展,但是不可修改。
- 对于扩展是开放的(Open for extension)
- 对于修改是封闭的(Closed for modification)
![](https://cdn.gumengyo.top//image-20230428090233389.png)
开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。
第 5 章 依赖倒转原则
依赖倒转原则:
- 高层模块不应该依赖低层模块。两个都应该依赖抽象。
- 抽象不应该依赖细节。细节应该依赖抽象。
里氏代换原则(LSP):子类型必须能够替换掉它们的父类型。
由于子类型的可替换性才使得使用父类类型的模块在无须修改的情况下就可以扩展。
![](https://cdn.gumengyo.top//image-20230428092805695.png)
第 6 章 装饰模式
装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
![](https://cdn.gumengyo.top//image-20230428141827346.png)
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 class DecoratorPattern {
public static void main(String[] args) { ConcreteComponent c = new ConcreteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c); d2.SetComponent(d1); d2.Operation(); } }
abstract class Component{ public abstract void Operation(); }
class ConcreteComponent extends Component{ public void Operation(){ System.out.println("具体对象的实际操作"); } }
abstract class Decorator extends Component{ protected Component component;
public void SetComponent(Component component){ this.component = component; }
@Override public void Operation() { if (component != null){ component.Operation();; } } }
class ConcreteDecoratorA extends Decorator{
protected String addedState;
public void Operation(){ super.Operation();
this.addedState = "具有装饰对象A的独有操作"; System.out.println(this.addedState);
} }
class ConcreteDecoratorB extends Decorator{
public void Operation(){ super.Operation(); this.AddedBehavior(); }
private void AddedBehavior(){ System.out.println("具有装饰对象B的独有操作"); } }
|
商场促销——简单工厂+策略+装饰模式实现
![](https://cdn.gumengyo.top//image-20230428141722534.png)
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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
| package cn.jishuin;
import java.util.*;
public class Promotion { public static void main(String[] args) { System.out.println("**********************************************"); System.out.println("《大话设计模式》代码样例"); System.out.println();
int discount = 0; double price = 0d; int num = 0; double totalPrices = 0d; double total = 0d;
Scanner sc = new Scanner(System.in);
do { System.out.println("商品折扣模式如下:"); System.out.println("1.正常收费"); System.out.println("2.打八折"); System.out.println("3.打七折"); System.out.println("4.满300送100"); System.out.println("5.先打8折,再满300送100"); System.out.println("6.先满200送50,再打7折"); System.out.println("请输入商品折扣模式:"); discount = Integer.parseInt(sc.nextLine()); System.out.println("请输入商品单价:"); price = Double.parseDouble(sc.nextLine()); System.out.println("请输入商品数量:"); num = Integer.parseInt(sc.nextLine()); System.out.println();
if (price>0 && num>0){
CashContext cc = new CashContext(discount);
totalPrices = cc.getResult(price,num);
total = total + totalPrices;
System.out.println(); System.out.println("单价:"+ price + "元 数量:"+ num +" 合计:"+ totalPrices +"元"); System.out.println(); System.out.println("总计:"+ total+"元"); System.out.println(); } } while(price>0 && num>0);
System.out.println(); System.out.println("**********************************************"); } }
interface ISale { double acceptCash(double price,int num); }
class CashSuper implements ISale {
protected ISale component;
public void decorate(ISale component) { this.component=component; }
public double acceptCash(double price,int num){
double result = 0d; if (this.component != null){ result = this.component.acceptCash(price,num); } return result;
}
}
class CashNormal implements ISale { public double acceptCash(double price,int num){ return price * num; } }
class CashRebate extends CashSuper {
private double moneyRebate = 1d; public CashRebate(double moneyRebate){ this.moneyRebate = moneyRebate; }
public double acceptCash(double price,int num){ double result = price * num * this.moneyRebate; return super.acceptCash(result,1); }
}
class CashReturn extends CashSuper {
private double moneyCondition = 0d; private double moneyReturn = 0d;
public CashReturn(double moneyCondition,double moneyReturn){ this.moneyCondition = moneyCondition; this.moneyReturn = moneyReturn; }
public double acceptCash(double price,int num){ double result = price * num; if (moneyCondition>0 && result >= moneyCondition) result = result - Math.floor(result / moneyCondition) * moneyReturn; return super.acceptCash(result,1); }
}
class CashContext { private ISale cs;
public CashContext(int cashType) { switch (cashType) { case 1: this.cs = new CashNormal(); break; case 2: CashRebate cr1 = new CashRebate(0.7d); cr1.decorate(new CashNormal()); this.cs = cr1; break; case 3: CashRebate cr2 = new CashRebate(0.8d); cr2.decorate(new CashNormal()); this.cs = cr2; break; case 4: CashReturn cr3 = new CashReturn(300d, 100d); cr3.decorate(new CashNormal()); this.cs = cr3; break; case 5: CashNormal cn = new CashNormal(); CashReturn cr4 = new CashReturn(300d, 100d); CashRebate cr5 = new CashRebate(0.8d); cr4.decorate(cn); cr5.decorate(cr4); this.cs = cr5; break; case 6: CashNormal cn2 = new CashNormal(); CashRebate cr6 = new CashRebate(0.7d); CashReturn cr7 = new CashReturn(200d, 50d); cr6.decorate(cn2); cr7.decorate(cr6); this.cs = cr7; break; } } public double getResult(double price,int num){ return this.cs.acceptCash(price,num); } }
|
第 7 章 代理模式
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。
![](https://cdn.gumengyo.top//image-20230503180154059.png)
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
|
public class ProxyPattern { public static void main(String[] args) { SchoolGirl girlLjj = new SchoolGirl(); girlLjj.setName("李娇娇");
Proxy boyDl = new Proxy(girlLjj); boyDl.giveDolls(); boyDl.giveFlowers(); boyDl.giveChocolate(); } }
interface IGiveGift{ void giveDolls(); void giveFlowers(); void giveChocolate(); }
class SchoolGirl{ private String name;
public String getName(){ return this.name; }
public void setName(String name){ this.name = name; } }
class Pursuit implements IGiveGift{
private SchoolGirl mm; public Pursuit(SchoolGirl mm){ this.mm = mm; }
@Override public void giveDolls() { System.out.println(this.mm.getName() + ",你好!送你洋娃娃。"); }
@Override public void giveFlowers() { System.out.println(this.mm.getName() + ",你好!送你鲜花。"); }
@Override public void giveChocolate() { System.out.println(this.mm.getName() + ",你好!送你巧克力。"); } }
class Proxy implements IGiveGift{
private Pursuit gg;
public Proxy(SchoolGirl mm){ this.gg = new Pursuit(mm); }
@Override public void giveDolls() { this.gg.giveDolls(); }
@Override public void giveFlowers() { this.gg.giveFlowers(); }
@Override public void giveChocolate() { this.gg.giveChocolate(); } }
|
代理模式应用:
- 远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
- 虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。
- 安全代理,用来控制真实对象访问的权限。
- 智能指引,是指当调用真实的对象时,代理处理另外一些事。
第 8 章 工厂方法模式
工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式是简单工厂模式的进一步抽象和推广。
优点:
- 对于复杂的参数构造对象,可以很好地对外层屏蔽代码的复杂性
- 很好的解耦能力
![](https://cdn.gumengyo.top/Snipaste_2023-05-04_09-20-36.png)
![](https://cdn.gumengyo.top/Snipaste_2023-05-04_11-22-06.png)
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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| package cn.jishuqin.chapter08;
import java.util.*;
public class FactoryMethod { public static void main(String[] args) { Scanner sc = new Scanner(System.in);
System.out.println("请输入数字A: "); double numberA = Double.parseDouble(sc.nextLine()); System.out.println("请选择运算符号(+、-、*、/、pow、log): "); String strOperate = sc.nextLine(); System.out.println("请输入数字B: "); double numberB = Double.parseDouble(sc.nextLine());
Operation operate = OperationFactory.createOperate(strOperate); double result = operate.getResult(numberA, numberB);
System.out.println("结果是: " + result); } }
abstract class Operation { public abstract double getResult(double numberA, double numberB) ; }
class Add extends Operation { @Override public double getResult(double numberA, double numberB) { return numberA + numberB; } }
class Sub extends Operation { @Override public double getResult(double numberA, double numberB) { return numberA + numberB; } }
class Mul extends Operation { @Override public double getResult(double numberA, double numberB) { return numberA * numberB; } }
class Div extends Operation { @Override public double getResult(double numberA, double numberB) { if (numberB == 0) { System.out.println("除数不能为0"); throw new ArithmeticException(); } return numberA / numberB; } }
class Pow extends Operation{
@Override public double getResult(double numberA, double numberB) { return Math.pow(numberA,numberB); } }
class Log extends Operation{
@Override public double getResult(double numberA, double numberB) { return Math.log(numberB) / Math.log(numberA); } }
interface IFactory{ Operation createOperation(String operType); }
class FactoryBasic implements IFactory{
@Override public Operation createOperation(String operType) { Operation oper = null; switch (operType){ case "+": oper = new Add(); break; case "-": oper = new Sub(); break; case "*": oper = new Mul(); break; case "/": oper = new Div(); break; } return oper; } }
class FactoryAdvanced implements IFactory{
@Override public Operation createOperation(String operType) { Operation oper = null; switch (operType){ case "pow": oper = new Pow(); break; case "log": oper = new Log(); break;
} return oper; } }
class OperationFactory{ public static Operation createOperate(String operate){ Operation oper = null; IFactory factory = null; switch (operate){ case "+": case "-": case "*": case "/": factory = new FactoryBasic(); break; case "pow": case "log": factory = new FactoryAdvanced(); } oper = factory.createOperation(operate); return oper; } }
|
第 9 章 原型模式
原型模式(Prototype),用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
浅复制与深复制:
- 浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
- 深复制:深复制把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
![](https://cdn.gumengyo.top/Snipaste_2023-05-04_11-21-15.png)
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
| package cn.jishuqin.chapter09;
public class PrototypePattern{ public static void main(String[] args) { Resume resume1 = new Resume("大鸟"); resume1.setPersonalInfo("男","29"); resume1.setWorkExperience("1998-2000","xx公司");
Resume resume2 = resume1.clone(); resume2.setWorkExperience("2000-2003","YY集团");
Resume resume3 = resume1.clone(); resume3.setPersonalInfo("男","24");
resume1.display(); resume2.display(); resume3.display(); } }
class WorkExperience implements Cloneable{ private String timeArea;
public String getTimeArea() { return timeArea; }
public void setTimeArea(String timeArea) { this.timeArea = timeArea; }
private String company;
public String getCompany() { return company; }
public void setCompany(String company) { this.company = company; }
public WorkExperience clone(){ WorkExperience object = null; try{ object = (WorkExperience) super.clone(); }catch (CloneNotSupportedException exception){ System.out.println("Clone异常。"); } return object; } }
class Resume implements Cloneable{ private String name; private String sex; private String age; private WorkExperience work; public Resume(String name) { this.name = name; this.work = new WorkExperience(); }
public void setPersonalInfo(String sex,String age){ this.sex = sex; this.age = age; }
public void setWorkExperience(String timeArea,String company){ this.work.setTimeArea(timeArea); this.work.setCompany(company); }
public void display(){ System.out.println(this.name + " " + this.sex + " " + this.age); System.out.println("工作经历 " + this.work.getTimeArea() + " " + this.work.getCompany()); }
@Override protected Resume clone() { Resume object = null; try { object = (Resume) super.clone(); object.work = this.work.clone(); }catch (CloneNotSupportedException exception){ System.out.println("Clone 异常。"); } return object; } }
|
第 10 章 模板方法模式
模板方法(Template Method)模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
![](https://cdn.gumengyo.top//image-20230504142740007.png)
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
| package cn.jishuqin.chapter10;
public class TemplateMethod { public static void main(String[] args) { AbstractClass abstractClass = new ConcreteClassA(); abstractClass.templateMethod();
abstractClass = new ConcreteClassB(); abstractClass.templateMethod(); } }
abstract class AbstractClass{ public void templateMethod(){
System.out.println("共享的代码~");
this.primitiveOperation1(); this.primitiveOperation2();
}
public abstract void primitiveOperation1(); public abstract void primitiveOperation2(); }
class ConcreteClassA extends AbstractClass{
@Override public void primitiveOperation1() { System.out.println("具体类A方法1实现"); }
@Override public void primitiveOperation2() { System.out.println("具体类A方法2实现"); } }
class ConcreteClassB extends AbstractClass{
@Override public void primitiveOperation1() { System.out.println("具体类B方法1实现"); }
@Override public void primitiveOperation2() { System.out.println("具体类B方法2实现"); } }
|
模板方法模式的特点
- 模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。
- 模板方法模式就是提供了一个很好的代码复用平台。
第 11 章 迪米特法则
迪米特法则(LoD),也叫最少知识原则。
迪米特法则(LoD):如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
第 12 章 外观模式
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
![](https://cdn.gumengyo.top//image-20230505171033965.png)
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
| package cn.jishuqin.chapter11;
public class FacadePattern { public static void main(String[] args) { Facade facade = new Facade();
facade.methodA(); facade.methodB(); } }
class SubSystemOne{ public void methodOne(){ System.out.println("子系统方法一"); } }
class SubSystemTwo{ public void methodTwo(){ System.out.println("子系统方法二"); } }
class SubSystemThree{ public void methodThree(){ System.out.println("子系统方法三"); } }
class SubSystemFour{ public void methodFour(){ System.out.println("子系统方法四"); } }
class Facade{ SubSystemOne one; SubSystemTwo two; SubSystemThree three; SubSystemFour four;
public Facade(){ one = new SubSystemOne(); two = new SubSystemTwo(); three = new SubSystemThree(); four = new SubSystemFour(); }
public void methodA(){ one.methodOne(); two.methodTwo(); three.methodThree(); four.methodFour(); }
public void methodB(){ two.methodTwo(); three.methodThree(); } }
|
第 13 章 建造者模式
建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
![](https://cdn.gumengyo.top//image-20230505194106302.png)
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
| package cn.jishuqin.chapter13;
import java.util.*;
public class BuilderPattern { public static void main(String[] args) { Director director = new Director(); Builder b1 = new ConcreteBuilder1(); Builder b2 = new ConcreteBuilder2();
director.construct(b1); Product p1 = b1.getResult(); p1.show();
director.construct(b2); Product p2 = b2.getResult(); p2.show();
} }
class Product { ArrayList<String> parts = new ArrayList<String>();
public void add(String part){ parts.add(part); }
public void show(){ for (String part : parts) { System.out.println(part); } } }
abstract class Builder { public abstract void buildPartA(); public abstract void buildPartB(); public abstract Product getResult(); }
class ConcreteBuilder1 extends Builder {
private Product product = new Product();
@Override public void buildPartA() { product.add("部件A"); }
@Override public void buildPartB() { product.add("部件B"); }
@Override public Product getResult() { return product; } }
class ConcreteBuilder2 extends Builder {
private Product product = new Product();
@Override public void buildPartA() { product.add("部件X"); }
@Override public void buildPartB() { product.add("部件Y"); }
@Override public Product getResult() { return product; } }
class Director{ public void construct(Builder builder) { builder.buildPartA(); builder.buildPartB(); } }
|
建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。
第 14 章 观察者模式
观察者模式又叫作发布-订阅(Publish/Subscri)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
![](https://cdn.gumengyo.top//image-20230506133700094.png)
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
| package cn.jishuqin.chapter14;
import java.util.*;
public class ObserverPattern { public static void main(String[] args) { Subject subject = new ConcreteSubject(); subject.attach(new ConcreteObserver("NameX",subject)); subject.attach(new ConcreteObserver("NameY",subject)); subject.attach(new ConcreteObserver("NameZ", subject)); subject.setSubjectState("ABC");
subject.notifyObserver(); } }
abstract class Subject { private ArrayList<Observer> list = new ArrayList<Observer>();
public void attach(Observer observer){ list.add(observer); }
public void detach(Observer observer){ list.remove(observer); }
public void notifyObserver(){ for (Observer item : list) { item.update(); } }
protected String subjectState; public String getSubjectState() { return this.subjectState; } public void setSubjectState(String value) { this.subjectState = value; } }
abstract class Observer { public abstract void update(); }
class ConcreteSubject extends Subject{ }
class ConcreteObserver extends Observer{ private String name; private Subject sub; public ConcreteObserver(String name,Subject sub){ this.name = name; this.sub = sub; }
@Override public void update() { System.out.println("观察者"+this.name+"的新状态是"+this.sub.getSubjectState()); } }
|
特点:
- 当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
- 抽象模型有两个方面,其中一方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。
- 观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
第 15 章 抽象工厂模式
抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
| package cn.jishuqin.chapter15;
public class AbstractFactory { public static void main(String[] args) { User user = new User(); Department department = new Department();
IFactory factory = new SqlserverFactory();
IUser iu = factory.createUser(); iu.insert(user); iu.getUser(1);
IDepartment idept = factory.createDepartment(); idept.insert(department); idept.getDepartment(2); } }
class User{
private int _id; public int getId() { return this._id; } public void setId(int value) { this._id = value; }
private String _name; public String getName(){ return this._name; } public void setName(String value){ this._name = value; } }
class Department{
private int _id;
public int get_id() { return this._id; } public void set_id(int value){ this._id = value; }
private String _name; public String getName() { return this._name; } public void setName(String value){ this._name = value; } }
interface IUser{ void insert(User user); User getUser(int id); }
interface IDepartment{ void insert(Department department); Department getDepartment(int id); }
class SqlserverUser implements IUser{
public void insert(User user){ System.out.println("在SQL Server中给User表增加一条记录"); }
@Override public User getUser(int id) { System.out.println("在SQL Server中根据用户ID得到User表一条记录"); return null; } }
class AccessUser implements IUser{
@Override public void insert(User user) { System.out.println("在Access中给User表增加一条记录"); }
@Override public User getUser(int id) { System.out.println("在Access中根据用户ID得到User表一条记录"); return null; } }
class SqlserverDepartment implements IDepartment{
public void insert(Department department){ System.out.println("在SQLServer中给Department表增加一条记录"); }
@Override public Department getDepartment(int id) { System.out.println("在SQL Server中根据部门ID得到Department表一条记录"); return null; } }
class AccessDepartment implements IDepartment{
public void insert(Department department){ System.out.println("在Access中给Department表增加一条记录"); }
@Override public Department getDepartment(int id) { System.out.println("在Access中根据部门ID得到Department表一条记录"); return null; } }
interface IFactory{ IUser createUser(); IDepartment createDepartment(); }
class SqlserverFactory implements IFactory{
@Override public IUser createUser() { return new SqlserverUser(); }
@Override public IDepartment createDepartment() { return new SqlserverDepartment(); } }
class AccessFactory implements IFactory{
@Override public IUser createUser() { return new AccessUser(); }
@Override public IDepartment createDepartment() { return new AccessDepartment(); } }
|
特点:
- 易于交换产品系列,由于具体工厂类,在一应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
- 它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
第 16 章 状态模式
状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
![](https://cdn.gumengyo.top/Snipaste_2023-05-11_08-37-15.png)
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 134 135 136 137 138 139 140 141
| package cn.jishuqin.chapter16;
public class StatePattern { public static void main(String[] args) { Work emergencyProjects = new Work(); emergencyProjects.setHour(9); emergencyProjects.writeProgram(); emergencyProjects.setHour(10); emergencyProjects.writeProgram(); emergencyProjects.setHour(12); emergencyProjects.writeProgram(); emergencyProjects.setHour(13); emergencyProjects.writeProgram(); emergencyProjects.setHour(14); emergencyProjects.writeProgram(); emergencyProjects.setHour(17);
emergencyProjects.setWorkFinished(false);
emergencyProjects.writeProgram(); emergencyProjects.setHour(19); emergencyProjects.writeProgram(); emergencyProjects.setHour(22); emergencyProjects.writeProgram();
} }
class Work{
private State current;
public Work(){ current = new ForenoonState(); } public void setState(State value){ this.current =value; }
public void writeProgram(){ this.current.writeProgram(this); }
private int hour; public int getHour() { return this.hour; } public void setHour(int value) { this.hour = value; } private boolean workFinished = false; public boolean getWorkFinished() { return this.workFinished; }
public void setWorkFinished(boolean value){ this.workFinished = value; } }
abstract class State { public abstract void writeProgram(Work w); }
class ForenoonState extends State{ public void writeProgram (Work w){ if (w.getHour() < 12){ System.out.println("当前时间:" + w.getHour() + "点 上午工作,精神百倍"); }else { w.setState(new NoonState()); w.writeProgram(); } } }
class NoonState extends State{ public void writeProgram (Work w){ if (w.getHour() < 13){ System.out.println("当前时间:" + w.getHour() + "点 饿了,午饭:犯困,午休"); }else { w.setState(new AfternoonState()); w.writeProgram(); } } }
class AfternoonState extends State{ public void writeProgram (Work w){ if (w.getHour() < 17){ System.out.println("当前时间:" + w.getHour() + "点 下午状态还不错,继续努力"); }else { w.setState(new EveningState()); w.writeProgram(); } } }
class EveningState extends State{ public void writeProgram (Work w){ if (w.getWorkFinished()){ w.setState(new RestState()); w.writeProgram(); }else { if (w.getHour() < 21){ System.out.println("当前时间:" + w.getHour() + "点 加班哦,疲累之极"); }else { w.setState(new SleepingState()); w.writeProgram(); } } } }
class SleepingState extends State{
@Override public void writeProgram(Work w) { System.out.println("当前时间:" + w.getHour() + "点 不行了,睡着了。"); } }
class RestState extends State{
@Override public void writeProgram(Work w) { System.out.println("当前时间:" + w.getHour() + "点 下班回家了。"); } }
|
状态模式的好处与用处:
- 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
- 消除庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
- 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
第 17 章 适配器模式
适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
![](https://cdn.gumengyo.top/Snipaste_2023-05-11_09-32-09.png)
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
| package cn.jishuqin.chapter17;
public class AdapterPattern { public static void main(String[] args) { Player forwards = new Forwards("巴蒂尔"); forwards.attack();
Player guards = new Guards("麦克格雷迪"); guards.attack();
Player center = new Translator("姚明");
center.attack(); center.defense(); } }
abstract class Player{ protected String name; public Player(String name){ this.name = name; }
public abstract void attack(); public abstract void defense(); }
class Forwards extends Player{ public Forwards(String name){ super(name); } public void attack() { System.out.println("前锋 " + this.name + " 进攻"); } public void defense(){ System.out.println("前锋 " + this.name + " 防守"); } }
class Center extends Player{ public Center(String name){ super(name); } public void attack() { System.out.println("中锋 " + this.name + " 进攻"); } public void defense(){ System.out.println("中锋 " + this.name + " 防守"); } }
class Guards extends Player{ public Guards(String name){ super(name); } public void attack() { System.out.println("后卫 " + this.name + " 进攻"); } public void defense(){ System.out.println("后卫 " + this.name + " 防守"); } }
class ForeignCenter{ private String name; public String getName(){ return this.name; } public void setName(String value) { this.name = value; } public void 进攻(){ System.out.println("外籍中锋 " +this.name + " 进攻"); } public void 防守(){ System.out.println("外籍中锋 " +this.name + " 防守"); } }
class Translator extends Player{
private ForeignCenter foreignCenter = new ForeignCenter();
public Translator(String name){ super(name); foreignCenter.setName(name); }
@Override public void attack() { foreignCenter.进攻(); }
@Override public void defense() { foreignCenter.防守(); } }
|
第 18 章 备忘录模式
备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
![](https://cdn.gumengyo.top/Snipaste_2023-05-11_10-19-19.png)
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
| package cn.jishuqin.chapter18;
public class MementoPattern { public static void main(String[] args) { Originator o = new Originator(); o.setState("On"); o.show();
Caretaker c = new Caretaker(); c.setMemento(o.createMemento());
o.setState("off"); o.show();
o.recoveryMemento(c.getMemento()); o.show(); } }
class Originator{
private String state; public String getState(){ return this.state; } public void setState(String value){ this.state = value; } public void show(){ System.out.println("State:" + this.state); } public Memento createMemento(){ return new Memento(this.state); } public void recoveryMemento(Memento memento){ this.setState(memento.getState()); } }
class Memento{ private String state;
public Memento(String state){ this.state = state; }
public String getState(){ return this.state; } public void setState(String value){ this.state = value; } }
class Caretaker{ private Memento memento; public Memento getMemento(){ return this.memento; } public void setMemento(Memento value){ this.memento = value; }
}
|
第 19 章 组合模式
组合模式(Composite),将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
![](https://cdn.gumengyo.top//image-20230515181230670.png)
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
| package cn.jishuqin.chapter19;
import java.util.ArrayList;
public class CompositePattern { public static void main(String[] args) { Composite root = new Composite("root"); root.add(new Leaf("Leaf A")); root.add(new Leaf("Leaf B"));
Composite comp = new Composite("Composite X"); comp.add(new Leaf("Leaf XA")); comp.add(new Leaf("Leaf XB")); root.add(comp);
Composite comp2 = new Composite("Composite XY"); comp2.add(new Leaf("Leaf XYA")); comp2.add(new Leaf("Leaf XYB")); comp.add(comp2);
Leaf leaf = new Leaf("Leaf C"); root.add(leaf);
Leaf leaf2 = new Leaf("Leaf D"); root.add(leaf2); root.remove(leaf2);
root.display(1);
} }
abstract class Component{ protected String name; public Component(String name){ this.name = name; }
public abstract void add(Component component); public abstract void remove(Component component); public abstract void display(int depth); }
class Leaf extends Component {
public Leaf(String name){ super(name); }
@Override public void add(Component component) { System.out.println("Cannot add to a leaf."); }
@Override public void remove(Component component) { System.out.println("Cannot remove from a leaf."); }
@Override public void display(int depth) { for (int i = 0; i < depth; i++) System.out.print("-"); System.out.println(name); } }
class Composite extends Component{
private ArrayList<Component> children = new ArrayList<Component>();
public Composite(String name){ super(name); }
@Override public void add(Component component) { children.add(component); }
@Override public void remove(Component component) { children.remove(component); }
@Override public void display(int depth) { for (int i = 0;i<depth;i++) System.out.print("-"); System.out.println(name); for (Component item : children) { item.display(depth+2); } } }
|
需求中是体现部分与整体层次的结构时,希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式。
第 20 章 迭代器模式
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
![](https://cdn.gumengyo.top//image-20230515193830432.png)
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
| package cn.jishuqin.chapter20;
import java.util.ArrayList;
public class IteratorPattern { public static void main(String[] args) { ConcreteAggregate bus = new ConcreteAggregate(); bus.add("大鸟"); bus.add("小菜"); bus.add("行李"); bus.add("老外"); bus.add("公交内部员工"); bus.add("小偷");
Iterator conductor = new ConcreteIterator(bus);
conductor.first(); while (!conductor.isDone()){ System.out.println(conductor.currentItem() + ",请买车票!"); conductor.next(); } } }
abstract class Aggregate{ public abstract Iterator createIterator(); }
class ConcreteAggregate extends Aggregate{
private ArrayList<Object> items = new ArrayList<Object>();
@Override public Iterator createIterator() { return new ConcreteIterator(this); }
public int getCount(){ return items.size(); }
public void add(Object object){ items.add(object); }
public Object getCurrentItem(int index){ return items.get(index); } }
abstract class Iterator{ public abstract Object first(); public abstract Object next(); public abstract boolean isDone(); public abstract Object currentItem(); }
class ConcreteIterator extends Iterator{
private ConcreteAggregate aggregate; private int current = 0;
public ConcreteIterator(ConcreteAggregate aggregate){ this.aggregate = aggregate; }
@Override public Object first() { return aggregate.getCurrentItem(0); }
@Override public Object next() { Object ret = null; current++; if (current < aggregate.getCount()){ ret = aggregate.getCurrentItem(current); } return ret; }
@Override public boolean isDone() { return current >= aggregate.getCount() ? true : false; }
@Override public Object currentItem() { return aggregate.getCurrentItem(current); } }
|
当你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。
迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。
第 21 章 单例模式
单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。
懒汉单例:要在第一次被引用时,才会将自己实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Singleton { private static Singleton instance;
private Singleton1(){
}
public static Singleton getInstance() { if (instance == null){ instance = new Singleton(); } return instance; } }
|
饿汉单例:静态初始化的方式是在自己被加载时就将自己实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance() { return instance; } }
|
第 22 章 桥接模式
合成/聚合复用原则(CAPP),尽量使用合成/聚合,尽量不要使用类继承。
桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。
![](https://cdn.gumengyo.top//image-20230516164259051.png)
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
| package cn.jishuqin.chapter22;
public class BridgePattern { public static void main(String[] args) { Abstraction ab; ab = new RefinedAbstraction();
ab.setImplementor(new ConcreteImplementorA()); ab.operation();
ab.setImplementor(new ConcreteImplementorB()); ab.operation(); } }
abstract class Implementor{ public abstract void operation(); }
class ConcreteImplementorA extends Implementor{
@Override public void operation() { System.out.println("具体实现A的方法执行"); } }
class ConcreteImplementorB extends Implementor{
@Override public void operation() { System.out.println("具体实现B的方法执行"); } }
abstract class Abstraction{ protected Implementor implementor;
public void setImplementor(Implementor implementor){ this.implementor = implementor; }
public abstract void operation(); }
class RefinedAbstraction extends Abstraction{
@Override public void operation() { System.out.println("具体的Abstraction"); implementor.operation(); } }
|
实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。
第 23 章 命令模式
命令模式(Command),讲一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
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
| package cn.jishuqin.chapter23;
import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date;
public class CommandPattern { public static void main(String[] args) { Barbecuer boy = new Barbecuer(); Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); Waiter girl = new Waiter();
System.out.println("开门营业,顾客点菜"); girl.setOrder(bakeMuttonCommand1); girl.setOrder(bakeMuttonCommand1); girl.setOrder(bakeMuttonCommand1); girl.setOrder(bakeMuttonCommand1); girl.setOrder(bakeMuttonCommand1);
girl.cancelOrder(bakeMuttonCommand1);
girl.setOrder(bakeChickenWingCommand1);
System.out.println("点菜完毕,通知厨房烧菜"); girl.notifyCommand(); } }
class Barbecuer{ public void bakeMutton(){ System.out.println("烤羊肉串!"); } public void bakeChickenWing(){ System.out.println("烤鸡翅!"); } }
abstract class Command{ protected Barbecuer receiver;
public Command(Barbecuer receiver){ this.receiver = receiver; } public abstract void excuteCommand(); }
class BakeMuttonCommand extends Command { public BakeMuttonCommand(Barbecuer receiver){ super(receiver); }
@Override public void excuteCommand() { receiver.bakeMutton(); } }
class BakeChickenWingCommand extends Command{ public BakeChickenWingCommand(Barbecuer receiver){ super(receiver); }
@Override public void excuteCommand() { receiver.bakeChickenWing(); } }
class Waiter{ private ArrayList<Command> orders = new ArrayList<Command>();
public void setOrder(Command command){ String className= command.getClass().getSimpleName();
if (className.equals("BakeChickenWingCommand")){ System.out.println("服务员:鸡翅没有了,请点别的烧烤。"); }else { this.orders.add(command); System.out.println("增加订单:"+className + "时间:"+getNowTime()); } } public void cancelOrder(Command command){ String className = command.getClass().getSimpleName(); orders.remove(command); System.out.println("取消订单:"+className+" 时间:" + getNowTime()); } public void notifyCommand(){ for (Command command : orders) { command.excuteCommand(); } }
private String getNowTime(){ SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss"); return formatter.format(new Date()).toString(); } }
|
优点:
- 能较容易地设计一个命令队列
- 在需要的情况下,可以较容易地将命令记入日志
- 允许接收请求的一方决定是否要否决请求
- 可以容易地实现对请求的撤销和重做
- 由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易
- 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分隔开
第 24 章 职责链模式
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
![](https://cdn.gumengyo.top//image-20230517165824783.png)
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
| package cn.jishuqin.chapter24;
public class ChainOfResponsibilityPattern { public static void main(String[] args) { Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2(); Handler h3 = new ConcreteHandler3(); h1.setSuccessor(h2); h2.setSuccessor(h3);
int[] requests = {2,5,14,22,18,3,27,20};
for (int request : requests) { h1.handleRequest(request); } } }
abstract class Handler{ protected Handler successor;
public void setSuccessor(Handler successor) { this.successor = successor; }
public abstract void handleRequest(int request); }
class ConcreteHandler1 extends Handler {
@Override public void handleRequest(int request) { if (request >= 0 && request < 10){ System.out.println(this.getClass().getSimpleName() + " 处理请求 "+request); }else if(successor != null){ successor.handleRequest(request); } } }
class ConcreteHandler2 extends Handler {
@Override public void handleRequest(int request) { if (request >= 10 && request < 20){ System.out.println(this.getClass().getSimpleName() + " 处理请求 "+request); }else if(successor != null){ successor.handleRequest(request); } } }
class ConcreteHandler3 extends Handler {
@Override public void handleRequest(int request) { if (request >= 20 && request < 30){ System.out.println(this.getClass().getSimpleName() + " 处理请求 "+request); }else if(successor != null){ successor.handleRequest(request); } } }
|
职责链的好处:
- 接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接收者的引用。
- 可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。
第 25 章 中介者模式
中介者模式(Mediator),用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
![](https://cdn.gumengyo.top//image-20230517171344605.png)
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
| package cn.jishuqin.chapter25;
public class MediatorPattern { public static void main(String[] args) { ConcreteMediator m = new ConcreteMediator();
ConcreteColleague1 c1 = new ConcreteColleague1(m); ConcreteColleague2 c2 = new ConcreteColleague2(m);
m.setColleague1(c1); m.setColleague2(c2);
c1.send("吃过饭了吗?"); c2.send("没有呢,你打算请客?"); } }
abstract class Colleague{ protected Mediator mediator; public Colleague(Mediator mediator){ this.mediator = mediator; } }
class ConcreteColleague1 extends Colleague{ public ConcreteColleague1(Mediator mediator){ super(mediator); }
public void send(String message) { this.mediator.send(message,this); }
public void notify(String message) { System.out.println("同事1得到信息:"+message); } }
class ConcreteColleague2 extends Colleague{ public ConcreteColleague2(Mediator mediator){ super(mediator); }
public void send(String message) { this.mediator.send(message,this); }
public void notify(String message) { System.out.println("同事2得到信息:"+message); } }
abstract class Mediator{ public abstract void send(String message,Colleague colleague); }
class ConcreteMediator extends Mediator {
private ConcreteColleague1 colleague1; private ConcreteColleague2 colleague2;
public void setColleague1(ConcreteColleague1 value){ this.colleague1 = value; }
public void setColleague2(ConcreteColleague2 value){ this.colleague2 = value; }
@Override public void send(String message, Colleague colleague) { if (colleague == colleague1){ colleague2.notify(message); }else { colleague1.notify(message); } } }
|
中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。
第 26 章 享元模式
享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。
![](https://cdn.gumengyo.top//image-20230518185501261.png)
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
| package cn.jishuqin.chapter26;
import java.util.Hashtable;
public class FlyweightPattern { public static void main(String[] args) { int extrinsicstate = 22;
FlyweightFactory f = new FlyweightFactory();
Flyweight fx = f.getFlyweight("X"); fx.operation(--extrinsicstate);
Flyweight fy = f.getFlyweight("Y"); fy.operation(--extrinsicstate);
Flyweight fz = f.getFlyweight("Z"); fz.operation(--extrinsicstate);
Flyweight uf = new UnsharedConcreteFlyweight();
uf.operation(--extrinsicstate); } }
abstract class Flyweight{ public abstract void operation(int extrinsicstate); }
class ConcreteFlyweight extends Flyweight{ @Override public void operation(int extrinsicstate) { System.out.println("具体Flyweight:" + extrinsicstate); } }
class UnsharedConcreteFlyweight extends Flyweight{
@Override public void operation(int extrinsicstate) { System.out.println("不共享的具体Flyweight:" + extrinsicstate); } }
class FlyweightFactory{ private Hashtable<String,Flyweight> flyweights = new Hashtable<String,Flyweight>();
public FlyweightFactory(){ flyweights.put("X",new ConcreteFlyweight()); flyweights.put("Y",new ConcreteFlyweight()); flyweights.put("Z",new ConcreteFlyweight()); }
public Flyweight getFlyweight(String key){ return flyweights.get(key); } }
|
如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用享元模式;还有就是对象的大多数状态可以是外部状态,如果删除对象的外部状态,那么可以相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。
第 27 章 解释器模式
解释器模式(interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
![](https://cdn.gumengyo.top//image-20230518191404357.png)
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
| package cn.jishuqin.chapter27;
import java.util.ArrayList;
public class InterpreterPattern { public static void main(String[] args) { Context context = new Context(); ArrayList<AbstractExpression> list = new ArrayList<AbstractExpression>(); list.add(new TerminalExpression()); list.add(new NonterminalExpression()); list.add(new TerminalExpression()); list.add(new TerminalExpression());
for (AbstractExpression exp : list) { exp.interpret(context); } } }
abstract class AbstractExpression{ public abstract void interpret(Context context); }
class TerminalExpression extends AbstractExpression{
@Override public void interpret(Context context) { System.out.println("终端解释器"); } }
class NonterminalExpression extends AbstractExpression{
@Override public void interpret(Context context) { System.out.println("非终端解释器"); } }
class Context{ private String input; public String getInput() { return this.input; } public void setInput(String value){ this.input = value; }
private String output; public String getOutput() { return this.output; } public void setOutput(String value){ this.output = value; } }
|
如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。
这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
第 28 章 访问者模式
访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
![](https://cdn.gumengyo.top//image-20230520200148737.png)
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
| package cn.jishuqin.chapter28;
import java.util.ArrayList;
public class VisitorPattern { public static void main(String[] args) { ObjectStructure o = new ObjectStructure(); o.attach(new ConcreteElementA()); o.attach(new ConcreteElementB());
ConcreteVisitor1 v1 = new ConcreteVisitor1(); ConcreteVisitor2 v2 = new ConcreteVisitor2();
o.accept(v1); o.accept(v2); } }
abstract class Visitor { public abstract void visitConcreteElementA(ConcreteElementA concreteElementA); public abstract void visitConcreteElementB(ConcreteElementB concreteElementB); }
class ConcreteVisitor1 extends Visitor {
@Override public void visitConcreteElementA(ConcreteElementA concreteElementA) { System.out.println(concreteElementA.getClass().getSimpleName()+"被"+this.getClass().getSimpleName()+"访问"); }
@Override public void visitConcreteElementB(ConcreteElementB concreteElementB) { System.out.println(concreteElementB.getClass().getSimpleName()+"被"+this.getClass().getSimpleName()+"访问"); } }
class ConcreteVisitor2 extends Visitor {
@Override public void visitConcreteElementA(ConcreteElementA concreteElementA) { System.out.println(concreteElementA.getClass().getSimpleName()+"被"+this.getClass().getSimpleName()+"访问"); }
@Override public void visitConcreteElementB(ConcreteElementB concreteElementB) { System.out.println(concreteElementB.getClass().getSimpleName()+"被"+this.getClass().getSimpleName()+"访问"); } }
abstract class Element{ public abstract void accept(Visitor visitor); }
class ConcreteElementA extends Element{
@Override public void accept(Visitor visitor) { visitor.visitConcreteElementA(this); }
public void operationA(){ } }
class ConcreteElementB extends Element{
@Override public void accept(Visitor visitor) { visitor.visitConcreteElementB(this); }
public void operationA(){ } }
class ObjectStructure{ private ArrayList<Element> elements = new ArrayList<Element>();
public void attach(Element element){ elements.add(element); }
public void detach(Element element){ elements.remove(element); }
public void accept(Visitor visitor){ for (Element element : elements) { element.accept(visitor); } } }
|
访问者模式的目的是要把处理从数据结构分离出来,有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。
访问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。
访问者模式将有关的行为集中到一个访问者对象中。