正文

一、桥接模式

1、定义

桥接模式通过将实现和抽象分离开来,放在两个不同的类层次中,从而使得它们可以独立改变。

要点:

  • 当一个类存在两个独立变化的维度,而且都需要进行扩展时,可以将其中一个维度抽象化,另一个维度实现化。
  • 抽象化就是通过抽象类来实现多态,实现化则是通过接口来实现多态。
  • 桥接模式通过在抽象类中持有实现类接口,来将两个维度“桥接”起来。

2、实现步骤

(1)创建实现化角色接口

  1. /**
  2. * 实现化角色接口
  3. */
  4. public interface Implementor {
  5. void action();
  6. }

(2)创建具体实现化角色

  1. /**
  2. * 具体实现化角色A
  3. */
  4. public class ConcreteImplementorA implements Implementor {
  5. @Override
  6. public void action() {
  7. System.out.println("ConcreteImplementorA action");
  8. }
  9. }
  1. /**
  2. * 具体实现化角色B
  3. */
  4. public class ConcreteImplementorB implements Implementor {
  5. @Override
  6. public void action() {
  7. System.out.println("ConcreteImplementorB action");
  8. }
  9. }

(3)创建抽象化角色抽象类,并持有实现化角色接口

  1. /**
  2. * 抽象化角色抽象类
  3. */
  4. public abstract class Abstraction {
  5. /**
  6. * 实现化角色接口
  7. */
  8. Implementor implementor;
  9. public Abstraction(Implementor implementor) {
  10. this.implementor = implementor;
  11. }
  12. public abstract void action();
  13. }

(4)创建具体抽象化角色

  1. /**
  2. * 具体抽象化角色A
  3. */
  4. public class ConcreteAbstractionA extends Abstraction {
  5. public ConcreteAbstractionA(Implementor implementor) {
  6. super(implementor);
  7. }
  8. @Override
  9. public void action() {
  10. System.out.print("ConcreteAbstractionA action --> ");
  11. // 调用实现化角色的方法
  12. implementor.action();
  13. }
  14. }
  1. /**
  2. * 具体抽象化角色B
  3. */
  4. public class ConcreteAbstractionB extends Abstraction {
  5. public ConcreteAbstractionB(Implementor implementor) {
  6. super(implementor);
  7. }
  8. @Override
  9. public void action() {
  10. System.out.print("ConcreteAbstractionB action --> ");
  11. // 调用实现化角色的方法
  12. implementor.action();
  13. }
  14. }

(5)组合抽象化角色与实现化角色

通过组合抽象化角色与实现化角色,来实现更多的功能。

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 实现化角色
  4. Implementor implementorA = new ConcreteImplementorA();
  5. Implementor implementorB = new ConcreteImplementorB();
  6. // 抽象化角色
  7. Abstraction abstractionAA = new ConcreteAbstractionA(implementorA);
  8. Abstraction abstractionAB = new ConcreteAbstractionA(implementorB);
  9. Abstraction abstractionBA = new ConcreteAbstractionB(implementorA);
  10. Abstraction abstractionBB = new ConcreteAbstractionB(implementorB);
  11. // 请求动作
  12. abstractionAA.action();
  13. abstractionAB.action();
  14. abstractionBA.action();
  15. abstractionBB.action();
  16. }
  17. }

二、生成器模式(建造者模式)

1、定义

生成器模式封装一个产品的构造过程,并允许按步骤构造。

要点:

  • 将一个复杂对象的创建过程封装起来。
  • 允许对象通过多个步骤来创建,并且可以改变过程(这和只有一个步骤的工厂模式不同)。

2、实现步骤

(1)创建产品类

  1. /**
  2. * 产品
  3. */
  4. public class Product {
  5. /**
  6. * 产品部件1
  7. */
  8. private String part1;
  9. /**
  10. * 产品部件2
  11. */
  12. private String part2;
  13. /**
  14. * 产品部件3
  15. */
  16. private String part3;
  17. public String getPart1() {
  18. return part1;
  19. }
  20. public void setPart1(String part1) {
  21. this.part1 = part1;
  22. }
  23. public String getPart2() {
  24. return part2;
  25. }
  26. public void setPart2(String part2) {
  27. this.part2 = part2;
  28. }
  29. public String getPart3() {
  30. return part3;
  31. }
  32. public void setPart3(String part3) {
  33. this.part3 = part3;
  34. }
  35. @Override
  36. public String toString() {
  37. return "Product [part1=" + part1 + ", part2=" + part2 + ", part3=" + part3 + "]";
  38. }
  39. }

