最近在读秦小波的《设计模式之禅》。本文又是一篇长达2000行的又水又长的笔记,记录书中所讲23个设计模式中的22个,基本上是将书中讲的各个设计模式的定义、优点、缺点、适用场景、demo抄下来了。推荐去阅读原书,这是一位学识丰富且有一个有趣的灵魂的作者所写,原书中每个设计模式的讲解都有一个十分有趣的例子,借助这些例子可以很好的加深理解和记忆。
设计模式感觉都是相通的,之前看过一本《JavaScript设计模式与开发实践》,其实都是讲的一回事,只是因为语言特性原因在实现方面有所区别,这本书的作者也有一个有趣的灵魂,我现在都还记得代理模式中“小明追美眉”的故事,也推荐阅读。
定义:
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
示例:
public class Singleton {
private static Singleton singleton = new Singleton();
// 私有化构造
private Singleton() {
}
// 获取实例
public static Singleton getInstance() {
return singleton;
}
// 类中其他方法尽量是static的
public static void otherMethod() {
}
}
优点:
缺点:
适用场景:
定义:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类
示例:
/**
* 抽象产品
*/
public abstract class Product {
public void method1() {
System.out.println("method1");
}
abstract public void method2();
}
/**
* 具体的一个产品
*/
public class ProductA extends Product {
public void method2() {
System.out.println("productA method2");
}
}
/**
* 具体的一个产品
*/
public class ProductB extends Product {
public void method2() {
System.out.println("productB method2");
}
}
/**
* 抽象工厂
*/
public abstract class Factory {
public abstract <T extends Product> T createProduct(Class<T> clazz);
}
/**
* 具体工厂
*/
public class ProductFactory1 extends Factory {
public <T extends Product> T createProduct(Class<T> clazz) {
Product product = null;
try {
product = (Product) Class.forName(clazz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) product;
}
}
/**
* 测试类
*/
public class FactoryTest {
@Test
public void test() {
Factory factory = new ProductFactory1();
ProductA productA = factory.createProduct(ProductA.class);
ProductB productB = factory.createProduct(ProductB.class);
productA.method2();
productB.method2();
}
}
优点:
使用场景:
工厂模式扩展:
/**
* 静态工厂
*/
public class ProductFactory2 {
private ProductFactory2() {
}
static Product createProduct(Class<Product> clazz) {
Product product = null;
try {
product = (Product) Class.forName(clazz.getName()).newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return product;
}
}
多工厂模式
实现单例模式
延迟初始化
定义:
为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类
示例:
public class Factory {
public ProductA createProductA() {
return new ProductA();
}
public ProductB createProductB() {
return new ProductB();
}
}
优点:
缺点:
适用场景:
一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。就是一堆类有相同的父类
定义:
定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
示例:
/**
* 模板类
*/
public abstract class TemplateClass {
protected abstract void method1();
protected abstract void method2();
/**
* 模板方法
*/
public void templateMethod() {
method1();
method2();
}
}
/**
* 根据模板类创建的类
*/
public class TemplateSubClass1 extends TemplateClass {
protected void method1() {
System.out.println("1 method1");
}
protected void method2() {
System.out.println("1 method2");
}
}
/**
* 根据模板类创建的类
*/
public class TemplateSubClass2 extends TemplateClass {
protected void method1() {
System.out.println("2 method1");
}
protected void method2() {
System.out.println("2 method2");
}
}
/**
* 测试类
*/
public class TemplateTest {
@Test
public void test() {
TemplateSubClass1 templateSubClass1 = new TemplateSubClass1();
templateSubClass1.templateMethod();
TemplateSubClass2 templateSubClass2 = new TemplateSubClass2();
templateSubClass2.templateMethod();
}
}
优点:
缺点:
子类对父类产生了影响,在复杂的项目中,会带来代码阅读的难度,会让新手难以适应
适用场景:
多个子类有公有的方法,并且逻辑基本相同
模板方法模式扩展:
可以通过定义开关的形式,调整模板方法的执行流程
定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
示例:
public class Product {
private String name;
private int price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
public class ProductBuilder {
private Product product = new Product();
public void buildName(String name) {
product.setName(name);
}
public void buildPrice(Integer price) {
product.setPrice(price);
}
public Product create() {
return product;
}
}
优点:
缺点:
适用场景:
定义:
为其他对象提供一种代理以控制对这个对象的访问
示例:
/**
* 被代理类接口
*/
public interface Subject {
void doSomething();
}
/**
* 真实被代理类
*/
public class RealSubject implements Subject {
public void doSomething() {
System.out.println("RealSubject doSomething");
}
}
/**
* 代理类
*/
public class SubjectProxy implements Subject {
private Subject subject = null;
public SubjectProxy() {
this.subject = new RealSubject();
}
public void doSomething() {
System.out.println("doSomething 被代理了");
this.subject.doSomething();
}
}
/**
* 测试类
*/
public class SubjectProxyTest {
@Test
public void test() {
SubjectProxy subjectProxy = new SubjectProxy();
subjectProxy.doSomething();
}
}
优点:
适用场景:
代理模式扩展:
就是示例那个,调用方知道代理的存在(类似正向代理)
调用方不知道代理的存在(类似反向代理)
/**
* 真实被代理类
*/
public class RealSubject implements Subject {
public RealSubject(Subject subject) throws ClassNotFoundException {
// 注意这里
if (subject == null) {
throw new ClassNotFoundException();
}
}
public void doSomething() {
System.out.println("RealSubject doSomething");
}
}
/**
* 代理类
*/
public class SubjectProxy implements Subject {
private Subject subject = null;
public SubjectProxy() {
// 注意这里
try {
this.subject = new RealSubject(this);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void doSomething() {
System.out.println("doSomething 被代理了");
this.subject.doSomething();
}
}
/***
* 测试类
*/
public class ProxyTest {
@Test
public void test() {
SubjectProxy subjectProxy = new SubjectProxy();
subjectProxy.doSomething();
}
@Test
public void test2() throws ClassNotFoundException {
// 会报错的
// RealSubject realSubject = new RealSubject();
// realSubject.doSomething();
}
}
必须通过真实角色查找到代理角色,否则你不能访问
感觉意义不是太大
动态代理是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象
/**
* 通知接口
*/
public interface Advice {
public void exec();
}
/**
* 通知类
*/
public class BeforeAdvice implements Advice {
public void exec() {
System.out.println("前置通知执行了");
}
}
/**
* 动态代理的handler
*/
public class MyInvocationHandler implements InvocationHandler {
// 被代理对象
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 寻找JoinPoint连结点
if (true) {
new BeforeAdvice().exec();
}
// 执行被代理的方法
return method.invoke(this.target, args);
}
}
/**
* 动态代理类
*/
public class SubjectDynamicProxy {
public static Subject newInstance(Subject subject) {
ClassLoader classLoader = subject.getClass().getClassLoader();
Class<?>[] interfaces = subject.getClass().getInterfaces();
InvocationHandler invocationHandler = new MyInvocationHandler(subject);
return (Subject) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
}
}
/**
* 测试类
*/
public class ProxyTest {
@Test
public void test() {
Subject subject = new RealSubject();
Subject proxySubject = SubjectDynamicProxy.newInstance(subject);
proxySubject.doSomething();
}
}
使用jdk的动态代理要求被代理类必须实现一个接口,CGLIB动态代理没有这个要求。
spring 的aop就是使用的动态代理技术实现的
定义:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。即基于对象创建对象,而不是类
示例:
public class Prototype implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Prototype clone() throws CloneNotSupportedException {
// 关键就是这个东西
return (Prototype) super.clone();
}
}
优点:
适用场景:
注意点:
定义:
用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互
示例:
/**
* 同事抽象类
*/
public abstract class Colleagure {
protected Mediator mediator;
public Colleagure(Mediator mediator) {
this.mediator = mediator;
}
}
/**
* 具体同事类
*/
public class ConcreteColleagure1 extends Colleagure {
public ConcreteColleagure1(Mediator mediator) {
super(mediator);
}
public void selfMethod1() {
System.out.println("ConcreteColleagure1 自己的业务逻辑");
}
public void depMethod1() {
// 依赖其他对象的逻辑,给中介者处理
super.mediator.doSomething1();
}
}
/**
* 具体同事类
*/
public class ConcreteColleagure2 extends Colleagure {
public ConcreteColleagure2(Mediator mediator) {
super(mediator);
}
public void selfMethod1() {
System.out.println("ConcreteColleagure2 自己的业务逻辑");
}
public void depMethod1() {
// 依赖其他对象的逻辑,给中介者处理
super.mediator.doSomething2();
}
}
/**
* 抽象中介者
*/
public abstract class Mediator {
protected ConcreteColleagure1 concreteColleagure1;
protected ConcreteColleagure2 concreteColleagure2;
public abstract void doSomething1();
public abstract void doSomething2();
public ConcreteColleagure1 getConcreteColleagure1() {
return concreteColleagure1;
}
public void setConcreteColleagure1(ConcreteColleagure1 concreteColleagure1) {
this.concreteColleagure1 = concreteColleagure1;
}
public ConcreteColleagure2 getConcreteColleagure2() {
return concreteColleagure2;
}
public void setConcreteColleagure2(ConcreteColleagure2 concreteColleagure2) {
this.concreteColleagure2 = concreteColleagure2;
}
}
/**
* 具体中介者
*/
public class ConcreteMediator extends Mediator {
public void doSomething1() {
super.concreteColleagure1.selfMethod1();
super.concreteColleagure2.selfMethod1();
}
public void doSomething2() {
super.concreteColleagure2.selfMethod1();
super.concreteColleagure1.selfMethod1();
}
}
/**
* 测试类
*/
public class MediatorTest {
@Test
public void test() {
Mediator mediator = new ConcreteMediator();
ConcreteColleagure2 concreteColleagure2 = new ConcreteColleagure2(mediator);
ConcreteColleagure1 concreteColleagure1 = new ConcreteColleagure1(mediator);
mediator.setConcreteColleagure1(concreteColleagure1);
mediator.setConcreteColleagure2(concreteColleagure2);
concreteColleagure1.depMethod1();
concreteColleagure2.depMethod1();
}
}
优点:
中介者模式的优点就是减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,实现了解耦
适用场景:
定义:
将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能
示例:
/**
* 抽象接收者
*/
public abstract class Recevier {
public abstract void doSomething();
}
/**
* 具体的接收者
*/
public class ConcreteRecevier1 extends Recevier {
public void doSomething() {
System.out.println("ConcreteRecevier1 业务逻辑");
}
}
/**
* 具体的接收者
*/
public class ConcreteRecevier2 extends Recevier {
public void doSomething() {
System.out.println("ConcreteRecevier2 业务逻辑");
}
}
/**
* 抽象命令类
*/
public abstract class Command {
public abstract void execute();
}
/**
* 具体命令类
*/
public class ConcreteCommand1 extends Command {
Recevier recevier;
public ConcreteCommand1(Recevier recevier) {
this.recevier = recevier;
}
public ConcreteCommand1() {
this(new ConcreteRecevier1());
}
public void execute() {
recevier.doSomething();
}
}
/**
* 具体命令类
*/
public class ConcreteCommand2 extends Command {
Recevier recevier;
public ConcreteCommand2(Recevier recevier) {
this.recevier = recevier;
}
public ConcreteCommand2() {
this(new ConcreteRecevier2());
}
public void execute() {
recevier.doSomething();
}
}
/**
* 调用者
*/
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void action() {
this.command.execute();
}
}
/**
* 测试类
*/
public class CommandTest {
@Test
public void test() {
Command command = new ConcreteCommand1();
Command command1 = new ConcreteCommand2();
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.action();
invoker.setCommand(command1);
invoker.action();
}
}
优点:
缺点:
定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止
示例:
/**
* 处理级别
*/
public enum Level {
LEVEL1(1, "级别1"),
LEVEL2(2, "级别2"),
LEVEL3(3, "级别3");
private int code;
private String msg;
private Level(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
/**
* 请求封装
*/
public class Request {
Level level;
public Request(Level level) {
this.level = level;
}
public Level getRequestLevel() {
return this.level;
}
}
/**
* 响应封装
*/
public class Response {
private int code;
private String msg;
public Response(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
/**
* 处理请求抽象
*/
public abstract class Handler {
private Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public final Response handleMessage(Request request) {
Response response = null;
if (this.getHandleLevel().getCode() == request.getRequestLevel().getCode()) {
// 自己处理
response = this.doRequest(request);
} else {
if (this.nextHandler != null) {
// 交给下一个人处理
response = this.nextHandler.handleMessage(request);
} else {
response = new Response(-1, "无人处理");
}
}
return response;
}
// 获取当前处理者能够处理的级别
protected abstract Level getHandleLevel();
// 处理请求
protected abstract Response doRequest(Request request);
}
/**
* 具体处理请求的类
*/
public class Level1Handler extends Handler {
protected Level getHandleLevel() {
return Level.LEVEL1;
}
protected Response doRequest(Request request) {
return new Response(1, "第一个级别在Level1Handler处理了");
}
}
public class Level2Handler extends Handler {
protected Level getHandleLevel() {
return Level.LEVEL2;
}
protected Response doRequest(Request request) {
return new Response(1, "第2个级别在Level2Handler处理了");
}
}
public class Level3Handler extends Handler {
protected Level getHandleLevel() {
return Level.LEVEL3;
}
protected Response doRequest(Request request) {
return new Response(1, "第2个级别在Level3Handler处理了");
}
}
/**
* 测试类
*/
public class RequestChainTest {
@Test
public void test() {
Level1Handler level1Handler = new Level1Handler();
Level2Handler level2Handler = new Level2Handler();
Level3Handler level3Handler = new Level3Handler();
level1Handler.setNextHandler(level2Handler);
level2Handler.setNextHandler(level3Handler);
Response response = level1Handler.handleMessage(new Request(Level.LEVEL2));
System.out.println(response.getCode());
System.out.println(response.getMsg());
}
}
优点:
定义:
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活
示例:
/**
* 被装饰类的抽象
*/
public abstract class Component {
public abstract void doSomething();
}
/**
* 具体被装饰者
*/
public class ConcreteComponent extends Component {
public void doSomething() {
System.out.println("被装饰类的方法");
}
}
/**
* 装饰类
*/
public class Decorator extends Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void doSomething() {
this.component.doSomething();
}
public void newMethod() {
System.out.println("新增一个方法");
}
}
优点:
缺点:
多层的装饰是比较复杂的
适用场景:
定义:
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换
示例:
/**
* 策略接口
*/
public interface Strategy {
void doSomething();
}
/**
* 具体的策略
*/
public class Strategy1 implements Strategy {
public void doSomething() {
System.out.println("第一种策略");
}
}
/**
* 具体的策略
*/
public class Strategy2 implements Strategy {
public void doSomething() {
System.out.println("第一种策略");
}
}
/**
* 封装策略
*/
public class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void execute() {
this.strategy.doSomething();
}
}
/**
* 测试类
*/
public class StrategyTest {
@Test
public void test() {
Context context = new Context();
context.setStrategy(new Strategy1());
context.execute();
}
}
优点:
缺点:
适用场景:
定义:
将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作
示例:
/**
* 目标角色
*/
public interface Target {
void request();
}
/**
* 源角色
*/
public class Adaptee {
public void doAnyThing() {
System.out.println("doAnyThing");
}
}
/**
* 适配器角色
*/
public class Atapter extends Adaptee implements Target {
public void request() {
super.doAnyThing();
}
}
优点:
适用场景:
当要改一个已经在生产中适用的类时可以考虑
定义:
它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节
示例:
很多集合类都实现了Iterable接口,就是迭代器模式
优点:
遍历方便,隐藏内部细节
定义:
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性
示例:
/**
* 抽象构件
*/
public abstract class Component {
public void doSomething() {
System.out.println("一些业务逻辑");
}
}
/**
* 树枝
*/
public class Composite extends Component {
/**
* 子节点容器
*/
private ArrayList<Component> componentArrayList = new ArrayList<Component>();
// 加节点
public void add(Component component) {
this.componentArrayList.add(component);
}
// 删节点
public void remove(Component component) {
this.componentArrayList.remove(component);
}
// 获取子节点
public ArrayList<Component> getChildren() {
return this.componentArrayList;
}
}
public class Leaf extends Component {
@Override
public void doSomething() {
System.out.println("叶子");
super.doSomething();
}
}
/**
* 测试类
*/
public class CompositeTest {
@Test
public void test() {
Composite root = new Composite();
root.doSomething();
Composite branch = new Composite();
Leaf leaf = new Leaf();
root.add(branch);
branch.add(leaf);
display(root);
}
private void display(Composite root) {
for (Component component1 : root.getChildren()) {
if (component1 instanceof Leaf) {
component1.doSomething();
} else {
display((Composite) component1);
}
}
}
}
优点:
适用场景:
维护和展示部分-整体关系的场景
从一个整体中能够独立出部分模块或功能的场景
定义:
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
示例:
/**
* 观察者接口
*/
public interface Observer {
// 更新
void update(Object object);
}
/**
* 具体的观察者
*/
public class ConcreteObserver implements Observer {
public void update(Object object) {
System.out.println("收到了通知"+object.toString());
}
}
/**
* 被观察者抽象类
*/
public abstract class Subject {
private ArrayList<Observer> observers = new ArrayList<Observer>();
public void addObserver(Observer observer) {
this.observers.add(observer);
}
public void removeObserver(Observer observer) {
this.observers.remove(observer);
}
public void notifyObservers(Object object) {
for (Observer observer : this.observers) {
observer.update(object);
}
}
}
/**
* 具体的被观察者
*/
public class ConcreteSubject extends Subject {
public void doSomething() {
super.notifyObservers("doSomething");
}
}
/**
* 测试类
*/
public class ObserverTest {
@Test
public void test() throws InterruptedException {
Observer observer = new ConcreteObserver();
ConcreteSubject subject = new ConcreteSubject();
subject.addObserver(observer);
Thread.sleep(1000);
subject.doSomething();
}
}
优点:
缺点:
适用场景:
定义:
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用
示例:
/**
* 子系统
*/
public class SubSystemA {
public void doSomethingA() {
System.out.println("doSomethingA");
}
}
/**
* 子系统
*/
public class SubSystemB {
public void doSomethingB() {
System.out.println("doSomethingB");
}
}
/**
* 子系统
*/
public class SubSystemC {
public void doSomethingC() {
System.out.println("doSomethingC");
}
}
/**
* 门面
*/
public class Facade {
private SubSystemA subSystemA = new SubSystemA();
private SubSystemB subSystemB = new SubSystemB();
private SubSystemC subSystemC = new SubSystemC();
public void methodA() {
subSystemA.doSomethingA();
}
public void methodB() {
subSystemB.doSomethingB();
}
public void methodC() {
subSystemC.doSomethingC();
}
}
优点:
缺点:
适用场景:
定义:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
示例:
/**
* 发起人角色
*/
public class Originator {
private String state; // 内部状态
public Originator() {
}
public Originator(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
// 创建备忘录
public Memento createMemento() {
return new Memento(this.state);
}
// 恢复备忘录
public void restoreMemento(Memento memento) {
this.setState(memento.getState());
}
public void changeState(String state) {
this.setState(state);
}
}
/**
* 备忘录
*/
public class Memento {
private String state; // 发起人内部状态
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
/**
* 备忘录管理员角色
*/
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
/**
* 测试类
*/
public class MementoTest {
@Test
public void test() {
Originator originator = new Originator("1");
System.out.println(originator.getState());
Caretaker caretaker = new Caretaker();
caretaker.setMemento(originator.createMemento());
originator.changeState("3");
System.out.println(originator.getState());
originator.restoreMemento(caretaker.getMemento());
System.out.println(originator.getState());
}
}
适用场景:
定义:
封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作
示例:
/**
* 访问者接口
*/
public interface IVisitor {
void visit(ConcreteElement1 concreteElement1);
void visit(ConcreteElement2 concreteElement2);
}
/**
* 具体的访问者
*/
public class Visitor implements IVisitor {
public void visit(ConcreteElement1 concreteElement1) {
concreteElement1.doSomething();
}
public void visit(ConcreteElement2 concreteElement2) {
concreteElement2.doSomething();
}
}
/**
* 抽象元素
*/
public abstract class Element {
public abstract void doSomething(); // 业务逻辑
public abstract void accept(IVisitor visitor); // 允许谁访问
}
/**
* 具体元素
*/
public class ConcreteElement1 extends Element {
public void doSomething() {
System.out.println("element1 业务逻辑");
}
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
/**
* 具体元素
*/
public class ConcreteElement2 extends Element {
public void doSomething() {
System.out.println("element2 业务逻辑");
}
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
/**
* 结构对象
*/
public class ObjectStructure {
public static Element createElement() {
Random random = new Random();
if(random.nextInt(100) < 50) {
return new ConcreteElement1();
} else {
return new ConcreteElement2();
}
}
}
/**
* 测试类
*/
public class VisitorTest {
@Test
public void test() {
for (int i = 0; i < 10; i++) {
Element e = ObjectStructure.createElement();
e.accept(new Visitor());
}
}
}
优点:
缺点:
适用场景:
业务规则要求遍历多个不同的对象
定义:
当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类
示例:
/**
* 状态抽象类
*/
public abstract class State {
protected Context context;
public void setContext(Context context) {
this.context = context;
}
// 行为1
public abstract void handle1();
// 行为2
public abstract void hanle2();
}
/**
* 具体状态
*/
public class State1 extends State {
public void handle1() {
}
public void hanle2() {
super.context.setCurrentState(Context.STATE2);
System.out.println("在状态1可以执行 handle2");
}
}
/**
* 具体状态
*/
public class State2 extends State {
public void handle1() {
super.context.setCurrentState(Context.STATE1);
System.out.println("在状态2可以执行 handle1");
}
public void hanle2() {
}
}
/**
* 环境角色
*/
public class Context {
public static final State STATE1 = new State1();
public static final State STATE2 = new State2();
private State currentState;
public State getCurrentState() {
return currentState;
}
public void setCurrentState(State state) {
this.currentState = state;
this.currentState.setContext(this);
}
public void handle1() {
this.currentState.handle1();
}
public void handle2() {
this.currentState.hanle2();
}
}
/**
* 测试类
*/
public class StateTest {
@Test
public void test() {
Context context = new Context();
context.setCurrentState(new State1());
context.handle1();
context.handle2();
context.handle2();
context.handle1();
}
}
优点:
缺点:
适用场景:
定义:
使用共享对象可有效地支持大量的细粒度的对象
示例:
/**
* 抽象享元角色
*/
public abstract class FlyWeight {
private String intrinsic;
protected final String extrinsic;
public FlyWeight(String extrinsic) {
this.extrinsic = extrinsic;
}
public abstract void operate(); // 业务逻辑
public String getIntrinsic() {
return intrinsic;
}
public void setIntrinsic(String intrinsic) {
this.intrinsic = intrinsic;
}
}
/**
* 具体享元角色
*/
public class ConcreteFlyWeight extends FlyWeight {
public ConcreteFlyWeight(String extrinsic) {
super(extrinsic);
}
public void operate() {
System.out.println("业务逻辑");
}
}
/**
* 享元对象工厂
*/
public class FlyWeightFactory {
private static HashMap<String, FlyWeight> flyWeightHashMap = new HashMap<String, FlyWeight>();
public static FlyWeight getFlyWeight(String extrinsic) {
FlyWeight flyWeight = null;
if (flyWeightHashMap.containsKey(extrinsic)) {
flyWeight = flyWeightHashMap.get(extrinsic);
} else {
flyWeight = new ConcreteFlyWeight(extrinsic);
flyWeightHashMap.put(extrinsic, flyWeight);
}
return flyWeight;
}
}
优点:
可以大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能
缺点:
提高了系统复杂性,需要分离出外部状态和内部状态
适用场景:
定义:
将抽象和实现解耦,使得两者可以独立地变化
示例:
/**
* 实现化角色
*/
public interface Implementor {
void doSomething();
void doAnyThing();
}
/**
* 具体实现化角色
*/
public class ConcreteImplementor implements Implementor{
public void doSomething() {
System.out.println("doSomething");
}
public void doAnyThing() {
System.out.println("doAnything");
}
}
/**
* 抽象化角色
*/
public abstract class Abstraction {
private Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public void request() {
this.implementor.doSomething();
}
public Implementor getImplementor() {
return implementor;
}
}
/**
* 具体的抽象化角色
*/
public class ConcreteAbstraction extends Abstraction {
public ConcreteAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void request() {
super.request();
super.getImplementor().doAnyThing();
}
}
优点:
适用场景:
原文:https://www.cnblogs.com/floor/p/12961398.html