赞
踩
设计模式 | 简述 | 目的 | 生活案例 |
---|---|---|---|
工厂模式(Factory Pattern) | 不同条件下创建不同实例 | 封装创建细节 | 实体工厂 |
单例模式(Singleton Pattern) | 保证一个类仅有一个实例,并且提供一个全局访问点 | 保证独一无二 | CEO |
原型模式(Prototype Pattern) | 通过拷贝原型创建新的对象 | 高效创建对象 | 克隆 |
建造者模式(Builder Pattern) | 用来创建复杂的复合对象 | 开放个性配置步骤 | 选配 |
代理模式(Proxy Pattern) | 为其他对象提供一种代理以控制对这个对象的访问 | 增强职责 | 媒婆 |
外观模式(Facade Pattern) | 对外提供一个统一的接口用来访问子系统 | 统一访问入口 | 前台 |
装饰器模式(Decorator Pattern) | 为对象添加新功能 | 灵活扩展、同宗同源 | 煎饼 |
享元模式(Flyweight Pattern) | 使用对象池来减少重复对象的创建 | 共享资源池 | 全国社保联网 |
组合模式(Composite Pattern) | 将整体与局部(树形结构)进行递归组合,让客户端能够以一种的方式对其进行处理 | 统一整体和个体 | 组织架构树 |
适配器模式(Adapter Pattern) | 将原来不兼容的两个类融合在一起 | 兼容转换 | 电源适配 |
桥接模式(Bridge Pattern) | 将两个能够独立变化的部分分离开来 | 不允许用继承 | 桥 |
模板模式(Template Pattern) | 定义一套流程模板,根据需要实现模板中的操作 | 逻辑复用 | 把大象装进冰箱 |
策略模式(Strategy Pattern) | 封装不同的算法,算法之间能互相替换 | 把选择权交给用户 | 选择支付方式 |
责任链模式(Chain of Responsibility Pattern | ) 拦截的类都实现统一接口,每个接收者都包含对下一个接收者的引用。将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。 | 解耦处理逻辑 | 踢皮球 |
迭代器模式(Iterator Pattern) | 提供一种方法顺序访问一个聚合对象中的各个元素 | 统一对集合的访问方式 | 逐个检票进站 |
命令模式(Command Pattern) | 将请求封装成命令,并记录下来,能够撤销与重做 | 解耦请求和处理 | 遥控器 |
状态模式(State Pattern) | 根据不同的状态做出不同的行为 | 绑定状态和行为 | 订单状态跟踪 |
备忘录模式(Memento Pattern) | 保存对象的状态,在需要时进行恢复 | 备份、后悔机制 | 草稿箱 |
中介者模式(Mediator Pattern) | 将对象之间的通信关联关系封装到一个中介类中单独处理,从而使其耦合松散 | 统一管理网状资源 | 朋友圈 |
解释器模式(Interpreter Pattern) | 给定一个语言,定义它的语法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子 | 实现特定语法解析 | 摩斯密码 |
观察者模式(Observer Pattern) | 状态发生改变时通知观察者,一对多的关系 | 解耦观察者与被观察者 | 闹钟 |
访问者模式(Visitor Pattern) | 稳定数据结构,定义新的操作行为 | 解耦数据结构和数据操作 | KPI考核 |
委派模式(Delegate Pattern) | 允许对象组合实现与继承相同的代码重用,负责任务的调用和分配 | 只对结果负责 | 授权委托书 |
一个类只有一个实例,且该类能自行创建这个实例
单例模式的应用场景主要有以下几个方面。
痴汉模式
public class God {
private static final God god = new God();//God对象提前实例化
private God(){}//构造方法私有化
public static God getInstance(){//获得God对象方法公开化
return god;
}
}
懒汉模式
public class God {
private static God god;//God对象不进行实例化
private God(){}
public static God getInstance() {
if (god == null) {//不存在则创建
god = new God();
}
return god;
}
}
多线程懒汉模式
public class God {
private volatile static God god;
private God(){}
public static God getInstance() {
if (god == null) { //God不存在则进行排队,去创建god对象
synchronized(God.class){
if (god == null) {
god = new God();
}
}
}
//God产生后不必再排队
return god;
}
}
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆。
原型模式通常适用于以下场景。
@Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor public class Person implements Cloneable { // 姓名 private String name; // 年龄 private Integer age; // 邮件 private String email; // 描述 private String desc; @Override public Person clone() throws CloneNotSupportedException { return (Person)super.clone(); } } ---------------------------------------------- private static Person prototype = new Person("张三",20,"123456@qq.com","我是张三"); @SneakyThrows public static void main(String[] args) { List<Person> list = new ArrayList(); for (int i = 0; i < 10 ; i++) { // 初始化一个对象 Person person = prototype.clone().setAge(i); list.add(person); } System.out.println(list); }
简单工厂模式的主要角色如下:
应用场景
抽象产品
public interface Product {
void show();
}
具体产品1
public class ProductA implements Product{
@Override
public void show() {
System.out.println("产品A");
}
}
具体产品2
public class ProductB implements Product{
@Override
public void show() {
System.out.println("产品B");
}
}
简单工厂类
public class SimpleFactory { public static Product create(Class<? extends Product> clazz) { if (Objects.nonNull(clazz)){ try { return clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return null; } public static void main(String[] args) { Product product = create(ProductA.class); product.show(); } }
应用场景:
工厂方法模式的主要角色如下。
抽象产品
public interface Product {
void show();
}
具体产品1
public class ProductA implements Product{
@Override
public void show() {
System.out.println("产品A");
}
}
具体产品2
public class ProductB implements Product{
@Override
public void show() {
System.out.println("产品B");
}
}
抽象工厂
public interface AbstractFactory {
Product newProduct();
}
具体工厂1
public class FactoryA implements AbstractFactory{
@Override
public Product newProduct() {
System.out.println("具体工厂1生成-->具体产品1...");
return new ProductA();
}
}
具体工厂2
public class FactoryB implements AbstractFactory{
@Override
public Product newProduct() {
System.out.println("具体工厂2生成-->具体产品2...");
return new ProductB();
}
}
调用实际工厂生产产品
public static void main(String[] args) {
try {
Class<?> factoryA = Class.forName("com.example.tools_demo.factory.FactoryA");
AbstractFactory factory = (AbstractFactory)factoryA.newInstance();
factory.newProduct();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
抽象工厂模式通常适用于以下场景:
抽象工厂模式的主要角色如下。
抽象工厂:提供了产品的生成方法
public interface AbstractFactory {
ProductA newProductA();
ProductB newProductB();
}
具体工厂:实现了产品的生成方法
public class FactoryA implements AbstractFactory{
@Override
public ProductA newProductA() {
System.out.println("具体工厂1生成-->具体产品1...");
return new ProductA();
}
@Override
public ProductB newProductB() {
System.out.println("具体工厂1生成-->具体产品2...");
return new ProductB();
}
}
调用实际工厂A 生产产品A和B
public static void main(String[] args) {
try {
Class<?> factoryA = Class.forName("com.example.tools_demo.factory.FactoryA");
AbstractFactory factory = (AbstractFactory)factoryA.newInstance();
factory.newProductA();
factory.newProductB();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示
即产品的组成部分是不变的,但每一部分是可以灵活选择的。
建造者(Builder)模式的主要角色如下。
建造者模式主要适用于以下应用场景:
产品角色:包含多个组成部件的复杂对象
public class Product { private String partA; private String partB; private String partC; public void setPartA(String partA) { this.partA = partA; } public void setPartB(String partB) { this.partB = partB; } public void setPartC(String partC) { this.partC = partC; } public void show() { System.out.println("partA: " + partA); System.out.println("partB: " + partB); System.out.println("partC: " + partC); } }
抽象建造者:包含创建产品各个子部件的抽象方法
public abstract class Builder {
//创建产品对象
protected Product product = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//返回产品对象
public Product getResult() {
return product;
}
}
具体建造者1:实现了抽象建造者接口
public class ConcreteBuilderA extends Builder {
public void buildPartA() {
product.setPartA("A 建造 PartA");
}
public void buildPartB() {
product.setPartB("A 建造 PartB");
}
public void buildPartC() {
product.setPartC("A 建造 PartC");
}
}
具体建造者2:实现了抽象建造者接口
public class ConcreteBuilderB extends Builder {
public void buildPartA() {
product.setPartA("B 建造 PartA");
}
public void buildPartB() {
product.setPartB("B 建造 PartB");
}
public void buildPartC() {
product.setPartC("B 建造 PartC");
}
}
指挥者:调用建造者中的方法完成复杂对象的创建
public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } //产品构建与组装方法 public Product construct() { builder.buildPartA(); builder.buildPartB(); builder.buildPartC(); return builder.getResult(); } // 只关心builder类,并不关心谁生成的bulder类的具体实现 // 建造顺序固定 public static void main(String[] args) { Builder builder = new ConcreteBuilderA(); Director director = new Director(builder); Product product = director.construct(); product.show(); } }
代理模式的主要角色如下。
代理模式的应用场景:
静态:由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
动态:在程序运行时,运用反射机制动态创建而成
抽象主题
public interface Subject {
void request();
}
真实主题
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("访问真实主题方法...");
}
}
代理
public class MyProxy implements Subject { private RealSubject realSubject; @Override public void request() { if (realSubject == null) { realSubject = new RealSubject(); } preRequest(); realSubject.request(); postRequest(); } public void preRequest() { System.out.println("访问真实主题之前的预处理。"); } public void postRequest() { System.out.println("访问真实主题之后的后续处理。"); } }
对真实主题的方法进行额外处理
public static void main(String[] args) {
MyProxy proxy = new MyProxy();
proxy.request();
}
JDK 实现代理只需要使用 newProxyInstance 方法,该方法需要接收三个参数
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h )
实现动态代理
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JdkProxy implements InvocationHandler { private Subject target; public Subject getInstance(Subject target) { this.target = target; Class<?> clazz = target.getClass(); /** *三个参数, *第一个是被代理类的类构造器, *第二个指的是被代理类的接口,也就是Subject接口, *第三个是实现这个代理的类 * **/ return (Subject) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { preRequest(); Object result = method.invoke(this.target, args); postRequest(); return result; } public void preRequest() { System.out.println("访问真实主题之前的预处理。"); } public void postRequest() { System.out.println("访问真实主题之后的后续处理。"); } }
代理对象
public class MyProxy implements Subject {
private RealSubject realSubject;
@Override
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
realSubject.request();
}
}
对真实主题方法进行额外处理
MyProxy proxy = new MyProxy();
JdkProxy jdkProxy = new JdkProxy();
Subject subject = jdkProxy.getInstance(proxy);
subject.request();
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作
适配器模式(Adapter)通常适用于以下场景。
适配器模式(Adapter)包含以下主要角色。
例如:一个烧水壶是使用两个插孔的插座。实现两孔插座的方法。但是现在只有三孔插座
三孔插座类
/**
* 三孔插座
*/
public interface TriplexOutlet {
void electrify(int l, int n, int e);
}
两孔插座类
/**
* 两孔插座
*/
public interface DualOutlet {
void electrify(int l, int n);
}
两孔插座电器
/**
* 烧水壶类
*/
public class Teakettle implements DualOutlet {
@Override
public void electrify(int l, int n) {
System.out.println("实现两孔插座");
System.out.println("火线:" + l + " 零线:" + n);
}
}
通过继承来实现适配器功能。
适配器类
/**
* 适配器类
*/
public class Adapter extends Teakettle implements TriplexOutlet {
@Override
public void triplexElectrify(int l, int n, int e) {
System.out.println("三孔插座使用两孔插座逻辑");
dualElectrify(l, n);
}
}
使用插孔
/**
* 使用插孔
*/
public class Boil {
public static void main(String[] args) {
Adapter adapter = new Adapter();
adapter.triplexElectrify(1, 2, 3);
}
}
通过对象注入来实现适配器功能。
适配器类
/** * 适配器类 */ public class Adapter implements TriplexOutlet { private Teakettle teakettle; public Adapter(Teakettle teakettle) { this.teakettle = teakettle; } @Override public void triplexElectrify(int l, int n, int e) { System.out.println("三孔插座使用两孔插座逻辑"); teakettle.dualElectrify(l, n); } }
使用插孔
/**
* 使用插孔
*/
public class Boil {
public static void main(String[] args) {
Adapter adapter = new Adapter(new Teakettle());
adapter.triplexElectrify(1, 2, 3);
}
}
通过抽象类来实现适配
适配器类
/**
* 适配器类
*/
public abstract class Adapter implements Appliance {
@Override
public void triplexElectrify(int l, int n, int e) {
}
@Override
public void dualElectrify(int l, int n) {
}
}
使用插孔
/**
* 使用插孔
*/
public class Boil extends Adapter{
@Override
public void dualElectrify(int l, int n) {
System.out.println("只实现用自己要的方法");
}
}
将抽象与实现分离,使它们可以独立变化;
桥接(Bridge)模式包含以下主要角色。
桥接模式通常适用于以下场景。
抽象角色
//抽象角色
public abstract class Abstraction {
protected Implementor imple;
protected Abstraction(Implementor imple) {
this.imple = imple;
}
public abstract void Operation();
}
抽象角色扩展
//扩展抽象角色
public class RefinedAbstraction extends Abstraction {
protected RefinedAbstraction(Implementor imple) {
super(imple);
}
public void Operation() {
System.out.println("扩展抽象化(Refined Abstraction)角色被访问");
imple.OperationImpl();
}
}
实现角色
//实现者角色
public interface Implementor {
void OperationImpl();
}
实现角色扩展
//具体实现者角色
public class ConcreteImplementorA implements Implementor {
public void OperationImpl() {
System.out.println("具体实现化(Concrete Implementor)角色被访问");
}
}
角色和实现各自对自己进行扩展,调用时不关心各自的扩展内容
public class BridgeTest {
public static void main(String[] args) {
Implementor imple = new ConcreteImplementorA();
Abstraction abs = new RefinedAbstraction(imple);
abs.Operation();
}
}
指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式
装饰器模式主要包含以下角色。
装饰器模式的应用场景:
抽象构建
//抽象构件角色
public interface Component {
void operation();
}
具体构建
//具体构件角色
public class ConcreteComponent implements Component {
public ConcreteComponent() {
System.out.println("创建具体构件角色");
}
public void operation() {
System.out.println("调用具体构件角色的方法operation()");
}
}
抽象装饰
//抽象装饰角色
public abstract class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
具体装饰1
//具体装饰角色1
public class ConcreteDecorator1 extends Decorator {
public ConcreteDecorator1(Component component) {
super(component);
}
public void operation() {
super.operation();
addedFunction();
}
public void addedFunction() {
System.out.println("为具体构件角色增加额外的功能 1");
}
}
具体装饰2
//具体装饰角色
public class ConcreteDecorator2 extends Decorator {
public ConcreteDecorator2(Component component) {
super(component);
}
public void operation() {
super.operation();
addedFunction();
}
public void addedFunction() {
System.out.println("为具体构件角色增加额外的功能 2");
}
}
角色构建很复杂时,构建器构建角色抽取出来,单独构建。装饰器对构建后的进行加工装饰
public class DecoratorTest {
public static void main(String[] args) {
Component a = new ConcreteComponent();
//构建角色
a.operation();
System.out.println("---------------------------------");
Component b = new ConcreteDecorator1(a);
//对已构建角色装饰装饰
b.operation();
System.out.println("---------------------------------");
Component c = new ConcreteDecorator2(b);
//对已装饰角色装饰装饰
c.operation();
}
}
通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。
外观(Facade)模式包含以下主要角色。
外观模式的应用场景
外观角色
//外观角色
public class Facade {
private SubSystem01 obj1 = new SubSystem01();
private SubSystem02 obj2 = new SubSystem02();
private SubSystem03 obj3 = new SubSystem03();
public void method() {
obj1.method1();
obj2.method2();
obj3.method3();
}
}
子系统1
//子系统角色
public class SubSystem01 {
public void method1() {
System.out.println("子系统01的method1()被调用!");
}
}
子系统2
//子系统角色
public class SubSystem02 {
public void method2() {
System.out.println("子系统02的method2()被调用!");
}
}
子系统3
//子系统角色
public class SubSystem03 {
public void method3() {
System.out.println("子系统03的method3()被调用!");
}
}
用户调用外观角色,外观角色去调用每个子系统
public class FacadeTest {
public static void main(String[] args) {
Facade f = new Facade();
f.method();
}
}
运用共享技术来有效地支持大量细粒度对象的复用
享元模式的主要角色有如下。
享元模式的应用场景:
非享元对象
//非享元角色 public class UnsharedConcreteFlyweight { private String info; UnsharedConcreteFlyweight(String info) { this.info = info; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } }
抽象享元角色
//抽象享元角色
public interface Flyweight {
void operation(UnsharedConcreteFlyweight state);
}
具体享元角色
//具体享元角色
public class ConcreteFlyweight implements Flyweight {
private String key;
ConcreteFlyweight(String key) {
this.key = key;
System.out.println("具体享元" + key + "被创建!");
}
@Override
public void operation(UnsharedConcreteFlyweight outState) {
System.out.print("具体享元" + key + "被调用,");
System.out.println("非享元信息是:" + outState.getInfo());
}
}
享元工厂角色
//享元工厂角色
public class FlyweightFactory {
private HashMap<String, Flyweight> flyweights = new HashMap<String, Flyweight>();
public Flyweight getFlyweight(String key) {
Flyweight flyweight = (Flyweight) flyweights.get(key);
if (flyweight != null) {
System.out.println("具体享元" + key + "已经存在,被成功获取!");
} else {
flyweight = new ConcreteFlyweight(key);
flyweights.put(key, flyweight);
}
return flyweight;
}
}
将资源放进资源池中,从资源池调用资源
public class FlyweightTest { public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); Flyweight f01 = factory.getFlyweight("a"); Flyweight f02 = factory.getFlyweight("a"); Flyweight f03 = factory.getFlyweight("a"); Flyweight f11 = factory.getFlyweight("b"); Flyweight f12 = factory.getFlyweight("b"); f01.operation(new UnsharedConcreteFlyweight("第1次调用a。")); f02.operation(new UnsharedConcreteFlyweight("第2次调用a。")); f03.operation(new UnsharedConcreteFlyweight("第3次调用a。")); f11.operation(new UnsharedConcreteFlyweight("第1次调用b。")); f12.operation(new UnsharedConcreteFlyweight("第2次调用b。")); } }
将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系
组合模式包含以下主要角色。
组合模式的应用场景
抽象组件
public abstract class Node { protected String name;//节点命名 public Node(String name) {//构造节点,传入节点名。 this.name = name; } //增加后续子节点方法 protected abstract void add(Node child); protected void ls(int space) { for (int i = 0; i < space; i++) { System.out.print(" ");//先循环输出n个空格; } System.out.println(name);//然后再打印自己的名字。 } //无参重载方法,默认从第0列开始显示。 protected void ls() { this.ls(0); } }
树枝节点
public class Folder extends Node { //文件夹可以包含子节点(文件夹或者文件)。 private List<Node> childrenNodes = new ArrayList<>(); public Folder(String name) { super(name);//调用父类“节点”的构造方法命名。 } @Override protected void add(Node child) { childrenNodes.add(child);//可以添加子节点。 } @Override public void ls(int space) { super.ls(space);//调用父类共通的ls方法列出自己的名字。 space++;//之后列出的子节点前,空格数要增加一个了。 for (Node node : childrenNodes) { node.ls(space);//调用子节点的ls方法。 } } }
树叶节点
public class File extends Node { public File(String name) { super(name); } @Override protected void add(Node child) { System.out.println("不能添加子节点。"); } @Override public void ls(int space) { super.ls(space); } }
调用
public class CompositeTest { public static void main(String[] args) { Node driveD = new Folder("D盘"); Node doc = new Folder("文档"); doc.add(new File("简历.doc")); doc.add(new File("项目介绍.ppt")); driveD.add(doc); Node music = new Folder("音乐"); Node jay = new Folder("周杰伦"); jay.add(new File("双截棍.mp3")); jay.add(new File("告白气球.mp3")); jay.add(new File("听妈妈的话.mp3")); Node jack = new Folder("张学友"); jack.add(new File("吻别.mp3")); jack.add(new File("一千个伤心的理由.mp3")); music.add(jay); music.add(jack); driveD.add(music); driveD.ls(); } }
定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
模板方法模式包含以下主要角色。
模式的应用场景
钩子方法的抽象类
//含钩子方法的抽象类 public abstract class HookAbstractClass { //模板方法 public void templateMethod() { abstractMethod1(); hookMethod1(); if (hookMethod2()) { specificMethod(); } abstractMethod2(); } //具体方法 public void specificMethod() { System.out.println("抽象类中的具体方法被调用..."); } //钩子方法1 public void hookMethod1() { } //钩子方法2 public boolean hookMethod2() { return true; } //抽象方法1 public abstract void abstractMethod1(); //抽象方法2 public abstract void abstractMethod2(); }
含钩子方法的具体子类
//含钩子方法的具体子类 public class HookConcreteClass extends HookAbstractClass { public void abstractMethod1() { System.out.println("抽象方法1的实现被调用..."); } public void abstractMethod2() { System.out.println("抽象方法2的实现被调用..."); } public void hookMethod1() { System.out.println("钩子方法1被重写..."); } public boolean hookMethod2() { return false; } }
具体子类创建抽象方法,重写钩子函数,调用模板方法时会调用子类重写后的方法
public class HookTemplateTest {
public static void main(String[] args) {
HookAbstractClass tm = new HookConcreteClass();
tm.templateMethod();
}
}
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。
策略模式的主要角色如下。
策略模式的应用场景:
抽象策略类
//抽象策略类
interface Strategy {
public void strategyMethod(); //策略方法
}
策略类A
//具体策略类A
class ConcreteStrategyA implements Strategy {
public void strategyMethod() {
System.out.println("具体策略A的策略方法被访问!");
}
}
策略类B
//具体策略类B
class ConcreteStrategyB implements Strategy {
public void strategyMethod() {
System.out.println("具体策略B的策略方法被访问!");
}
}
环境类
//环境类
class Context {
private Strategy strategy;
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void strategyMethod() {
strategy.strategyMethod();
}
}
使用
public class StrategyPattern {
public static void main(String[] args) {
Context c = new Context();
Strategy s = new ConcreteStrategyA();
c.setStrategy(s);
c.strategyMethod();
System.out.println("-----------------");
s = new ConcreteStrategyB();
c.setStrategy(s);
c.strategyMethod();
}
}
将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开;
命令模式包含以下主要角色。
命令模式通常适用于以下场景。
抽象命令类
//抽象命令
public interface AbstractCommand {
void execute();
}
调用者
//树枝构件: 调用者 public class CompositeInvoker implements AbstractCommand { private ArrayList<AbstractCommand> children = new ArrayList<AbstractCommand>(); public void add(AbstractCommand c) { children.add(c); } public void remove(AbstractCommand c) { children.remove(c); } public AbstractCommand getChild(int i) { return children.get(i); } public void execute() { for (Object obj : children) { ((AbstractCommand) obj).execute(); } } }
接收者
//接收者
public class CompositeReceiver {
public void action1() {
System.out.println("接收者的action1()方法被调用...");
}
public void action2() {
System.out.println("接收者的action2()方法被调用...");
}
}
具体命令1
//树叶构件: 具体命令1
public class ConcreteCommand1 implements AbstractCommand {
private CompositeReceiver receiver;
ConcreteCommand1() {
receiver = new CompositeReceiver();
}
public void execute() {
receiver.action1();
}
}
具体命令2
//树叶构件: 具体命令2
public class ConcreteCommand2 implements AbstractCommand {
private CompositeReceiver receiver;
ConcreteCommand2() {
receiver = new CompositeReceiver();
}
public void execute() {
receiver.action2();
}
}
将两个命令分别调用接收者不同方法,封装到调用者中,调用者执行调用方法,循环调用每个命令
public class CompositeCommandTest {
public static void main(String[] args) {
AbstractCommand cmd1 = new ConcreteCommand1();
AbstractCommand cmd2 = new ConcreteCommand2();
CompositeInvoker ir = new CompositeInvoker();
ir.add(cmd1);
ir.add(cmd2);
System.out.println("客户访问调用者的execute()方法...");
ir.execute();
}
}
为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
职责链模式主要包含以下角色。
模式的应用场景
** 抽象处理者**
public abstract class Approver {// 审批人抽象类 protected String name;// 抽象出审批人的姓名。 protected Approver nextApprover;// 下一个审批人,更高级别领导。 public Approver(String name) { this.name = name; } protected Approver setNextApprover(Approver nextApprover) { this.nextApprover = nextApprover; return this.nextApprover;// 返回下个审批人,链式编程。 } public abstract void approve(int amount);// 抽象审批方法由具体审批人子类实现 }
具体处理者:员工
public class Staff extends Approver { public Staff(String name) { super(name); } @Override public void approve(int amount) { if (amount <= 1000) { System.out.println("审批通过。【员工:" + name + "】"); } else { System.out.println("无权审批,升级处理。【员工:" + name + "】"); this.nextApprover.approve(amount); } } }
具体处理者:经理
public class Manager extends Approver { public Manager(String name) { super(name); } @Override public void approve(int amount) { if (amount <= 5000) { System.out.println("审批通过。【经理:" + name + "】"); } else { System.out.println("无权审批,升级处理。【经理:" + name + "】"); this.nextApprover.approve(amount); } } }
具体处理者:CEO
public class CEO extends Approver { public CEO(String name) { super(name); } @Override public void approve(int amount) { if (amount <= 10000) { System.out.println("审批通过。【CEO:" + name + "】"); } else { System.out.println("驳回申请。【CEO:" + name + "】"); } } }
客户角色
审批自动进行,直到结束
public class Client { public static void main(String[] args) { Approver flightJohn = new Staff("张飞"); flightJohn.setNextApprover(new Manager("关羽")).setNextApprover(new CEO("刘备")); //高层接触不到也没必要接触,直接找员工张飞审批。 flightJohn.approve(1000); /** 审批通过。【员工:张飞】 **/ flightJohn.approve(4000); /** 无权审批,升级处理。【员工:张飞】 审批通过。【经理:关羽】 **/ flightJohn.approve(9000); /** 无权审批,升级处理。【员工:张飞】 无权审批,升级处理。【经理:关羽】 审批通过。【CEO:刘备】 **/ flightJohn.approve(88000); /** 无权审批,升级处理。【员工:张飞】 无权审批,升级处理。【经理:关羽】 驳回申请。【CEO:刘备】 **/ } }
对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
状态模式包含以下主要角色。
通常在以下情况下可以考虑使用状态模式。
抽象状态
//抽象状态类
public abstract class State {
public abstract void handle(Context context);
}
具体状态A类
//具体状态A类
public class ConcreteStateA extends State {
public void handle(Context context) {
System.out.println("当前状态是 A.");
context.setState(new ConcreteStateB());
}
}
具体状态B类
//具体状态B类
public class ConcreteStateB extends State {
public void handle(Context context) {
System.out.println("当前状态是 B.");
context.setState(new ConcreteStateA());
}
}
环境类
//环境类 public class Context { private State state; //定义环境类的初始状态 public Context() { this.state = new ConcreteStateA(); } //设置新状态 public void setState(State state) { this.state = state; } //读取状态 public State getState() { return (state); } //对请求做处理 public void Handle() { state.handle(this); } }
默认状态为A,多次调用自动转换状态
public class StatePatternClient {
public static void main(String[] args) {
Context context = new Context(); //创建环境
context.Handle(); //处理请求
context.Handle();
context.Handle();
context.Handle();
}
}
指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式
观察者模式的主要角色如下。
模式的应用场景
抽象主题
//抽象目标 public abstract class Subject { protected List<Observer> observers = new ArrayList<Observer>(); //增加观察者方法 public void add(Observer observer) { observers.add(observer); } //删除观察者方法 public void remove(Observer observer) { observers.remove(observer); } public abstract void notifyObserver(); //通知观察者方法 }
具体主题
//具体目标
public class ConcreteSubject extends Subject {
public void notifyObserver() {
System.out.println("具体目标发生改变...");
System.out.println("--------------");
for (Observer obs : observers) {
obs.response();
}
}
}
抽象观察者
//抽象观察者
public interface Observer {
void response(); //反应
}
具体观察者1
//具体观察者1
public class ConcreteObserver1 implements Observer {
public void response() {
System.out.println("具体观察者1作出反应!");
}
}
具体观察者2
//具体观察者2
public class ConcreteObserver2 implements Observer {
public void response() {
System.out.println("具体观察者2作出反应!");
}
}
主题发生改变,循环通知观察者
public class ObserverPattern {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer obs1 = new ConcreteObserver1();
Observer obs2 = new ConcreteObserver2();
subject.add(obs1);
subject.add(obs2);
subject.notifyObserver();
}
}
定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互
中介者模式包含以下主要角色。
模式的应用场景
抽象中介者
//抽象中介者
public abstract class Mediator {
public abstract void register(Colleague colleague);
public abstract void relay(Colleague cl); //转发
}
具体中介者
//具体中介者 public class ConcreteMediator extends Mediator { private List<Colleague> colleagues = new ArrayList<Colleague>(); public void register(Colleague colleague) { if (!colleagues.contains(colleague)) { colleagues.add(colleague); colleague.setMedium(this); } } public void relay(Colleague cl) { for (Colleague ob : colleagues) { if (!ob.equals(cl)) { ((Colleague) ob).receive(); } } } }
抽象同事类
//抽象同事类
public abstract class Colleague {
protected Mediator mediator;
public void setMedium(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive();
public abstract void send();
}
具体同事类1
//具体同事类
public class ConcreteColleague1 extends Colleague {
public void receive() {
System.out.println("具体同事类1收到请求。");
}
public void send() {
System.out.println("具体同事类1发出请求。");
mediator.relay(this); //请中介者转发
}
}
具体同事类2
//具体同事类
public class ConcreteColleague2 extends Colleague {
public void receive() {
System.out.println("具体同事类2收到请求。");
}
public void send() {
System.out.println("具体同事类2发出请求。");
mediator.relay(this); //请中介者转发
}
}
同事类发送信息到中介类,中介类将信息发送到除发送者的其他同事类
public class MediatorPattern {
public static void main(String[] args) {
Mediator md = new ConcreteMediator();
Colleague c1, c2;
c1 = new ConcreteColleague1();
c2 = new ConcreteColleague2();
md.register(c1);
md.register(c2);
c1.send();
System.out.println("-------------");
c2.send();
}
}
提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示;
迭代器模式主要包含以下角色。
模式的应用场景
抽象聚合
//抽象聚合
public interface Aggregate {
void add(Object obj);
void remove(Object obj);
Iterator getIterator();
}
具体聚合
//具体聚合 public class ConcreteAggregate implements Aggregate { private List<Object> list = new ArrayList<Object>(); public void add(Object obj) { list.add(obj); } public void remove(Object obj) { list.remove(obj); } public Iterator getIterator() { return (new ConcreteIterator(list)); } }
抽象迭代器
//抽象迭代器
public interface Iterator {
Object first();
Object next();
boolean hasNext();
}
具体迭代器
//具体迭代器 public class ConcreteIterator implements Iterator { private List<Object> list = null; private int index = -1; public ConcreteIterator(List<Object> list) { this.list = list; } public boolean hasNext() { if (index < list.size() - 1) { return true; } else { return false; } } public Object first() { index = 0; Object obj = list.get(index); ; return obj; } public Object next() { Object obj = null; if (this.hasNext()) { obj = list.get(++index); } return obj; } }
调用
public class IteratorPattern { public static void main(String[] args) { Aggregate ag = new ConcreteAggregate(); ag.add("JAVA"); ag.add("PHP"); ag.add("C++"); System.out.print("聚合的内容有:"); Iterator it = ag.getIterator(); while (it.hasNext()) { Object ob = it.next(); System.out.print(ob.toString() + "\t"); } Object ob = it.first(); System.out.println("\nFirst:" + ob.toString()); } }
将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式
访问者模式包含以下主要角色。
模式的应用场景
抽象访问者
//抽象访问者
public interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
具体访问者A类
//具体访问者A类
public class ConcreteVisitorA implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者A访问-->" + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("具体访问者A访问-->" + element.operationB());
}
}
具体访问者B类
//具体访问者B类
public class ConcreteVisitorB implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者B访问-->" + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("具体访问者B访问-->" + element.operationB());
}
}
抽象元素
//抽象元素类
public interface Element {
void accept(Visitor visitor);
}
具体元素A类
//具体元素A类
public class ConcreteElementA implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationA() {
return "具体元素A的操作。";
}
}
具体元素B类
//具体元素B类
public class ConcreteElementB implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationB() {
return "具体元素B的操作。";
}
}
对象结构角色
//对象结构角色 public class ObjectStructure { private List<Element> list = new ArrayList<Element>(); public void accept(Visitor visitor) { Iterator<Element> i = list.iterator(); while (i.hasNext()) { i.next().accept(visitor); } } public void add(Element element) { list.add(element); } public void remove(Element element) { list.remove(element); } }
对集合中的不同类型数据(类型数量稳定)进行多种操作时,使用访问者模式
public class VisitorPattern {
public static void main(String[] args) {
ObjectStructure os = new ObjectStructure();
os.add(new ConcreteElementA());
os.add(new ConcreteElementB());
Visitor visitor = new ConcreteVisitorA();
os.accept(visitor);
System.out.println("------------------------");
visitor = new ConcreteVisitorB();
os.accept(visitor);
}
}
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态
备忘录模式的主要角色如下。
模式的应用场景
发起人
//发起人 public class Originator { private String state; public void setState(String state) { this.state = state; } public String getState() { return state; } public Memento createMemento() { return new Memento(state); } public void restoreMemento(Memento m) { this.setState(m.getState()); } }
管理者
//管理者
public class Caretaker {
private Memento memento;
public void setMemento(Memento m) {
memento = m;
}
public Memento getMemento() {
return memento;
}
}
备忘录
//备忘录 public class Memento { private String state; public Memento(String state) { this.state = state; } public void setState(String state) { this.state = state; } public String getState() { return state; } }
发起人创建备忘录,将当前对象存储到备忘录中,管理者保存备忘录。
发起人恢复时,从管理者中拿到备忘录,回复数据
public class MementoPattern {
public static void main(String[] args) {
Originator or = new Originator();
Caretaker cr = new Caretaker();
or.setState("S0");
System.out.println("初始状态:" + or.getState());
cr.setMemento(or.createMemento()); //保存状态
or.setState("S1");
System.out.println("新的状态:" + or.getState());
or.restoreMemento(cr.getMemento()); //恢复状态
System.out.println("恢复状态:" + or.getState());
}
}
给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子
解释器模式包含以下主要角色。
模式的应用场景
抽象表达式类
//抽象表达式类
public interface Expression {
boolean interpret(String info);
}
非终结符表达式类
//非终结符表达式类
class AndExpression implements Expression {
private Expression city = null;
private Expression person = null;
public AndExpression(Expression city, Expression person) {
this.city = city;
this.person = person;
}
public boolean interpret(String info) {
String s[] = info.split("的");
return city.interpret(s[0]) && person.interpret(s[1]);
}
}
终结符表达式类
//终结符表达式类
public class TerminalExpression implements Expression {
private Set<String> set = new HashSet<String>();
public TerminalExpression(String[] data) {
for (int i = 0; i < data.length; i++) set.add(data[i]);
}
public boolean interpret(String info) {
if (set.contains(info)) {
return true;
}
return false;
}
}
环境类
//环境类 class Context { private String[] citys = {"韶关", "广州"}; private String[] persons = {"老人", "妇女", "儿童"}; private Expression cityPerson; public Context() { Expression city = new TerminalExpression(citys); Expression person = new TerminalExpression(persons); cityPerson = new AndExpression(city, person); } public void freeRide(String info) { boolean ok = cityPerson.interpret(info); if (ok) System.out.println("您是" + info + ",您本次乘车免费!"); else System.out.println(info + ",您不是免费人员,本次乘车扣费2元!"); } }
用【的】去拆分语句,然后去判断是否在表达式中。
/*文法规则
<expression> ::= <city>的<person>
<city> ::= 韶关|广州
<person> ::= 老人|妇女|儿童
*/
public class InterpreterPatternDemo {
public static void main(String[] args) {
Context bus = new Context();
bus.freeRide("韶关的老人");
bus.freeRide("韶关的年轻人");
bus.freeRide("广州的妇女");
bus.freeRide("广州的儿童");
bus.freeRide("山东的儿童");
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。