(2)创建生成器抽象类

  1. /**
  2. * 生成器抽象类
  3. */
  4. public abstract class Builder {
  5. protected Product product = new Product();
  6. public abstract void buildPart1();
  7. public abstract void buildPart2();
  8. public abstract void buildPart3();
  9. /**
  10. * 获取产品
  11. */
  12. public Product getProduct() {
  13. return product;
  14. }
  15. }

(3)创建具体生成器

  1. /**
  2. * 具体生成器
  3. */
  4. public class ConcreteBuilder extends Builder {
  5. @Override
  6. public void buildPart1() {
  7. product.setPart1("product part 1");
  8. }
  9. @Override
  10. public void buildPart2() {
  11. product.setPart2("product part 2");
  12. }
  13. @Override
  14. public void buildPart3() {
  15. product.setPart3("product part 3");
  16. }
  17. }

(4)使用生成器生成产品

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 生成器
  4. Builder builder = new ConcreteBuilder();
  5. // 生成产品
  6. builder.buildPart1();
  7. builder.buildPart2();
  8. builder.buildPart3();
  9. // 获取产品
  10. Product product = builder.getProduct();
  11. System.out.println(product);
  12. }
  13. }

三、责任链模式

1、定义

责任链模式为某个请求创建一个对象链。每个对象依序检查此请求,并对其进行处理,或者将它传给链中的下一个对象。

要点:

  • 将请求的发送者和接受者解耦。
  • 通过改变链内成员或调动它们的次序,允许你动态地新增或删除责任。

2、实现步骤

(1)创建请求数据包类

  1. /**
  2. * 请求数据包
  3. */
  4. public class Request {
  5. /**
  6. * 级别
  7. */
  8. private int level;
  9. /**
  10. * 数据
  11. */
  12. private String data;
  13. public Request(int level, String data) {
  14. this.level = level;
  15. this.data = data;
  16. }
  17. public int getLevel() {
  18. return level;
  19. }
  20. public void setLevel(int level) {
  21. this.level = level;
  22. }
  23. public String getData() {
  24. return data;
  25. }
  26. public void setData(String data) {
  27. this.data = data;
  28. }
  29. }

(2)创建处理器抽象类

  1. /**
  2. * 处理器抽象类
  3. */
  4. public abstract class Handler {
  5. /**
  6. * 下一个处理器
  7. */
  8. protected Handler nextHandler;
  9. public Handler getNextHandler() {
  10. return nextHandler;
  11. }
  12. public void setNextHandler(Handler nextHandler) {
  13. this.nextHandler = nextHandler;
  14. }
  15. /**
  16. * 处理请求
  17. */
  18. protected abstract void handleRequest(Request request);
  19. }

(3)创建具体处理器

  1. /**
  2. * 具体处理器A
  3. */
  4. public class ConcreteHandlerA extends Handler {
  5. @Override
  6. protected void handleRequest(Request request) {
  7. if (request.getLevel() <= 1) {
  8. System.out.println("ConcreteHandlerA is handling the request, data: " + request.getData());
  9. } else {
  10. getNextHandler().handleRequest(request);
  11. }
  12. }
  13. }
  1. /**
  2. * 具体处理器B
  3. */
  4. public class ConcreteHandlerB extends Handler {
  5. @Override
  6. protected void handleRequest(Request request) {
  7. if (request.getLevel() <= 2) {
  8. System.out.println("ConcreteHandlerB is handling the request, data: " + request.getData());
  9. } else {
  10. getNextHandler().handleRequest(request);
  11. }
  12. }
  13. }
  1. /**
  2. * 具体处理器C
  3. */
  4. public class ConcreteHandlerC extends Handler {
  5. @Override
  6. protected void handleRequest(Request request) {
  7. if (request.getLevel() <= 3) {
  8. System.out.println("ConcreteHandlerC is handling the request, data: " + request.getData());
  9. } else {
  10. System.out.println("No handler can handle the request...");
  11. }
  12. }
  13. }

