文章目录
创建型 | 结构型 | 行为型 |
---|---|---|
工厂模式(简单工厂、工厂方法) | 适配器模式 | 解释器模式 |
抽象工厂模式 | 桥接模式 | 模板方法模式 |
原型模式 | 组合模式 | 策略模式 |
建造者模式 | 装饰模式 | 观察者模式 |
单例模式 | 外观模式 | 状态模式 |
享元模式 | 备忘录模式 | |
代理模式 | 迭代器模式 | |
命令模式 | ||
责任链模式 | ||
中介者模式 | ||
访问者模式 |
- 创建型包含5种模式,涉及对象/对象组合的创建构建。
- 结构性包含7种模式,涉及对象/类之间的关系。
- 行为型包含11种模式,涉及对象/类的行为、状态、流程。
一、创建型模式
1、工厂模式
a、简单工厂
// 定义一个操作接口
interface Operation {
double getResult();
}
// 实现加法操作
class OperationAdd implements Operation {
private double numberA;
private double numberB;
public OperationAdd(double numberA, double numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Override
public double getResult() {
return numberA + numberB;
}
}
// 实现减法操作
class OperationSub implements Operation {
private double numberA;
private double numberB;
public OperationSub(double numberA, double numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Override
public double getResult() {
return numberA - numberB;
}
}
// 实现乘法操作
class OperationMul implements Operation {
private double numberA;
private double numberB;
public OperationMul(double numberA, double numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Override
public double getResult() {
return numberA * numberB;
}
}
// 实现除法操作
class OperationDiv implements Operation {
private double numberA;
private double numberB;
public OperationDiv(double numberA, double numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Override
public double getResult() {
if (numberB == 0) {
throw new ArithmeticException("divided by 0");
}
return numberA / numberB;
}
}
// 工厂类,用于创建具体操作
class OperationFactory {
public static Operation createOperation(char operatorType, double numberA, double numberB) {
switch (operatorType) {
case '+':
return new OperationAdd(numberA, numberB);
case '-':
return new OperationSub(numberA, numberB);
case '*':
return new OperationMul(numberA, numberB);
case '/':
return new OperationDiv(numberA, numberB);
default:
throw new IllegalArgumentException("unsupported operation");
}
}
}
public class Main {
public static void main(String[] args) {
try {
char operatorType = '+';
double numberA = 1.2;
double numberB = 2.3;
Operation operation = OperationFactory.createOperation(operatorType, numberA, numberB);
System.out.println("Result: " + operation.getResult());
} catch (Exception ex) {
System.err.println("Error: " + ex.getMessage());
}
}
}
b、工厂方法
工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
// 定义操作接口
interface Operation {
double getResult();
}
// 加法操作实现
class OperationAdd implements Operation {
private double numberA;
private double numberB;
public OperationAdd(double numberA, double numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Override
public double getResult() {
return numberA + numberB;
}
}
// 减法操作实现
class OperationSub implements Operation {
private double numberA;
private double numberB;
public OperationSub(double numberA, double numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Override
public double getResult() {
return numberA - numberB;
}
}
// 乘法操作实现
class OperationMul implements Operation {
private double numberA;
private double numberB;
public OperationMul(double numberA, double numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Override
public double getResult() {
return numberA * numberB;
}
}
// 除法操作实现
class OperationDiv implements Operation {
private double numberA;
private double numberB;
public OperationDiv(double numberA, double numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Override
public double getResult() {
if (numberB == 0) {
throw new ArithmeticException("divided by 0");
}
return numberA / numberB;
}
}
// 工厂接口
interface IFactory {
Operation createOperation(double numberA, double numberB);
}
// 加法工厂
class AddFactory implements IFactory {
@Override
public Operation createOperation(double numberA, double numberB) {
return new OperationAdd(numberA, numberB);
}
}
// 减法工厂
class SubFactory implements IFactory {
@Override
public Operation createOperation(double numberA, double numberB) {
return new OperationSub(numberA, numberB);
}
}
// 乘法工厂
class MulFactory implements IFactory {
@Override
public Operation createOperation(double numberA, double numberB) {
return new OperationMul(numberA, numberB);
}
}
// 除法工厂
class DivFactory implements IFactory {
@Override
public Operation createOperation(double numberA, double numberB) {
return new OperationDiv(numberA, numberB);
}
}
public class Main {
public static void main(String[] args) {
try {
// 创建一个除法工厂
IFactory operFactory = new DivFactory();
// 通过工厂创建一个除法操作对象
Operation operation = operFactory.createOperation(3.4, 4.5);
System.out.println("Result: " + operation.getResult());
} catch (Exception ex) {
System.err.println("Error: " + ex.getMessage());
}
}
}
2、抽象工厂模式
抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
// 抽象产品A
interface AbstractProductA {
void methodA();
}
// 具体产品A1
class ProductA1 implements AbstractProductA {
@Override
public void methodA() {
System.out.println("ProductA1's methodA");
}
}
// 具体产品A2
class ProductA2 implements AbstractProductA {
@Override
public void methodA() {
System.out.println("ProductA2's methodA");
}
}
// 抽象产品B
interface AbstractProductB {
void methodB();
}
// 具体产品B1
class ProductB1 implements AbstractProductB {
@Override
public void methodB() {
System.out.println("ProductB1's methodB");
}
}
// 具体产品B2
class ProductB2 implements AbstractProductB {
@Override
public void methodB() {
System.out.println("ProductB2's methodB");
}
}
// 抽象工厂
interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}
public class Main {
public static void main(String[] args) {
// 使用具体工厂1
AbstractFactory factory1 = new ConcreteFactory1();
AbstractProductA productA1 = factory1.createProductA();
AbstractProductB productB1 = factory1.createProductB();
productA1.methodA();
productB1.methodB();
// 使用具体工厂2
AbstractFactory factory2 = new ConcreteFactory2();
AbstractProductA productA2 = factory2.createProductA();
AbstractProductB productB2 = factory2.createProductB();
productA2.methodA();
productB2.methodB();
}
}
3、原型模式
原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
// 原型接口
interface Prototype {
Prototype clone(); // 克隆方法
}
// 具体原型A
class ConcretePrototypeA implements Prototype {
@Override
public Prototype clone() {
return new ConcretePrototypeA(); // 创建并返回一个新对象
}
}
// 具体原型B
class ConcretePrototypeB implements Prototype {
@Override
public Prototype clone() {
return new ConcretePrototypeB(); // 创建并返回一个新对象
}
}
public class Main {
public static void main(String[] args) {
// 创建具体原型A和具体原型B
ConcretePrototypeA prototypeA = new ConcretePrototypeA();
ConcretePrototypeB prototypeB = new ConcretePrototypeB();
// 克隆具体原型A和具体原型B
ConcretePrototypeA cloneA = (ConcretePrototypeA) prototypeA.clone();
ConcretePrototypeB cloneB = (ConcretePrototypeB) prototypeB.clone();
// 检查克隆是否成功
System.out.println("Clone A == Prototype A: " + (cloneA != prototypeA));
System.out.println("Clone B == Prototype B: " + (cloneB != prototypeB));
}
}
4、建造者模式
建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
// 产品类
class Product {
private String part1;
private String part2;
public void setPart1(String part1) {
this.part1 = part1;
}
public void setPart2(String part2) {
this.part2 = part2;
}
public void show() {
System.out.println("Part 1: " + part1);
System.out.println("Part 2: " + part2);
}
}
// 建造者接口
interface Builder {
void buildPart();
Product getResult();
}
// 具体建造者类
class ConcreteBuilder implements Builder {
private Product product;
public ConcreteBuilder() {
this.product = new Product();
}
@Override
public void buildPart() {
product.setPart1("Part 1 built by ConcreteBuilder");
product.setPart2("Part 2 built by ConcreteBuilder");
}
@Override
public Product getResult() {
return product;
}
}
// 指挥者类
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void construct() {
builder.buildPart();
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.getResult();
product.show();
}
}
5、单例模式
单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点。
// 线程安全的单例模式
class SingletonThreadSafe {
// 使用volatile保证内存可见性,防止指令重排
private static volatile SingletonThreadSafe instance;
// 私有构造函数,禁止直接实例化
private SingletonThreadSafe() {
}
// 获取单例实例的静态方法
public static SingletonThreadSafe getInstance() {
if (instance == null) {
synchronized (SingletonThreadSafe.class) {
// 加锁确保线程安全
if (instance == null) {
instance = new SingletonThreadSafe(); // 懒加载
}
}
}
return instance;
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
SingletonThreadSafe instance1 = SingletonThreadSafe.getInstance();
SingletonThreadSafe instance2 = SingletonThreadSafe.getInstance();
if (instance1 == instance2) {
System.out.println("Same instance");
} else {
System.out.println("Different instances");
}
}
}
二、结构型模式
1、适配器模式
适配器模式,将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
// 需要适配的类
class Adaptee {
public void specificRequest() {
System.out.println("Specific request!");
}
}
// 客户所期待的接口
interface Target {
void request();
}
// 适配器类,通过包装一个 Adaptee 对象,把原接口转换成目标接口
class Adapter implements Target {
private Adaptee adaptee;
public Adapter() {
this.adaptee = new Adaptee();
}
@Override
public void request() {
adaptee.specificRequest();
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
Target target = new Adapter();
target.request();
}
}
2、桥接模式
桥接模式,将抽象部分与它的实现部分分离,使它们都可以独立地变化。
// 实现部分的接口
interface Implementor {
void operation();
}
// 具体实现A
class ConcreteImplementorA implements Implementor {
public void operation() {
System.out.println("ConcreteImplementorA's method executed");
}
}
// 具体实现B
class ConcreteImplementorB implements Implementor {
public void operation() {
System.out.println("ConcreteImplementorB's method executed");
}
}
// 抽象部分
abstract class Abstraction {
protected Implementor implementor; // 聚合Implementor
protected String name;
public Abstraction(String name) {
this.name = name;
}
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public void operation() {
System.out.print("Abstraction-" + name + ": ");
if (implementor != null) {
implementor.operation();
}
}
}
// 扩展抽象部分A
class AbstractionA extends Abstraction {
public AbstractionA(String name) {
super(name);
}
@Override
public void operation() {
super.operation();
}
}
// 扩展抽象部分B
class AbstractionB extends Abstraction {
public AbstractionB(String name) {
super(name);
}
@Override
public void operation() {
super.operation();
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
Abstraction a = new AbstractionA("A");
a.setImplementor(new ConcreteImplementorA());
a.operation();
a.setImplementor(new ConcreteImplementorB());
a.operation();
Abstraction b = new AbstractionB("B");
b.setImplementor(new ConcreteImplementorA());
b.operation();
b.setImplementor(new ConcreteImplementorB());
b.operation();
// 符合开放-封闭原则,如果需要新的 Abstraction 或 ConcreteImplementor,只需扩展类
}
}
3、组合模式
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
import java.util.ArrayList;
import java.util.List;
// 抽象基类 Component,声明接口
abstract class Component {
protected String name;
// 用于显示层次结构的辅助函数
protected String repeatableLayer(int depth) {
return "-".repeat(depth);
}
public Component(String name) {
this.name = name;
}
public void add(Component component) {
System.out.println("Cannot add to this component");
}
public void remove(Component component) {
System.out.println("Cannot remove from this component");
}
public abstract void display(int depth);
}
// 叶子节点 Leaf,没有子节点
class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public void display(int depth) {
System.out.println(repeatableLayer(depth) + name);
}
}
// 组合节点 Composite,用于存储子节点
class Composite extends Component {
private List<Component> children = new ArrayList<>();
public Composite(String name) {
super(name);
}
@Override
public void add(Component component) {
children.add(component);
}
@Override
public void remove(Component component) {
if (children.contains(component)) {
children.remove(component);
} else {
System.out.println("Component not found to remove");
}
}
@Override
public void display(int depth) {
System.out.println(repeatableLayer(depth) + name);
for (Component child : children) {
child.display(depth + 2);
}
}
}
// 客户端
public class Main {
public static void main(String[] args) {
// 生成树根,根上长出两叶 Leaf A 和 Leaf B
Composite root = new Composite("root");
root.add(new Leaf("Leaf A"));
root.add(new Leaf("Leaf B"));
// 根上长出分支 Composite X,分支上也有两叶 Leaf X-A 和 Leaf X-B
Composite compositeX = new Composite("Composite X");
compositeX.add(new Leaf("Leaf X-A"));
compositeX.add(new Leaf("Leaf X-B"));
root.add(compositeX);
// 在 Composite X 上再长出分支 Composite X-Y,分支上也有两叶 Leaf X-Y-A 和 Leaf X-Y-B
Composite compositeXY = new Composite("Composite X-Y");
compositeXY.add(new Leaf("Leaf X-Y-A"));
compositeXY.add(new Leaf("Leaf X-Y-B"));
compositeX.add(compositeXY);
// 显示树的结构
root.display(1);
// 测试删除节点
System.out.println("\nRemoving Leaf X-A from Composite X");
compositeX.remove(new Leaf("Leaf X-A")); // 该方法没有找到 "Leaf X-A" 会显示 "Component not found to remove"
root.display(1);
}
}
4、装饰模式
装饰模式,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
// Component is the interface for the object
interface Component {
void operation();
}
// ConcreteComponent defines a concrete object
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("Operation of ConcreteComponent");
}
}
// Decorator is the abstract class, inheriting from Component
abstract class Decorator implements Component {
protected Component component;
public void setComponent(Component comp) {
this.component = comp;
}
@Override
public void operation() {
if (component != null) {
component.operation();
}
}
}
// ConcreteDecoratorA is a concrete decorator A
class ConcreteDecoratorA extends Decorator {
private String addedState;
@Override
public void operation() {
// First, call the original component's operation(), then add functionality
super.operation();
addedState = "New state in A ";
System.out.println(addedState + "Operation of ConcreteDecoratorA");
}
}
// ConcreteDecoratorB is a concrete decorator B
class ConcreteDecoratorB extends Decorator {
@Override
public void operation() {
super.operation();
addedBehavior();
System.out.println("Operation of ConcreteDecoratorB");
}
private void addedBehavior() {
System.out.println("Added behavior in B");
}
}
// ConcreteDecoratorC is a concrete decorator C
class ConcreteDecoratorC extends Decorator {
@Override
public void operation() {
super.operation();
System.out.println("No special behavior in C " + "Operation of ConcreteDecoratorC");
}
}
// Client code
public class Main {
public static void main(String[] args) {
// Create a concrete Component object
Component concreteComponent = new ConcreteComponent();
// Create concrete decorator A and decorate the original object
ConcreteDecoratorA decoratorA = new ConcreteDecoratorA();
decoratorA.setComponent(concreteComponent);
// Create concrete decorator B and decorate the original object
ConcreteDecoratorB decoratorB = new ConcreteDecoratorB();
decoratorB.setComponent(concreteComponent);
// Create concrete decorator C and decorate the original object
ConcreteDecoratorC decoratorC = new ConcreteDecoratorC();
decoratorC.setComponent(concreteComponent);
// Use decorator A, B, C to decorate the original object
System.out.println("Using ConcreteDecoratorA:");
decoratorA.operation();
System.out.println("\nUsing ConcreteDecoratorB:");
decoratorB.operation();
System.out.println("\nUsing ConcreteDecoratorC:");
decoratorC.operation();
}
}
5、外观模式
外观模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
// "System" interface (abstract class in C++)
interface SystemInterface {
void operation();
}
// SubSystemOne class implements SystemInterface
class SubSystemOne implements SystemInterface {
public void operation() {
System.out.println("SubSystem method one");
}
}
// SubSystemTwo class implements SystemInterface
class SubSystemTwo implements SystemInterface {
public void operation() {
System.out.println("SubSystem method two");
}
}
// SubSystemThree class implements SystemInterface
class SubSystemThree implements SystemInterface {
public void operation() {
System.out.println("SubSystem method three");
}
}
// SubSystemFour class implements SystemInterface
class SubSystemFour implements SystemInterface {
public void operation() {
System.out.println("SubSystem method four");
}
}
// Facade class that simplifies access to the subsystems
class Facade {
private SubSystemOne subSystemOne;
private SubSystemTwo subSystemTwo;
private SubSystemThree subSystemThree;
private SubSystemFour subSystemFour;
public Facade() {
subSystemOne = new SubSystemOne();
subSystemTwo = new SubSystemTwo();
subSystemThree = new SubSystemThree();
subSystemFour = new SubSystemFour();
}
public void methodA() {
System.out.println("Method Group A:");
subSystemOne.operation();
subSystemTwo.operation();
subSystemFour.operation();
}
public void methodB() {
System.out.println("Method Group B:");
subSystemThree.operation();
subSystemFour.operation();
}
}
// FacadeClient (client code)
public class Main {
public static void main(String[] args) {
// The client can use the Facade to interact with the subsystems
// without knowing the details of each subsystem.
// This is similar to hiding the complexity of legacy systems.
Facade facade = new Facade();
facade.methodA();
facade.methodB();
}
}
6、享元模式
享元模式,运用共享技术有效地支持大量细粒度的对象。
import java.util.HashMap;
import java.util.Map;
// FlyWeight base class, accepting and acting on external state
interface FlyWeight {
void operation(int extrinsicState);
}
// ConcreteFlyWeight class implements FlyWeight
class ConcreteFlyWeight implements FlyWeight {
public void operation(int extrinsicState) {
System.out.println("Concrete FlyWeight: " + extrinsicState);
}
}
// UnsharedConcreteFlyWeight class implements FlyWeight
class UnsharedConcreteFlyWeight implements FlyWeight {
public void operation(int extrinsicState) {
System.out.println("Unshared Concrete FlyWeight: " + extrinsicState);
}
}
// FlyWeightFactory class responsible for managing FlyWeight objects
class FlyWeightFactory {
private Map<String, FlyWeight> flyWeights = new HashMap<>();
public FlyWeight getFlyWeight(String key) {
// If the FlyWeight with the given key does not exist, create it
if (!flyWeights.containsKey(key)) {
flyWeights.put(key, new ConcreteFlyWeight());
}
return flyWeights.get(key);
}
}
// Client code to use FlyWeightFactory
public class Main {
public static void main(String[] args) {
int extrinsicState = 22;
FlyWeightFactory factory = new FlyWeightFactory();
// Get and use shared FlyWeight objects
FlyWeight fx = factory.getFlyWeight("X");
fx.operation(--extrinsicState);
FlyWeight fy = factory.getFlyWeight("Y");
fy.operation(--extrinsicState);
FlyWeight fz = factory.getFlyWeight("Z");
fz.operation(--extrinsicState);
// Get and use a non-shared FlyWeight object
FlyWeight uf = new UnsharedConcreteFlyWeight();
uf.operation(--extrinsicState);
}
}
7、代理模式
代理模式,为其他对象提供一种代理以控制对这个对象的访问。
// Subject interface shared by both RealSubject and Proxy
interface Subject {
void request();
}
// RealSubject class that implements the Subject interface
class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject's request");
}
}
// Proxy class that implements the Subject interface and uses RealSubject
class Proxy implements Subject {
private Subject subject;
public Proxy() {
subject = new RealSubject();
}
public void request() {
subject.request();
}
}
// Client code to use Proxy and RealSubject
public class Main {
public static void main(String[] args) {
// Create Proxy object, which will delegate request to RealSubject
Proxy proxy = new Proxy();
proxy.request(); // This will call RealSubject's request
}
}
三、行为型模式
1、解释器模式
解释器模式,给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
import java.util.ArrayList;
import java.util.List;
// Context class, holds the global information
class Context {
private String input;
private String output;
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
}
// AbstractExpression class, declares the interpret method
abstract class AbstractExpression {
public abstract void interpret(Context context);
}
// TerminalExpression class, represents terminal symbols in the grammar
class TerminalExpression extends AbstractExpression {
@Override
public void interpret(Context context) {
System.out.println("Terminal Interpreter");
}
}
// NonTerminalExpression class, represents non-terminal symbols in the grammar
class NonTerminalExpression extends AbstractExpression {
@Override
public void interpret(Context context) {
System.out.println("Non-terminal Interpreter");
}
}
// InterpreterClient (Client code)
public class Main {
public static void main(String[] args) {
Context context = new Context();
// Create a list of AbstractExpressions
List<AbstractExpression> list = new ArrayList<>();
// Add different types of expressions to the list
list.add(new TerminalExpression());
list.add(new NonTerminalExpression());
list.add(new TerminalExpression());
list.add(new TerminalExpression());
// Interpret each expression
for (AbstractExpression expression : list) {
expression.interpret(context);
}
}
}
2、模板方法模式
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
// AbstractTemplate class: Defines the template method and abstract operations
abstract class AbstractTemplate {
// Abstract method 1
public abstract void primitiveOperation1();
// Abstract method 2
public abstract void primitiveOperation2();
// Template method: Defines the structure of the algorithm
public final void templateMethod() {
primitiveOperation1();
primitiveOperation2();
System.out.println("Template Method Finished");
}
}
// ConcreteClassA: Implements the abstract operations for Class A
class ConcreteClassA extends AbstractTemplate {
@Override
public void primitiveOperation1() {
System.out.println("ConcreteClassA Method 1 Implementation");
}
@Override
public void primitiveOperation2() {
System.out.println("ConcreteClassA Method 2 Implementation");
}
}
// ConcreteClassB: Implements the abstract operations for Class B
class ConcreteClassB extends AbstractTemplate {
@Override
public void primitiveOperation1() {
System.out.println("ConcreteClassB Method 1 Implementation");
}
@Override
public void primitiveOperation2() {
System.out.println("ConcreteClassB Method 2 Implementation");
}
}
// TemplateClient (Client code)
public class Main {
public static void main(String[] args) {
// Create instances of ConcreteClassA and ConcreteClassB
AbstractTemplate abstractTemplate;
abstractTemplate = new ConcreteClassA();
abstractTemplate.templateMethod();
abstractTemplate = new ConcreteClassB();
abstractTemplate.templateMethod();
}
}
3、策略模式
场景:商场促销。简单工厂模式虽然也能解决这个问题,但这个模式只是解决对象的创建问题,而且由于工厂本身包括了所有的收费方式,商场是可能经常性地更改打折额度和返利额度,每次维护或扩展收费方式都要改动这个工厂。所以它不是最好的办法。
面对算法的时常变动,应该有更好的办法。
策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
// Strategy Interface: Defines the algorithm interface
interface Strategy {
void algorithmInterface();
}
// ConcreteStrategyA: Implements the algorithm for Strategy A
class ConcreteStrategyA implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("Concrete implementation of Strategy A");
}
}
// ConcreteStrategyB: Implements the algorithm for Strategy B
class ConcreteStrategyB implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("Concrete implementation of Strategy B");
}
}
// ConcreteStrategyC: Implements the algorithm for Strategy C
class ConcreteStrategyC implements Strategy {
@Override
public void algorithmInterface() {
System.out.println("Concrete implementation of Strategy C");
}
}
// Context: Holds a reference to a strategy and calls the strategy's algorithm
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
// Context Interface
public void contextInterface() {
strategy.algorithmInterface();
}
}
// StrategyClient (Client code)
public class Main {
public static void main(String[] args) {
// Create contexts with different strategies
Strategy strategyA = new ConcreteStrategyA();
Context contextA = new Context(strategyA);
contextA.contextInterface();
Strategy strategyB = new ConcreteStrategyB();
Context contextB = new Context(strategyB);
contextB.contextInterface();
Strategy strategyC = new ConcreteStrategyC();
Context contextC = new Context(strategyC);
contextC.contextInterface();
}
}
4、观察者模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
import java.util.ArrayList;
import java.util.List;
// 抽象观察者
interface Observer {
void update();
}
// 抽象主题(通知者)
class Subject {
protected List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
// 具体主题(通知者)
class ConcreteSubject extends Subject {
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String state) {
subjectState = state;
}
}
// 具体观察者
class ConcreteObserver implements Observer {
private String name;
private String observerState;
private ConcreteSubject concreteSubject;
public ConcreteObserver(ConcreteSubject subject, String name) {
this.concreteSubject = subject;
this.name = name;
}
@Override
public void update() {
observerState = concreteSubject.getSubjectState();
System.out.println("Observer " + name + "'s new state is: " + observerState);
}
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
public String getObserverState() {
return observerState;
}
public void setObserverState(String newState) {
observerState = newState;
}
public ConcreteSubject getConcreteSubject() {
return concreteSubject;
}
public void setConcreteSubject(ConcreteSubject subject) {
concreteSubject = subject;
}
}
// 观察者模式客户端
public class Main {
public static void main(String[] args) {
ConcreteSubject concreteSubject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver(concreteSubject, "X");
ConcreteObserver observer2 = new ConcreteObserver(concreteSubject, "Y");
ConcreteObserver observer3 = new ConcreteObserver(concreteSubject, "Z");
concreteSubject.attach(observer1);
concreteSubject.attach(observer2);
concreteSubject.attach(observer3);
concreteSubject.setSubjectState("ABC");
concreteSubject.notifyObservers();
}
}
5、状态模式
状态模式,当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
// 抽象状态类
interface State {
void handle(Context context);
}
// Context 类,维护一个 ConcreteState 子类的实例
class Context {
private State state;
public Context(State initialState) {
state = initialState;
}
public State getState() {
return state;
}
public void setState(State newState) {
state = newState;
}
public void request() {
state.handle(this);
}
}
// 具体状态 A
class ConcreteStateA implements State {
@Override
public void handle(Context context) {
System.out.println("Now in state A");
context.setState(new ConcreteStateB()); // 切换到状态B
}
}
// 具体状态 B
class ConcreteStateB implements State {
@Override
public void handle(Context context) {
System.out.println("Now in state B");
context.setState(new ConcreteStateC()); // 切换到状态C
}
}
// 具体状态 C
class ConcreteStateC implements State {
@Override
public void handle(Context context) {
System.out.println("Now in state C");
context.setState(new ConcreteStateA()); // 切换到状态A
}
}
// 客户端:不断请求,不断更改状态
public class Main {
public static void main(String[] args) {
// 初始化状态为 ConcreteStateA
Context context = new Context(new ConcreteStateA());
// 模拟请求,不断转换状态
context.request(); // 当前状态为 A,切换到 B
context.request(); // 当前状态为 B,切换到 C
context.request(); // 当前状态为 C,切换到 A
context.request(); // 当前状态为 A,切换到 B
context.request(); // 当前状态为 B,切换到 C
}
}
6、备忘录模式
备忘录:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
// 发起人(Originator)类
class Originator {
private String state;
// 创建备忘录
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 创建备忘录
public Memento createMemento() {
return new Memento(this.state);
}
// 恢复备忘录中的状态
public void recoverMemento(Memento memento) {
this.state = memento.getState();
}
// 显示当前状态
public void show() {
System.out.println("state = " + this.state);
}
// 设置状态
public void setState(String state) {
this.state = state;
}
// 获取当前状态
public String getState() {
return state;
}
}
// 管理者(CareTaker)类
class CareTaker {
private Originator.Memento memento;
// 获取备忘录
public Originator.Memento getMemento() {
return memento;
}
// 设置备忘录
public void setMemento(Originator.Memento memento) {
this.memento = memento;
}
}
// 客户端
public class Main {
public static void main(String[] args) {
// 设置初始状态
Originator originator = new Originator();
originator.setState("On");
originator.show();
// 管理者通过备忘录保存状态
CareTaker careTaker = new CareTaker();
careTaker.setMemento(originator.createMemento());
// 改变状态
originator.setState("Off");
originator.show();
// 通过管理者从备忘录中恢复状态
originator.recoverMemento(careTaker.getMemento());
originator.show();
}
}
7、迭代器模式
迭代器模式,提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
import java.util.ArrayList;
import java.util.List;
// 迭代器接口
interface Iterator<T> {
T first();
T next();
boolean isDone();
T currentItem();
}
// 聚集接口
interface Aggregate<T> {
Iterator<T> createIterator();
}
// 具体聚集类
class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> items = new ArrayList<>();
// 创建迭代器
@Override
public Iterator<T> createIterator() {
return new ConcreteIterator<>(this);
}
public int count() {
return items.size();
}
public T getItem(int index) {
return items.get(index);
}
public void addItem(T item) {
items.add(item);
}
}
// 具体迭代器类
class ConcreteIterator<T> implements Iterator<T> {
private ConcreteAggregate<T> aggregate;
private int current = 0;
public ConcreteIterator(ConcreteAggregate<T> aggregate) {
this.aggregate = aggregate;
}
@Override
public T first() {
return aggregate.getItem(0);
}
@Override
public T next() {
current++;
if (current < aggregate.count()) {
return aggregate.getItem(current);
}
return null; // 返回null表示迭代完成
}
@Override
public boolean isDone() {
return current >= aggregate.count();
}
@Override
public T currentItem() {
return aggregate.getItem(current);
}
}
// 迭代器客户端
public class Main {
public static void main(String[] args) {
ConcreteAggregate<String> bus = new ConcreteAggregate<>();
// 添加乘客
bus.addItem("Big Bird");
bus.addItem("Small Dish");
bus.addItem("Luggage");
bus.addItem("Foreigner");
bus.addItem("Bus Internal Staff");
bus.addItem("Thief");
Iterator<String> iterator = bus.createIterator();
while (!iterator.isDone()) {
System.out.println(iterator.currentItem() + " please buy a ticket!");
iterator.next();
}
}
}
8、命令模式
命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以 及支持可撤销的操作。
import java.util.ArrayList;
import java.util.List;
// 接收者接口
interface Receiver {
void action();
}
class ReceiverA implements Receiver {
@Override
public void action() {
System.out.println("ReceiverA execute the request!");
}
}
class ReceiverB implements Receiver {
@Override
public void action() {
System.out.println("ReceiverB execute the request!");
}
}
class ReceiverC implements Receiver {
@Override
public void action() {
System.out.println("ReceiverC execute the request!");
}
}
// 命令接口
interface Command {
void execute();
void addReceiver(Receiver receiver);
}
// 具体命令类
class ConcreteCommand implements Command {
private List<Receiver> receivers = new ArrayList<>();
public ConcreteCommand(List<Receiver> receivers) {
this.receivers = receivers;
}
@Override
public void execute() {
for (Receiver receiver : receivers) {
receiver.action();
}
}
@Override
public void addReceiver(Receiver receiver) {
receivers.add(receiver);
}
}
// 调用者类
class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
}
// 客户端
public class Main {
public static void main(String[] args) {
List<Receiver> receivers = new ArrayList<>();
receivers.add(new ReceiverA());
receivers.add(new ReceiverB());
receivers.add(new ReceiverC());
Command command = new ConcreteCommand(receivers);
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.executeCommand();
}
}
9、责任链模式
责任链模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
import java.util.ArrayList;
import java.util.List;
// 处理请求的接口
abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(int request);
}
// 具体处理者A
class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request <= 10) {
System.out.println(this.getClass().getSimpleName() + " processed the request " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者B
class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request > 10 && request <= 20) {
System.out.println(this.getClass().getSimpleName() + " processed the request " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者C
class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request > 20 && request <= 30) {
System.out.println(this.getClass().getSimpleName() + " processed the request " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 客户端
public class Main {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
handlerA.setSuccessor(handlerB);
handlerB.setSuccessor(handlerC);
List<Integer> requests = new ArrayList<>();
requests.add(2);
requests.add(14);
requests.add(5);
requests.add(6);
requests.add(8);
requests.add(23);
requests.add(12);
requests.add(21);
for (int request : requests) {
handlerA.handleRequest(request);
}
}
}
10、中介者模式
中介者模式,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
// 抽象中介者类
interface Mediator {
void send(String message, Colleague colleague);
}
// 抽象同事类
abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void sendMsg(String message);
public abstract void notifyMsg(String message);
}
// 具体同事类1
class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
@Override
public void sendMsg(String message) {
mediator.send(message, this);
}
@Override
public void notifyMsg(String message) {
System.out.println("Colleague 1 got the message: " + message);
}
}
// 具体同事类2
class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
@Override
public void sendMsg(String message) {
mediator.send(message, this);
}
@Override
public void notifyMsg(String message) {
System.out.println("Colleague 2 got the message: " + message);
}
}
// 具体中介者类
class ConcreteMediator implements Mediator {
private ConcreteColleague1 c1;
private ConcreteColleague2 c2;
public void setC1(ConcreteColleague1 colleague) {
c1 = colleague;
}
public void setC2(ConcreteColleague2 colleague) {
c2 = colleague;
}
@Override
public void send(String message, Colleague colleague) {
if (colleague == c1) {
c2.notifyMsg(message);
} else {
c1.notifyMsg(message);
}
}
}
// 客户端
public class Main {
public static void main(String[] args) {
// 创建中介者
ConcreteMediator concreteMediator = new ConcreteMediator();
// 创建具体同事类对象并让它们知道中介者
ConcreteColleague1 concreteColleague1 = new ConcreteColleague1(concreteMediator);
ConcreteColleague2 concreteColleague2 = new ConcreteColleague2(concreteMediator);
// 让中介者知道具体同事类对象
concreteMediator.setC1(concreteColleague1);
concreteMediator.setC2(concreteColleague2);
// 发送消息
concreteColleague1.sendMsg("Have you eaten?");
concreteColleague2.sendMsg("No, are you planning to treat us?");
}
}
11、访问者模式
访问者模式,表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
import java.util.ArrayList;
import java.util.List;
// 抽象元素类
abstract class Element {
public abstract void accept(Visitor visitor);
public abstract String getName();
}
// 抽象访问者类
interface Visitor {
void visitConcreteElementA(ConcreteElementA concreteElementA);
void visitConcreteElementB(ConcreteElementB concreteElementB);
}
// 具体元素A
class ConcreteElementA extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElementA(this);
}
@Override
public String getName() {
return "ConcreteElementA";
}
}
// 具体元素B
class ConcreteElementB extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElementB(this);
}
@Override
public String getName() {
return "ConcreteElementB";
}
}
// 具体访问者1
class ConcreteVisitor1 implements Visitor {
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println(concreteElementA.getName() + " be " + getName() + " Visited");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println(concreteElementB.getName() + " be " + getName() + " Visited");
}
public String getName() {
return "ConcreteVisitor1";
}
}
// 具体访问者2
class ConcreteVisitor2 implements Visitor {
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println(concreteElementA.getName() + " be " + getName() + " Visited");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println(concreteElementB.getName() + " be " + getName() + " Visited");
}
public String getName() {
return "ConcreteVisitor2";
}
}
// 对象结构类
class ObjectStructure {
private List<Element> elements = new ArrayList<>();
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);
}
}
}
// 客户端
public class Main {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.attach(new ConcreteElementA());
objectStructure.attach(new ConcreteElementB());
ConcreteVisitor1 visitor1 = new ConcreteVisitor1();
ConcreteVisitor2 visitor2 = new ConcreteVisitor2();
System.out.println("Use visitor 1 to access the elements:");
objectStructure.accept(visitor1);
System.out.println("\nUse visitor 2 to access the elements:");
objectStructure.accept(visitor2);
}
}
提示:更多内容可以访问Clang’s Blog:https://www.clang.asia