(4)使用处理器链处理请求

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 创建责任链(处理器链)
  4. Handler handlerA = new ConcreteHandlerA();
  5. Handler handlerB = new ConcreteHandlerB();
  6. Handler handlerC = new ConcreteHandlerC();
  7. handlerA.setNextHandler(handlerB);
  8. handlerB.setNextHandler(handlerC);
  9. // 使用责任链处理请求
  10. handlerA.handleRequest(new Request(1, "请求1"));
  11. handlerA.handleRequest(new Request(2, "请求2"));
  12. handlerA.handleRequest(new Request(3, "请求3"));
  13. handlerA.handleRequest(new Request(4, "请求4"));
  14. }
  15. }

四、蝇量模式(享元模式)

1、定义

蝇量模式能让某个类的一个实例能用来提供许多“虚拟实例”。

要点:

  • 运用共享技术,减少运行时对象实例的个数,节省内存。
  • 当一个类有许多实例,而这些实例能被同一个方法控制时,可以使用蝇量模式。

2、实现步骤

(1)创建抽象蝇量类

  1. /**
  2. * 抽象蝇量类
  3. */
  4. public abstract class Flyweight {
  5. /**
  6. * 共享状态(所有实例共有的、一致的状态)
  7. */
  8. public String sharedState;
  9. /**
  10. * 非共享状态(不同实例间不共有、或者不一致的状态)
  11. */
  12. public final String unsharedState;
  13. public Flyweight(String unsharedState) {
  14. this.unsharedState = unsharedState;
  15. }
  16. public abstract void operate();
  17. }

(2)创建具体蝇量类

  1. /**
  2. * 具体蝇量类
  3. */
  4. public class ConcreteFlyweight extends Flyweight {
  5. public ConcreteFlyweight(String unsharedState) {
  6. super(unsharedState);
  7. sharedState = "Shared State";
  8. }
  9. @Override
  10. public void operate() {
  11. System.out.println("ConcreteFlyweight is operating. [sharedState: " + sharedState + ", unsharedState: " + unsharedState + "]");
  12. }
  13. }

(3)创建蝇量类工厂

  1. /**
  2. * 蝇量类工厂
  3. */
  4. public class FlyweightFactory {
  5. /**
  6. * 池容器
  7. */
  8. private static HashMap<String, Flyweight> pool = new HashMap<>();
  9. /**
  10. * 获取蝇量类实例
  11. */
  12. public static Flyweight getFlyweight(String unsharedState) {
  13. // 从池中取出蝇量类实例
  14. Flyweight flyweight = pool.get(unsharedState);
  15. if (flyweight == null) {
  16. // 创建蝇量类实例,并放入池中
  17. System.out.println("Create flyweight instance, and put into the pool:" + unsharedState);
  18. flyweight = new ConcreteFlyweight(unsharedState);
  19. pool.put(unsharedState, flyweight);
  20. } else {
  21. System.out.println("Get flyweight instance from the pool:" + unsharedState);
  22. }
  23. return flyweight;
  24. }
  25. }

(4)使用蝇量类工厂创建蝇量类

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 从工厂获取蝇量类实例,并执行操作
  4. Flyweight flyweight1 = FlyweightFactory.getFlyweight("Unshared State A");
  5. flyweight1.operate();
  6. System.out.println();
  7. Flyweight flyweight2 = FlyweightFactory.getFlyweight("Unshared State B");
  8. flyweight2.operate();
  9. System.out.println();
  10. Flyweight flyweight3 = FlyweightFactory.getFlyweight("Unshared State A");
  11. flyweight3.operate();
  12. }
  13. }

五、解释器模式

1、定义

解释器模式将每一个语法规则表示成一个类。

要点:

  • 当你需要实现一个简单的语言时,就使用解释器。
  • 解释器模式的每一个语法规则对应一个表达式类,表达式包含终结符表达式和非终结符表达式。
  • 终结符表达式对应的语法规则不可再分解,因此终结符表达式的解释方法不会调用其他表达式的解释方法。
  • 非终结符表达式对应的语法规则可以分解为其他语法规则,因此非终结符表达式的解释方法会调用到其他表达式的解释方法。

2、实现步骤

(1)创建上下文环境类

  1. /**
  2. * 上下文环境(运行环境)
  3. * 用于管理全局信息
  4. */
  5. public class Context {
  6. // TODO 处理全局信息的相关方法
  7. /**
  8. * 运行
  9. */
  10. public void run(String data) {
  11. // 调用相关表达式的解释方法
  12. Expression terminal1 = new TerminalExpression(data);
  13. Expression terminal2 = new TerminalExpression(data);
  14. Expression nonterminal = new NonterminalExpression(terminal1, terminal2);
  15. nonterminal.interpret(this);
  16. }
  17. }

(2)创建表达式接口

  1. /**
  2. * 表达式接口
  3. */
  4. public interface Expression {
  5. /**
  6. * 执行解释
  7. */
  8. public void interpret(Context context);
  9. }

(3)创建具体表达式

  1. /**
  2. * 终结符表达式
  3. */
  4. public class TerminalExpression implements Expression {
  5. private String data;
  6. public TerminalExpression(String data) {
  7. this.data = data;
  8. }
  9. @Override
  10. public void interpret(Context context) {
  11. System.out.println("TerminalExpression is interpreting data: " + data);
  12. // TODO 进行解释操作,终结符表达式不会调用其他表达式的解释方法
  13. }
  14. }
  1. /**
  2. * 非终结符表达式
  3. */
  4. public class NonterminalExpression implements Expression {
  5. private Expression exp1;
  6. private Expression exp2;
  7. public NonterminalExpression(Expression exp1, Expression exp2) {
  8. this.exp1 = exp1;
  9. this.exp2 = exp2;
  10. }
  11. @Override
  12. public void interpret(Context context) {
  13. System.out.println("NonterminalExpression is interpreting...");
  14. // 调用其他表达式的解释方法
  15. exp1.interpret(context);
  16. exp2.interpret(context);
  17. }
  18. }

(4)使用表达式解释数据

  1. public class Test {
  2. public static void main(String[] args) {
  3. Context context = new Context();
  4. context.run("I like cat");
  5. }
  6. }

3、举个栗子

创建一个解释“二元运算代码”的解释器。

代码格式:算术表达式; 变量赋值1; 变量赋值2。

代码例子:a + b; a = 1; b = 2。

(1)创建上下文环境类

  1. /**
  2. * 上下文环境(运行环境)
  3. * 用于管理全局信息
  4. */
  5. public class Context {
  6. /**
  7. * 数据池
  8. */
  9. private static Map<Expression, Integer> dataPool = new HashMap<Expression, Integer>();
  10. /**
  11. * 赋值
  12. */
  13. public void assign(Expression var, int value) {
  14. dataPool.put(var, value);
  15. }
  16. /**
  17. * 取值
  18. */
  19. public int lookup(Expression var) {
  20. Integer value = dataPool.get(var);
  21. return value == null ? 0 : value;
  22. }
  23. /**
  24. * 运行代码
  25. */
  26. public int run(String code) {
  27. return new CodeExpression(code).interpret(this);
  28. }
  29. }

(2)创建抽象表达式

  1. /**
  2. * 抽象表达式
  3. */
  4. public abstract class Expression {
  5. protected String code;
  6. public Expression(String code) {
  7. this.code = code;
  8. }
  9. /**
  10. * 执行解释
  11. */
  12. public abstract int interpret(Context context);
  13. @Override
  14. public boolean equals(Object obj) {
  15. if (obj == null) {
  16. return false;
  17. }
  18. if (this == obj) {
  19. return true;
  20. }
  21. if (obj instanceof Expression) {
  22. return this.code.equals(((Expression) obj).code);
  23. }
  24. return false;
  25. }
  26. @Override
  27. public int hashCode() {
  28. return code.hashCode();
  29. }
  30. }

(3)创建解释“二元运算代码”的具体表达式

  1. /**
  2. * 代码表达式
  3. */
  4. public class CodeExpression extends Expression {
  5. public CodeExpression(String code) {
  6. super(code);
  7. }
  8. @Override
  9. public int interpret(Context context) {
  10. // 代码格式: 算术表达式; 变量赋值1; 变量赋值2
  11. // 代码例子: a + b; a = 1; b = 2
  12. String[] codes = code.split("; ");
  13. // 算术表达式
  14. ArithExpression arith = new ArithExpression(codes[0]);
  15. // 赋值表达式
  16. AssignExpression assign = null;
  17. for (int i = 1; i < codes.length; i++) {
  18. assign = new AssignExpression(codes[i]);
  19. assign.interpret(context);
  20. }
  21. return arith.interpret(context);
  22. }
  23. }
  1. /**
  2. * 算术表达式
  3. */
  4. public class ArithExpression extends Expression {
  5. public ArithExpression(String code) {
  6. super(code);
  7. }
  8. @Override
  9. public int interpret(Context context) {
  10. // a + b
  11. // 以"空格"分隔变量与运算符
  12. String[] codes = code.split(" ");
  13. // 变量表达式
  14. VarExpression var1 = new VarExpression(codes[0]);
  15. VarExpression var2 = new VarExpression(codes[2]);
  16. // 运算符表达式
  17. OperatorExpression operator = new OperatorExpression(var1, codes[1], var2);
  18. return operator.interpret(context);
  19. }
  20. }
  1. /**
  2. * 赋值表达式
  3. */
  4. public class AssignExpression extends Expression {
  5. public AssignExpression(String code) {
  6. super(code);
  7. }
  8. @Override
  9. public int interpret(Context context) {
  10. // a = 1
  11. // 以"空格等号空格"分隔变量与数值
  12. String[] codes = code.split(" = ");
  13. // 变量表达式
  14. VarExpression var = new VarExpression(codes[0]);
  15. // 变量赋值
  16. context.assign(var, Integer.parseInt(codes[1]));
  17. return 0;
  18. }
  19. }
  1. /**
  2. * 变量表达式
  3. */
  4. public class VarExpression extends Expression {
  5. public VarExpression(String code) {
  6. super(code);
  7. }
  8. @Override
  9. public int interpret(Context context) {
  10. return context.lookup(this);
  11. }
  12. }
  1. /**
  2. * 运算符表达式
  3. */
  4. public class OperatorExpression extends Expression {
  5. Expression var1;
  6. Expression var2;
  7. public OperatorExpression(Expression var1, String code, Expression var2) {
  8. super(code);
  9. this.var1 = var1;
  10. this.var2 = var2;
  11. }
  12. @Override
  13. public int interpret(Context context) {
  14. OperatorExpression operator = null;
  15. switch (code) {
  16. case "+":
  17. operator = new AddExpression(var1, var2);
  18. break;
  19. case "-":
  20. operator = new SubExpression(var1, var2);
  21. break;
  22. default:
  23. throw new RuntimeException("暂不支持该运算");
  24. }
  25. return operator.interpret(context);
  26. }
  27. }
  1. /**
  2. * 加法表达式
  3. */
  4. public class AddExpression extends OperatorExpression {
  5. public AddExpression(Expression var1, Expression var2) {
  6. super(var1, "+", var2);
  7. }
  8. @Override
  9. public int interpret(Context context) {
  10. return var1.interpret(context) + var2.interpret(context);
  11. }
  12. }
  1. /**
  2. * 减法表达式
  3. */
  4. public class SubExpression extends OperatorExpression {
  5. public SubExpression(Expression var1, Expression var2) {
  6. super(var1, "-", var2);
  7. }
  8. @Override
  9. public int interpret(Context context) {
  10. return var1.interpret(context) - var2.interpret(context);
  11. }
  12. }

(4)使用表达式解释“二元运算代码”

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 上下文环境
  4. Context context = new Context();
  5. // 运行代码
  6. int result = context.run("a + b; a = 1; b = 2");
  7. System.out.println("结果1:" + result);
  8. result = context.run("a - b; a = 7; b = 2");
  9. System.out.println("结果2:" + result);
  10. }
  11. }

六、中介者模式

1、定义

中介者模式用于集中相关对象之间复杂的沟通和控制方式。

要点:

  • 通过将对象彼此解耦,可以增加对象的复用性。
  • 每个对象都会在自己状态改变时,告诉中介者。
  • 每个对象都会对中介者所发出的请求做出回应。

2、实现步骤

(1)创建交互对象抽象类

  1. /**
  2. * 交互对象抽象类
  3. */
  4. public abstract class InteractiveObject {
  5. protected Mediator mediator;
  6. public InteractiveObject(Mediator mediator) {
  7. this.mediator = mediator;
  8. }
  9. /**
  10. * 发送信息
  11. */
  12. public abstract void send(String msg);
  13. /**
  14. * 接收信息
  15. */
  16. public abstract void receive(String msg);
  17. }

(2)创建具体交互对象

  1. /**
  2. * 具体交互对象A
  3. */
  4. public class ConcreteInteractiveObjectA extends InteractiveObject {
  5. public ConcreteInteractiveObjectA(Mediator mediator) {
  6. super(mediator);
  7. }
  8. @Override
  9. public void send(String msg) {
  10. System.out.println("ConcreteInteractiveObjectA has sended message: " + msg);
  11. mediator.forward(this, msg);
  12. }
  13. @Override
  14. public void receive(String msg) {
  15. System.out.println("ConcreteInteractiveObjectA has received message: " + msg);
  16. }
  17. }
  1. /**
  2. * 具体交互对象B
  3. */
  4. public class ConcreteInteractiveObjectB extends InteractiveObject {
  5. public ConcreteInteractiveObjectB(Mediator mediator) {
  6. super(mediator);
  7. }
  8. @Override
  9. public void send(String msg) {
  10. System.out.println("ConcreteInteractiveObjectB has sended message: " + msg);
  11. mediator.forward(this, msg);
  12. }
  13. @Override
  14. public void receive(String msg) {
  15. System.out.println("ConcreteInteractiveObjectB has received message: " + msg);
  16. }
  17. }
  1. /**
  2. * 具体交互对象C
  3. */
  4. public class ConcreteInteractiveObjectC extends InteractiveObject {
  5. public ConcreteInteractiveObjectC(Mediator mediator) {
  6. super(mediator);
  7. }
  8. @Override
  9. public void send(String msg) {
  10. System.out.println("ConcreteInteractiveObjectC has sended message: " + msg);
  11. mediator.forward(this, msg);
  12. }
  13. @Override
  14. public void receive(String msg) {
  15. System.out.println("ConcreteInteractiveObjectC has received message: " + msg);
  16. }
  17. }

(3)创建中介者抽象类

  1. /**
  2. * 中介者抽象类
  3. */
  4. public abstract class Mediator {
  5. /**
  6. * 注册交互对象
  7. */
  8. public abstract void register(InteractiveObject obj);
  9. /**
  10. * 转发信息
  11. */
  12. public abstract void forward(InteractiveObject obj, String msg);
  13. }

(4)创建具体中介者

  1. /**
  2. * 具体中介者
  3. */
  4. public class ConcreteMediator extends Mediator {
  5. /**
  6. * 交互对象集合
  7. */
  8. private List<InteractiveObject> interactiveObjs = new ArrayList<>();
  9. @Override
  10. public void register(InteractiveObject obj) {
  11. interactiveObjs.add(obj);
  12. }
  13. @Override
  14. public void forward(InteractiveObject obj, String msg) {
  15. for (InteractiveObject interactiveObj : interactiveObjs) {
  16. if (!interactiveObj.equals(obj)) {
  17. interactiveObj.receive(msg);
  18. }
  19. }
  20. }
  21. }

(5)使用中介者管理交互对象之间的交互

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 中介者
  4. Mediator mediator = new ConcreteMediator();
  5. // 交互对象
  6. InteractiveObject objA = new ConcreteInteractiveObjectA(mediator);
  7. InteractiveObject objB = new ConcreteInteractiveObjectB(mediator);
  8. InteractiveObject objC = new ConcreteInteractiveObjectC(mediator);
  9. // 注册交互对象到中介者
  10. mediator.register(objA);
  11. mediator.register(objB);
  12. mediator.register(objC);
  13. // 发送信息
  14. objA.send("hello");
  15. }
  16. }

七、备忘录模式

1、定义

备忘录模式通过将状态存储在对象外部,使得对象可以返回之前的状态。

2、实现步骤

(1)创建备忘录

  1. /**
  2. * 备忘录
  3. */
  4. public class Memento {
  5. private String state;
  6. public Memento(String state) {
  7. this.state = state;
  8. }
  9. public String getState() {
  10. return state;
  11. }
  12. public void setState(String state) {
  13. this.state = state;
  14. }
  15. }

(2)创建备忘录管理者

  1. /**
  2. * 备忘录管理者
  3. */
  4. public class MementoCaretaker {
  5. private Memento memento;
  6. public Memento getMemento() {
  7. return memento;
  8. }
  9. public void setMemento(Memento memento) {
  10. this.memento = memento;
  11. }
  12. }

(3)创建备忘录发起人

  1. /**
  2. * 备忘录发起人
  3. */
  4. public class MementoOriginator {
  5. private String state;
  6. public String getState() {
  7. return state;
  8. }
  9. public void setState(String state) {
  10. this.state = state;
  11. }
  12. /**
  13. * 创建备忘录
  14. */
  15. public Memento createMemento() {
  16. return new Memento(state);
  17. }
  18. /**
  19. * 从备忘录中恢复状态
  20. */
  21. public void restoreFromMemento(Memento memento) {
  22. this.setState(memento.getState());
  23. }
  24. }

(4)使用备忘录存储、恢复状态

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 备忘录管理者
  4. MementoCaretaker caretaker = new MementoCaretaker();
  5. // 备忘录发起人
  6. MementoOriginator originator = new MementoOriginator();
  7. originator.setState("状态1");
  8. System.out.println("初始状态:" + originator.getState());
  9. // 备忘录发起人创建备忘录
  10. Memento memento = originator.createMemento();
  11. // 备忘录管理者保存备忘录
  12. caretaker.setMemento(memento);
  13. // 备忘录发起人改变状态
  14. originator.setState("状态2");
  15. System.out.println("新状态:" + originator.getState());
  16. // 从备忘录管理者中取出备忘录,并通过备忘录恢复状态
  17. originator.restoreFromMemento(caretaker.getMemento());
  18. System.out.println("恢复状态:" + originator.getState());
  19. }
  20. }

八、原型模式

1、定义

原型模式允许你通过复制现有的实例来创建新的实例。

要点:

  • 在 Java 中,这通常意味着使用 clone() 方法,或者反序列化。

2、实现步骤

(1)创建原型类,并实现 Cloneable 接口

  1. /**
  2. * 原型类(实现Cloneable接口)
  3. */
  4. public class Prototype implements Cloneable {
  5. public String type;
  6. public Prototype(String type) {
  7. this.type = type;
  8. }
  9. public String getType() {
  10. return type;
  11. }
  12. public void setType(String type) {
  13. this.type = type;
  14. }
  15. /**
  16. * 实现clone方法
  17. */
  18. @Override
  19. public Prototype clone() {
  20. try {
  21. return (Prototype) super.clone();
  22. } catch (CloneNotSupportedException e) {
  23. e.printStackTrace();
  24. }
  25. return null;
  26. }
  27. @Override
  28. public String toString() {
  29. return "Prototype [type=" + type + "]";
  30. }
  31. }

(2)通过复制现有实例,来创建新的实例

  1. public class Test {
  2. public static void main(String[] args) {
  3. Prototype prototype1 = new Prototype("A");
  4. System.out.println(prototype1);
  5. // 复制现有实例来创建新的实例
  6. Prototype prototype2 = prototype1.clone();
  7. System.out.println(prototype2);
  8. }
  9. }

九、访问者模式

1、定义

访问者模式通过访问数据结构(比如组合结构)中的每个元素,来对元素进行各种操作。

要点:

  • 通过将数据结构与数据操作分离,使得无需改变结构本身,就可以添加作用于结构内的元素的新的操作。

2、实现步骤

(1)创建元素接口

元素接口中定义了接受访问者访问的方法。

  1. /**
  2. * 元素接口
  3. */
  4. public interface Element {
  5. /**
  6. * 接受访问者访问
  7. */
  8. public void accept(Visitor visitor);
  9. }

(2)创建具体元素

  1. /**
  2. * 具体元素A
  3. */
  4. public class ConcreteElementA implements Element {
  5. @Override
  6. public void accept(Visitor visitor) {
  7. // 具体元素接受访问 -> 访问者访问具体元素
  8. visitor.visit(this);
  9. }
  10. public void operate() {
  11. System.out.println(" ConcreteElementA operate");
  12. }
  13. }
  1. /**
  2. * 具体元素B
  3. */
  4. public class ConcreteElementB implements Element {
  5. @Override
  6. public void accept(Visitor visitor) {
  7. // 具体元素接受访问 -> 访问者访问具体元素
  8. visitor.visit(this);
  9. }
  10. public void operate1() {
  11. System.out.println(" ConcreteElementB operate1");
  12. }
  13. public void operate2() {
  14. System.out.println(" ConcreteElementB operate2");
  15. }
  16. }

(3)创建数据结构

  1. /**
  2. * 数据结构
  3. */
  4. public class DataStructure {
  5. private List<Element> elements = new ArrayList<>();
  6. public void add(Element element) {
  7. elements.add(element);
  8. }
  9. public void remove(Element element) {
  10. elements.remove(element);
  11. }
  12. /**
  13. * 接受访问者访问
  14. */
  15. public void accept(Visitor visitor) {
  16. for (Element element : elements) {
  17. element.accept(visitor);
  18. }
  19. }
  20. }

(4)创建访问者接口

  1. /**
  2. * 访问者接口
  3. */
  4. public interface Visitor {
  5. /**
  6. * 访问具体元素A
  7. */
  8. public void visit(ConcreteElementA element);
  9. /**
  10. * 访问具体元素B
  11. */
  12. public void visit(ConcreteElementB element);
  13. }

(5)创建具体访问者

  1. /**
  2. * 具体访问者
  3. */
  4. public class ConcreteVisitor implements Visitor {
  5. @Override
  6. public void visit(ConcreteElementA element) {
  7. System.out.println("ConcreteVisitor visit ConcreteElementA:");
  8. // 访问者操作元素
  9. element.operate();
  10. }
  11. @Override
  12. public void visit(ConcreteElementB element) {
  13. System.out.println("ConcreteVisitor visit ConcreteElementB:");
  14. // 访问者操作元素
  15. element.operate1();
  16. element.operate2();
  17. }
  18. }

(6)使用访问者操作数据结构中的元素

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 数据结构
  4. DataStructure dataStructure = new DataStructure();
  5. dataStructure.add(new ConcreteElementA());
  6. dataStructure.add(new ConcreteElementB());
  7. // 访问者
  8. Visitor visitor = new ConcreteVisitor();
  9. // 数据结构接受访问者访问
  10. dataStructure.accept(visitor);
  11. }
  12. }

《Head First 设计模式》:剩下的模式的更多相关文章

  1. Java设计模式-享元模式(Flyweight)

    享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查 ...

  2. JavaScript设计模式之策略模式

    所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...

  3. 每天一个设计模式-7 生成器模式(Builder)

    每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...

  4. 每天一个设计模式-2 外观模式(Facade)

    每天一个设计模式-2  外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...

  5. Java设计模式之建造者模式(Builder)

    前言: 最近一直在学习okHttp,也对其做了一些整理,okHttp和Retrofit结合大大加速我们的开发效率,源码里面采用了很多设计模式,今天我们来学习一下其中的设计模式之一建造者模式. 建造者模 ...

  6. [Head First设计模式]云南米线馆中的设计模式——模版方法模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  7. 设计模式——抽象工厂模式及java实现

    设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...

  8. 设计模式-14 MVC模式

    一 MVC设计模式 MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式,它是一个存在于服务器 表达层的模型,它将应用分开,改变应用之间的高度耦合 MVC设计模式将 ...

  9. 设计模式_11_原型模式(prototype)深拷贝、浅拷贝

    设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...

  10. 17. 星际争霸之php设计模式--职责链模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

随机推荐

  1. vue学习04 v-on指令

    vue学习04 v-on指令 v-on的作用是为元素绑定事件,比如click单击,dbclick双击 v-on指令可简写为@ 代码测试 <!DOCTYPE html> <html l ...

  2. tomcat源码--springboot整合tomcat源码分析

    1.测试代码,一个简单的springboot web项目:地址:https://gitee.com/yangxioahui/demo_mybatis.git 一:tomcat的主要架构:1.如果我们下 ...

  3. Django-当前菜单激活状态-模版 request | slice

    如何满足这个需求? 1. view中传递过来一个当前页面的参数标识,通过模版语言进行判断 {% if current_page == 'index' %}active{% endif %} # 每一个 ...

  4. Django-Scrapy生成后端json接口

    Django-Scrapy生成后端json接口: 网上的关于django-scrapy的介绍比较少,该博客只在本人查资料的过程中学习的,如果不对之处,希望指出改正: 以后的博客可能不会再出关于djan ...

  5. Spring系列之事务的控制 注解实现+xml实现+事务的隔离等级

    Spring系列之事务的控制 注解实现+xml实现 在前面我写过一篇关于事务的文章,大家可以先去看看那一篇再看这一篇,学习起来会更加得心应手 链接:https://blog.csdn.net/pjh8 ...

  6. 082 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 01 构造方法-无参构造方法

    082 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 01 构造方法-无参构造方法 本文知识点:构造方法-无参构造方法 说明:因为时间紧张, ...

  7. Python3基础——函数

    ython 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...

  8. 使用 PL/SQL Developer 导入 .sql 文件

    操作系统:Windows 10 x64 PL/SQL Developer Version 12.0.7.1837 (64 bit) 01.226959 第一节:下载 Oracle Database X ...

  9. Linux中的硬链接和软连接

    1.Linux链接概念Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接]硬连接指通过索引节点 ...

  10. 达梦产品技术支持培训-day7-DM8数据库备份与还原-原理

    (本文部分内容摘自DM产品技术支持培训文档,如需要更详细的文档,请查询官方操作手册,谢谢) 1.DM8备份还原简介 1.1.基本概念 (1)表空间与数据文件 ▷ DM8表空间类型: ▷ SYSTEM ...