前言
在设计模式 概览中,我尽可能的使用通用化的语言来描述设计模式.
本章内, 我们将给出Java版本的设计模式概览, 及通用示例.
章节目录
本文主要包括如下几个部分:
六项基本准则
创建型模式(五种)
结构型模式(七种)
行为型模式(十一种)
六项基本原则
略. 总体为了满足对修改关闭, 对继承开放对原则.
创建模式
创建者模式的目标是创建对象. 主要包括如下五种:
- 工厂模式: 工厂.
- 抽象工厂模式: 抽象的工厂.
- 单例模式: 单个实例对象.
- 原型模式: 拷贝创建.
- 建造者模式: 建造创建.
单例模式
# 饿汉模式
class Singleton {
private Singleton(){}
private final static Singleton singleton = new Singleton();
public static Singleton getInstance(){
return singleton;
}
}
public class SingletonTest{
public static void main(String[] args) {
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
System.out.println(obj1 ==obj2);
}
}
# 懒汉模式 - 线程非安全
class UnsafeLazySingleton{
private UnsafeLazySingleton(){}
private static UnsafeLazySingleton lazySingleton;
public static UnsafeLazySingleton getInstance(){
if(null == lazySingleton){
lazySingleton = new UnsafeLazySingleton();
}
return lazySingleton;
}
}
# 懒汉模式 - 线程安全
class SafeLazySingleton{
private SafeLazySingleton(){}
private static SafeLazySingleton lazySingleton;
public static SafeLazySingleton getInstance(){
synchronized (lazySingleton) {
if(null == lazySingleton){
lazySingleton = new SafeLazySingleton();
}
}
return lazySingleton;
}
}
# 懒汉模式 - 线程安全(优化版)
# 使用synchronized和volatile关键字双向锁定对象
class DoubleLockSafeLazySingleton{
private DoubleLockSafeLazySingleton(){}
private volatile static DoubleLockSafeLazySingleton lazySingleton;
public static DoubleLockSafeLazySingleton getInstance(){
if(null == lazySingleton){
synchronized (lazySingleton) {
if(null == lazySingleton){
lazySingleton = new DoubleLockSafeLazySingleton();
}
}
}
return lazySingleton;
}
}
工厂模式
工厂模式的代码比较简单. 因为是通用工厂, 所以都是使用反射返回一个对象的实例. 抽象代码如下所示:
# 通用工厂模式
class CommonFactory{
public Object newInstance(Class class) throws Exception{
return Class.forName(class.getName()).newInstance();
}
public Object getInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class c = Class.forName(className);
return c.newInstance();
}
}
通用工厂模式还要一些的变种.例如:简单工厂模式
/ 多个抽象工厂模式
/ 单例工厂模式
/ 延迟加载
.这里只简单的写下简单工厂模式
.
# 简单工厂模式(生产 A、B两种种类)
class SimpleFactory{
static class A{}
static class B{}
public Object getInstance(String name) {
if(name.equals("A")){
return new A();
}else if(name.equals("B")){
return new B();
}
return null;
}
}
抽象工厂模式
抽象工厂模式个人认为是对于工厂模式的扩展. 当一个公司有例如2条以上的生产线的时候. 一个工厂模式已经远远不能够满足了, 此时需要抽象工厂模式
.
抽象工厂模式创建的是抽象的对象.
#双工厂的抽象工厂模式
public abstract class AbstractProductA{
// 公用方法
public void shareMeothod(){}
// 私有方法
public void doSomething();
}
#ProductA1-class
class ProductA1 extends AbstractProductA{
public void doSomething(){System.out.println("Product A1");}
}
#ProductA2-class
class ProductA2 extends AbstractProductA{
public void doSomething(){System.out.println("Product A2");}
}
# AbstractProductB- abstract class
# ProductB1-class
# ProductB2-class
# AbstractCreator-abstract class
public abstract class AbstractCreator{
// A 产品线
public abstract AbstractProductA createProductA();
// B 产品线
public abstract AbstractProductB createProductB();
}
# Creator1-class
public class Creator1 extends AbstractCreator{
// A 产品线
public AbstractProductA createProductA(){return new ProductA1();}
// B 产品线
public AbstractProductB createProductB(){return new ProductB1();}
}
# Creator2-class
public class Creator2 extends AbstractCreator{
// A 产品线
public AbstractProductA createProductA(){return new ProductA2();}
// B 产品线
public AbstractProductB createProductB(){return new ProductB2();}
}
# 双工厂
public class client{
public static void main(String args[]){
AbstractCreator creator1 = new Creator1();
AbstractCreator creator2 = new Creator2();
// 1产品工厂
AbstractProductA a1 = creator1.createProductA();
AbstractProductB b1 = creator1.createProductB();
// 2产品工厂
AbstractProductA a2 = creator2.createProductA();
AbstractProductB b2 = creator2.createProductB();
}
}
上述标示的是双产品线的抽象工厂模式. 其中createProductA
与createProductB
皆为抽象工厂的抽象方法. 与简单工厂不同的是, 抽象工厂模式可以有多种实现.(即多个工厂流水线)
原型模式
原型模式
即拷贝创建模式
. 我们通过继承Cloneable接口
的clone()方法
进行拷贝.主要分为浅拷贝
与深拷贝
2种. (无论深拷贝还是浅拷贝, 都是通过实现Cloneable
的clone()
方法实现.)
# 浅拷贝
class SimpleClone implements Cloneable{
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
# 深拷贝
class DeepClone implements Cloneable{
private ArrayList<Integer> arrayList = new ArrayList<>();
public Object clone() throws CloneNotSupportedException{
DeepClone obj = (DeepClone)super.clone();
obj.arrayList = (ArrayList<Integer>)this.arrayList.clone();
return obj;
}
}
# 二进制流深拷贝
class ByteDeepClone implements Cloneable{
public Object deepClone() throws CloneNotSupportedException,IOException, ClassNotFoundException{
// 写入当前对象的二进制流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos;
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
建造者模式
建造者模式
的核心在于组装创建与定制化构建. 当某个对象需要什么样的构造方法, 各个参数应当如何分配时. 就当选择建造者模式了. 类如其名, 类的构建在于一步一步的构造.
# Product-class
public class Product{
public void doSomething(){
// 独立业务处理
}
}
# Builder- abstract class
public abstract class Builder{
//设置产品的不同部分
public abstract void setPart();
// 建造产品
public abstract Product buildProduct();
}
# ConcreteBuilder - class
public class ConcreteBuilder extends Builder{
private Product product = new Product();
// 设置产品零件
public void setPart(){
//产品零件业务逻辑
// name=1; age=20;
}
// 组件一个产品
public Product buildProduct(){
return product;
}
}
# Director
public class Director{
private Builder builder = new ConcreteBuilder();
// 构造不同的产品
public Product getProduct{
builder.setPart();
// 设置不同的零件,产生不同的产品
return builder.buildeProduct();
}
}
当然其有时还用于多参数的分部构造函数
.例如,有时我们在代码内看到new Hello().setname(123).setAge(12)
.这样的形式. 这就是构造者模式构造而成.
构造者模式的核心在于定制化构造
.这是工厂模式
所不能即的.但是工厂胜于通用, 构造胜在定制化.
结构型模式
结构型模式与创建型不同. 其旨在类与类之间的关系. 结构型模式主要包括如下几种:
- 适配器模式: 适配不同的接口&类.
- 装饰模式: 对接口&方法进行装饰, 补充.
- 代理模式: 对对象进行代理.
- 门面模式: 统一开放对门面.
- 桥接模式: 桥接抽象对象,使两边能够独立对变化.
- 组合模式: 部分与整体进行组合.
- 享元模式: 分享和重用对象.
模式关系
从宏观来看,适配器模式主要有3种类型,类适配器/对象适配器/接口适配器。其中,类适配器最贴合适配本意。同时,对象适配器引申出了装饰器模式/代理模式/外观模式、桥接模式。(这五种书中称为包管理设计模式)
但是从一定程度上来说,对象适配器,组合模式和享元模式并无直接的联系。(这边感觉原作者画错了。)
适配器模式
适配器模式(Adapter Pattern)的定义如下:
Convert the interface of a class into another interface clients expert. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. (将一个类的接口变成客户端所期待的另一种接口,从而使原本因为接口不匹配而无法工作的两个类能够在一起工作。)
- 适配器模式-通用类图
// interface - target 目标角色
public interface Target{
// 目标角色自己的方法
public void request();
}
// ConcreteTarget - class - 目标角色实现类
public class ConcreteTarget implements Target{
public void request(){
System.out.println("Concrete Target Class.");
}
}
// Adaptee - class - 原角色
public class Adaptee{
// 原有的业务逻辑
public void doSomething(){
// 原有的业务结构
}
}
// Adapter - class - 适配器角色
public class extend Adaptee implements Target {
public void request(){
// 原业务逻辑结构
doSomething();
}
}
// Client - class - 使用场景
public class Client{
public static void main(String []args){
// 原有业务逻辑
Target targetConcrete = new ConcreteTarget();
targetConcrete.request();
// 更改后的业务逻辑
Target targetAdapter = new Adapter();
targetAdapter.request();
}
}
- 扩展1 - 对象适配器 & 类适配器(Case 1) & 接口适配器
// 适配器类(适配器模式-对象适配器)
public class OuterUserInfoAdapter implements IUserInfo{
public IOuterBaseInfo baseInfo = null;
public IOuterHomeInfo homeInfo = null;
public OuterUserInfoAdapter(IOuterBaseInfo baseInfo, IOuterHomeInfo homeInfo){
this.baseInfo = baseInfo;
this.homeInfo = homeInfo;
}
public String getUserName(){return (String) baseInfo. getUserOfficeInfo().get("userName");}
public String getHomeAddress(){return (String) homeInfo.getUserBaseInfo().get("homeAddress");}
public String getMobileNumber(){...}
public String getOfficeTelNumber(){...}
public String getJobPosition(){...}
public String getHomeTelNumber(){...}
}
- 扩展2 - 接口适配器
使用抽象类来解决接口中需要实现的方法过多的问题。
interface IUserInfo{
public String method1();
public String method2();
}
public abstract class AbstactUserInfo implements IUserInfo{
public String method1(){}
public String method2(){}
}
public class UserInfo1 extends AbstactUserInfo{
public String method1(){
// do something method1
}
}
public class UserInfo2 extends AbstactUserInfo{
public String method2(){
// do something method2
}
}
publc class Client {
public static void main(String []args){
IUserInfo userInfo1 = new UserInfo1();
userInfo1.method1();
userInfo1.method2();
IUserInfo userInfo2 = new UserInfo2();
userInfo2.method1();
userInfo2.method2();
}
}
装饰模式
装饰模式(Decorator Pattern)是一种比较常见的模式,其定义如下:
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionally.(事业相同的接口动态的给一个对象增加一些额外的功能,就增加功能来说,装饰模式相比生成子类更为灵活。)
- 装饰器模式 - 通用类图
// Component - abstact class - 抽象构件类
public abstract class Component{
// 抽象的方法
public abstract void operate();
}
// ConcreteComponent - class - 实体构件类
public class ConcreteComponent extends Component{
public abstract void operate(){
// do Something()
}
}
public abstract class Decorator extends Component{
private Component component = null;
public Decorator(Component component){
this.component = component;
}
public void operate(){
this.component.operate():
}
}
// 装饰类1
public class ConcreteDecorator extends Decorator{
public void decoratorMethod(){}
public void decoratorMethod2(){}
public void operate(){
// 方法前装饰
decoratorMethod();
this.component.operate():、
// 方法后装饰
decoratorMethod2();
}
}
// 装饰类2
public class ConcreteDecorator2 extends Decorator{
public void decoratorMethod(){}
public void decoratorMethod2(){}
public void operate(){
// 方法前装饰
decoratorMethod();
this.component.operate():、
// 方法后装饰
decoratorMethod2();
}
}
public class Client{
public static void main(String []args){
Component concreteComponent = new ConcreteComponent();
Component decoratorComponent1 = new ConcreteDecorator(concreteComponent);
decoratorComponent1.operate();
Component decoratorComponent2 = new ConcreteDecorator2(concreteComponent);
decoratorComponent2.operate();
}
}
代理模式
代理模式(Proxy Pattern)是一个使用率非常高的模式,其定义如下:
Provides a surrogate(代理) or placeholder(占位符) for another object to control access to it.(为其它对象提供一种代理以控制这个对象的访问)
- 代理模式-通用类图
# Subject - interface - 抽象主题类
interface Subject{
// 定义一个方法
public void request();
}
# RealSubject - class - 具体主题类
class RealSubject implements Subject{
// 实现接口方法
public void request(){}
}
# Proxy - class - 代理类
public class Proxy implements Subject{
private Subject subject = null;
// 默认代理
public Proxy(){this.subject = new RealSubject;}
// 定义代理者
public Proxy(Subject subject){this.subject = subject;}
// before
public void uniqueMethod(){}
// 接口方法
public void request(){
uniqueMethod();
subject. request();
}
}
- 动态代理模式-通用类图
# interface - Subject - 抽象主题
interface Subject{
// 业务操作
public void doSomething();
}
# RealSubject - class - 真实主题
class RealSubject implements Subject{
// 业务操作
public void doSomething(){}
}
# MyInvocationHandler - class - 动态代理Handler类
class MyInvocationHandler implements InvocationHandler {
// 被代理的对象
private Object target = null;
// 通过构造函数给予一个对象
public MyInvocationHandler(Obj _obj){
this.obj = _obj;
}
// 代理方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
// 执行被代理的方法
return method.invoke(this.target, args);
}
}
# DynamicProxy - class - 动态代理类
public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader loader, Class<?> [] interfaces, InvocationHandler h){
// 寻找 JoinPoint链接点 AOP框架使用元数据定义
if(true){
// 执行一个前置通知
(new BeforeAdvice()).exec();
}
return (T)Proxy.newProxyInstance(loader,interfaces,h);
}
}
// IAdvice - 接口通知和实现代码
interface IAdvice{
// 通知方法
public void exec();
}
public class BeforeAdvice implements IAdvice{
public void exec(){}
}
// Client - 动态代理场景类
class Client{
public static void main(String []args){
// 定义一个主题
Subject subject = new RealSubject();
// 定义一个Handler
InvocationHandler handler = new MyInvocationHandler(subject);
// 定义主题的代理
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass.getInstance(),Handler);
// 代理的行为
proxy.doSomething("Finish");
}
}
# 进一步封装
public class SubjectDynmaicProxy extends DynamicProxy{
public static <T> T newProxyInstance(Subject subject){
// 参数不同的 重载函数
//(ClassLoader loader, Class<?> [] interfaces, InvocationHandler h)
ClassLoader loader = subject.getClass().getClassLoader();
Class<?>[] classes = subject.getClass().getInteraces();
// 获取Hander
InvocationHandler handler = new MyInvocationHandler(subject);
return (T)Proxy.newProxyInstance(loader,interfaces,handler);
}
}
门面模式
门面模式(Facade Pattern)也叫做外观模式,是一种比较常用的封装模式。其定义如下:
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.(要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。)
- 外观模式 - 通用类图
#所有的外部系统统一称为外部系统(SubSystemClasses)
# ClassA - Class - SubSystemClass
class ClassA{
public void doSomethingA(){}
}
# ClassB - Class - SubSystemClass
class ClassB{
public void doSomethingB(){}
}
# ClassC - Class - SubSystemClass
class ClassC{
public void doSomethingC(){}
}
# Facade - class
class Facade{
// 被委托的对象
private ClassA classA = new ClassA();
private ClassB classB = new ClassB();
private ClassC classC = new ClassC();
public void doSomethingA(){
classA.doSomethingA();
}
public void doSomethingB(){
classB.doSomethingB();
}
public void doSomethingC(){
classC.doSomethingC();
}
public void doSomething(){
classA.doSomethingA();
classB.doSomethingB();
classC.doSomethingC();
}
}
桥接模式
桥梁模式(Bridge Pattern)也叫做桥接模式。是一种比较简单的模式,其定义如下:
Decouple an abstraction from its implementation so that two can vary independently.(将抽象和实现解耦,使得两者可以独立变化。)
- 桥接模式 - 通用类图
Abstraction: 抽象化角色
RefinedAbstraction: 具体抽象化角色
Implementor: 实现化角色
ConcreteImplementor: 具体实现化角色
# Implementor -interface - 实现化角色
public interface Implementor{
public void doSomething();
public void doAnything();
}
# ConcreteImplementor - class - 具体实现化角色
public class ConcreteImplementor1 implements Implementor{
public void doSomething(){}
public void doAnything(){}
}
# Abstraction - abstract class - 抽象化角色
public abstract class Abstraction{
private Implementor implementor;
public Abstraction(Implementor implementor){
this.implementor = implementor;
}
public void request(){
implementor.doSomething();
}
public Implementor getImp(){
return Implementor;
}
}
# RefinedAbstaction
class RefinedAbstaction extends Abstraction{
private Implementor implementor;
public Abstraction(Implementor implementor){
super(implementor);
}
public void request(){
getImp().doSomething();
}
public Implementor getImp(){
return getImp();
}
}
# Client - class
public class Client{
public static void main(String []args){
// 定义一个实现化角色
Implementor imp = new ConcreteImplementor();
// 定义一个抽象化觉色
Abstraction abstract = new RefinedAbstaction(imp);
// 执行行为
abstract.request();
}
}
组合模式
组合模式(Composite Pattern)也叫合成模式,有时又叫做部分-整体模式(Part-Whole),主要用来描述部分和整体之间的关系,其定义如下:
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.(将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一支性。)
- 组合模式 - 通用类图
Component 抽象构建角色:含有组合对象的公共方法和属性。
Leaf: 叶子构件。最小的构建,没有其他的分支。
Composite: 树枝构件。组合构件树枝和叶子结点的合集。
# Component - abstract class
public abstract class Component{
// 公共属性和方法
public void doSomething(){}
}
# Leaf - class
public class Leaf extends Component{
// 覆写方法
public void doSomething(){}
}
# Composite - class
public Composite extends Component{
private ArrayList<Component> arrylist = new ArrayList<>();
public void Add(Component component){
arrylist.add(component);
}
public void Remove(Component component){
arrylist.remove(component);
}
public Component GetChild(int i){
return arrylist.get(i);
}
// 覆写方法
public void doSomething(){}
}
# Client - class
public class Client{
public static void main(String []args){
Component root = new Composite();
Component branch = new Composite();
Component leaf = new Leaf();
root.add(branch);
branch.add(leaf);
}
}
享元模式
享元模式(Flyweight Pattern)是池技术的重要实现方式,其定义如下:
Use sharing to support large numbers of fine-grained objects efficiently. (使用共享对象可有效地支持大量的细粒度的对象。)
- 享元模式 - 通用类图
#Flyweight - 抽象享元角色
public abstract class Flyweight{
//内部状态
private String instrinsic;
//外部状态
protected final String extrinsic;
public Flyweight(String _extrinsic){
this.extrinsic = _extrinsic;
}
// 抽象业务操作
public abstract void operate();
// 内部状态GET/SET
public String getInstrinsic(){return instrinsic;}
public String setInstrinsic(String instrinsic){
this.instrinsic = instrinsic;
}
}
// 具体享元角色1
public class ConcreteFlyweight1 extends Flyweight{
public ConcreteFlyweight1(String _extrinsic){
super(_extrinsic);
}
public abstract void operate(){}
}
// 具体享元角色2
public class ConcreteFlyweight2 extends Flyweight{
public ConcreteFlyweight1(String _extrinsic){
super(_extrinsic);
}
public abstract void operate(){}
}
// 享元工厂
public class FlyweightFactory{
// 定义一个池容器
private static HashMap<String,Flyweight> pool = new HashMap<>();
// 享元工厂
public static Flyweight getFlyweight(String _extrinsic){
Flyweight flyweight = null;
// 池中是否已有该对象
if(pool.containsKey(_extrinsic)){
// 池中有该对象
flyweight = pool.get(_extrinsic);
}else{
// 池中无该对象
flyweight = new ConcreteFlyweight1(_extrinsic);
pool.put(_extrinsic, flyweight);
}
return flyweight;
}
}
行为型模式
行为型模式旨在类与类间的动态关系. 行为型模式主要包括如下几种.
- 策略模式: 根据调用类, 使用不同的策略.
- 模板方法模式: 提供创建类的模板.
- 观察者模式: 观察对象, 更新通知.
- 迭代子模式: 迭代接口, 遍历对象.
- 责任链模式: 链式调用.
- 命令模式: 命令发布者、接收者、执行者拆分.
- 备忘录模式: 数据库备忘.
- 状态模式: 根据状态变化当前调用?
- 访问者模式: 允许访问接口.
- 中介者模式: 解耦类见复杂调用.
- 解释器模式: 解析表达式.
策略模式(Storage Pattern)
策略模式(Strateg Pattern)是一种比较简单的模式,也叫做政策模式(Policy Pattern).其定义如下:
Define a family of algorithms, encapsulate(封装) each one, and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。)
# Strategy - interface - 抽象策略角色
public interface Strategy{
// 策略模式运算法则
public void doSomething();
}
# ConcreteStrategy - class - 具体策略角色
public class ConcreteStrategy1 implements Strategy{
public void doSomething(){
}
}
public class ConcreteStrategy2 implements Strategy{
public void doSomething(){
}
}
// Context - class - 封装角色
public class Context{
// 抽象策略
priavate Strategy strategy;
// 构造函数设置抽象策略
public Context(Strategy _strategy){
strategy = _strategy;
}
// 封装后的策略方法
public void doAnything(){
strategy.doSomething();
}
}
// Client - class - 场景类
public class Client{
public static void main(String []args){
// 声明一个具体的策略
Strategy strategy = new ConcreteStrategy1();
// 申明上下文 - 并选择策略模式
Context context = new Context(strategy);
// 执行策略
context.doAnything();
}
}
模版方法模式(Template Method Pattern)
模版方法模式(Template Method Pattern)是如此简单,以至于让你感觉到你已经掌握其精髓了。其定义如下:
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changeing the algorithm’s structure,(定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。)
- 模版方法模式 - 通用类图
AbstractClass
内抽象方法一般有2类,基本方法和抽象方法:基本方法: 基本方法也叫做基本操作,由子类实现的方法,并且在模板方法内被调用。
模版方法: 可以有一个或几个,一般是一个具体方法,实现对基本方法的调度,完成固定的逻辑。
# AbstractClass - abstract class - 模版抽象类
abstract class AbstractClass{
// 基本方法
protected abstract void doSomething();
// 基本方法
protected abstract void doAnything();
// 模版方法
public void templateMethod(){
doSomething();
doAnything();
}
}
# ConcereteClass1 - class - 实现方法
public class ConcereteClass1 extends AbstractClass{
// 基本方法
protected void doSomething(){}
// 基本方法
protected void doAnything(){ }
}
# ConcereteClass2 - class - 实现方法
public class ConcereteClass2 extends AbstractClass{
// 基本方法
protected void doSomething(){}
// 基本方法
protected void doAnything(){ }
}
# Client - class - 客户端操作类
public class Client{
public static void main(String []args){
AbstractClass class1 = new ConcereteClass1();
class1.templateMethod();
AbstractClass class2 = new ConcereteClass2();
class2.templateMethod();
}
}
观察者模式(Observer Pattern)
观察者模式(Observer Pattern)也叫做发布-订阅模式(Publish/Subscribe).它是一个在项目中经常使用的模式,其定义如下:
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.(定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。)
- 观察者模式 - 通用类图
观察者模式主要有2种对象: 观察者和被观察者。
被观察者: Subject类。它必须能够动态的添加后删除观察者。(管理和通知观察者)
观察者: Observer类。接受消息后,进行更新操作。(update)
具体被观察者: ConcreteSubject
具体的观察者: ConcreteObserver
另:观察者模式也长被称为
订阅模式(Publish/Subscribe)
# Observer - interface
public interface Observer{
public void Update();
}
# ConcreteObserver - class
public class ConcreteObserver implements Observer{
public void Update(){}
}
# Subject - class - 被观察者
public abstract class Subject{
// 观察者数组
public Vector<Observer> obsVector = new Vector<Observer>();
public void attach(Observer o){
obsVector.add(o);
}
public void detach(Observer o){
obsVector.remove(o);
}
public void notify(){
for(Observer o: obsVector){
o.update();
}
}
}
# ConcreteSubject - class
public class ConcreteSubject extends Subject{
public void doSomething(){
// do something
// 业务逻辑
// 通知
super.notify();
}
}
// Client - 场景类
public class Client{
public static void main(String []args){
// 定义观察者
Observer observer = new ConcreteObserver();
// 定义被观察者
Subject subject = new ConcreteSubject();
// 绑定
subject.attach(subject);
// 被观察者活动 - 并通知观察者
subject.doSomething();
}
}
迭代子模式(Iterator Pattern)
迭代器模式(Iterator Pattern)目前已经是一个没落的模式,基本上没人会单独写一个迭代器,除非是产品性质的开发,其定义如下:
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(它提供一种方法访问一个容器对象中各个元素,而又不需要暴露该对象的内部细节。)
- 迭代子模式 - 通用类图
Aggregate: 抽象容器
ConcreteAggreggate: 具体容器
Iterator: 抽象迭代器
ConcreteIterator: 具体迭代器
# Iterator - interface
public interface Iterator{
// 遍历
public Object next();
// 存在下一个元素
public boolean hasNext();
// 删除当前指向
public boolean remove();
}
public class ConcreteIterator implements Iterator{
private Vector vector = new Vector();
public int cursor = 0;
public ConcreteIterator(Vector _vector){
this.vector = _vector;
}
public boolean hasNext(){
if(this.cursor == this.vector.size){
return false;
}else{
return true;
}
}
public Object next(){
Object result = null;
if(this.hasNext()){
result = this.vector.get(this.cursor++);
}else{
result = null;
}
return result;
}
public boolean remove(){
this.vector.remove(this.cursor);
return true;
}
}
# Aggregate
public interface Aggregate{
//add
public void add(Object object);
//remove
public void remove(Object object);
//foreach
public Iterator iterator();
}
# ConcreteAggregate
pubic class ConcreteAggregate implements Aggregate{
private Vector = new Vector();
public void add(Object object){
this.Vector.add(object);
}
public void remove(Object object){
this.remove(object);
}
public Iterator iterator(){
return new ConcreteIterator(this.vector);
}
}
# Client
public class Client{
public static void main(String []args){
Aggregate agg = new ConcreteAggregate();
agg.add("1");
agg.add("8");
// Iterator 遍历
Iterator ietrator = agg.iterator();
while(iterator.hasNext()){
Object o = iterator.next();
}
}
}
责任链模式(Line Pattern)
责任链模式的定义如下:
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request alonge the chain util an object handles it.(使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象形成一条链,并沿着这条链传递该请求,直到有对象处理它为止。)
- 责任链模式 - 通用类图
# Handler
public abstract class Hander{
private Hander nextHandler;
public void setNext(Handler _handler){
nextHandler = _handler;
}
//public final Response handlerMessage(int level){
public final void handlerMessage(int level){
if(level == getLevel()){
echo();
}else if(null != this.nextHandler){
this.nextHandler.handlerMessage(level);
}else{
// 自行处理,也可以什么都不做
}
}
// 级别管理
private int level;
public void setLevel(int level){
this.level = level;
}
public int getLevel(){
return level;
}
// 当执行任务时输出
public abstract void echo();
}
# ConcreteHandler1
public class ConcreteHandler1 extends Hander{
public abstract void echo(){
System.out.println("ConcreteHandler1"+this.getLevel());
}
}
# ConcreteHandler2
public class ConcreteHandler2 extends Hander{
public abstract void echo(){
System.out.println("ConcreteHandler2"+this.getLevel());
}
}
# ConcreteHandler3
public class ConcreteHandler3 extends Hander{
public abstract void echo(){
System.out.println("ConcreteHandler3"+this.getLevel());
}
}
# Client
public class Client{
public static void main(String []args){
Handler handler1 = new ConcreteHandler1();
handler1.setLevel(1);
Handler handler2 = new ConcreteHandler2();
handler2.setLevel(2);
Handler handler3 = new ConcreteHandler3();
handler3.setLevel(3);
handler1.setNext(handler2);
handler2.setNext(handler3);
// test1
handler1.handlerMessage(3);
// test2
handler1.handlerMessage(1);
// test3
handler1.handlerMessage(9);
}
}
命令模式(Command Pattern)
命令模式是一个高内聚的模式,其定义为:
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者纪录请求日志,可以提供命令的撤销和恢复功能。)
- 命令模式通用类图
# Receiver
public abstract class Receiver{
public abstract void doSomething();
}
# ConcreteReceiver1
public ConcreteReceiver1 extends Receiver{
public void doSomething(){}
}
# ConcreteReceiver2
public ConcreteReceiver2 extends Receiver{
public void doSomething(){}
}
# Command
public abstract class Command{
private Receiver receiver;
public Command(Receiver receiver){
this.receiver = receiver;
}
public abstract void execute();
}
# ConcreteCommand
public class ConcreteCommand{
public ConcreteCommand(Receiver receiver){
super(receiver);
}
public void execute(){
this.receiver.doSomething();
}
}
public class Invoker{
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void action(){
this.command.execute();
}
}
# Client - class
public class Client{
public static void main(String []args){
Receiver receiver1 = new ConcreteReceiver1();
Command command = new ConcreteCommand(receiver1);
Invoker invoker = new Invoker();
invoker.setCommnad(command);
invoker.action();
}
}
备忘录模式(Memento Pattern)
备忘录模式(Memento Patten)提供一种弥补真实世界缺陷的方法,让"后悔药"在程序的世界中真实可行。
Without voilating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.
(在不破坏封装的前提下,捕获一个对象的内部状态,并且在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。)
- 备忘录模式 - 通用类图
Originator: 发起人角色
Memento: 备忘录角色
Caretaker: 备忘录管理员角色
# Memento - class
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;
}
}
# Orginator
public class Orginator{
private String state = "";
public void setState(String state){
this.state = state;
}
public String getState(){
return state;
}
public Memento createMemento(){
return new Mementor(state);
}
public Memento restoreMemento(Memento memento){
this.state = memento.getState();
}
}
# Caretaker
public class Caretaker{
private Memento memento;
public void setMemento(Memento memento){
this.memento = memento;
}
public Memento getMemento(){
return memento;
}
}
# Client
public class Client{
public static void main(String []args){
// 创建发起者
Orginator originrator = new Orginator();
originrator.setState("hello");
// 创建保管人
Caretaker caretaker = new Caretaker();
// 备份状态
caretaker.setMemento(originrator.createMemento);
// 改变状态
originrator.setState("goodBye");
// 回滚状态
originrator.restoreMemento(caretaker.getMemento());
}
}
状态模式(State Pattern)
什么是状态模式,其定义下如下:
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.(当一个对象内在的状态改变时允许其行为改变,这个对象看起来像改变了其类。)
- 状态模式 - 通用类图
State: 抽象状态角色
ConcreteState: 具体状态角色
Context: 环境角色
# State
public abstract class State{
// 提供环境角色 提供子类访问
protected Context context;
public void setContext(Context _context){
this.context = _context;
}
public abstract void handle1();
public abstract void handle2();
}
# ConcreteState
public class ConcreteState1 extends State{
public void handle1(){}
public abstract void handle2(){
// 设置当前状态为状态2
super.context.setCurrentState(Context.STATE2);
// 过度到State2状态,由Context实现
super.context.handle2();
}
}
# ConcreteState
public class ConcreteState2 extends State{
public void handle1(){
// 设置当前状态为状态1
super.context.setCurrentState(Context.STATE1);
// 过度到State2状态,由Context实现
super.context.handle1();
}
public abstract void handle2(){}
}
public class Context{
//定义状态
public final static State STATE1 = new ConcreteState1();
public final static State STATE2 = new ConcreteState1();
private State currentState;
public void setCurrentState(State _state){
this.currentState = _state;
// 切换状态
this.currentState.setContext(this);
}
// 行为委托
public void handle1(){
this.currentState.handle1();
}
// 行为委托
public void handle2(){
this.currentState.handle2();
}
}
public class Client{
public static void main(String []args){
Context context = new Context();
context.setCurrentSate(new ConcreteState1());
// 行为执行
context.handle1();
context.handle2();
}
}
访问者模式(Visitor Pattern)
访问者模式(Visitor Pattern)是一个相对简单的模式,
其定义如下: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.(封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的数据。)
- 访问者模式 - 通用类图
Visitor - 抽象访问者
ConcreteVisitor - 具体访问者
Element - 抽象元素
ConcreteElement - 具体元素
Client - 客户端类
# Element - class
public abstract class Element{
// 定义业务逻辑
public abstract void doSomething();
// 允许谁来访问
public abstract void accept(Visitor visitor);
}
# ConcreteElement - class
public class ConcreteElement1 extends Element{
// 定义业务逻辑
public abstract void doSomething(){}
// 允许谁来访问
public abstract void accept(IVisitor visitor){
visitor.visit(this);
}
}
# IVisitor - interface
public interface IVisitor{
public void accept(Element element);
}
#
public ConcreteVisitor implements IVisitor{
public void accept(Element element){
if(element instance of ConcreteElement1){
// ConcreteElement1
}else if(element instance of ConcreteElement2){
// ConcreteElement2
}else{
// do something
}
}
}
# Client - class
public class Client {
public static void main(String []args){
Element element1 = new ConcreteElement1();
IVisitor visitor = new ConcreteVisitor();
element1.accept(visitor);
}
}
中介者模式(Mediator Pattern)
中介者模式的定义为:
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.(用一个中介对象封装一系列对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。)
- 中介者模式 - 通用类图
Mediator 抽象中介者
ConcreteMediator 实体中介者
Colleague 同事角色。同事角色有2种方法:自发行为(Self-Method)与依赖方法(Dependent Method)。前者角色自身可以实现,后者需要通过中介者进行耦合。
# Mediator - abstract class
public abstract class Mediator{
// 定义同事类(注意此处可能使用接口更加适合)
protected ConcreteColleague1 colleague1;
protected ConcreteColleague2 colleague2;
// Getter/Setter
public ConcreteColleague1 getColleague1(){
return colleague1;
}
public void setColleague1(ConcreteColleague1 colleague1){
this.colleague1 = colleague1;
}
public abstract void doSomething1();
public abstract void doSomething2();
}
# 具体中介者
public class ConcreteMediator extends Mediator{
public abstract void doSomething1(){
// 多个对象类中操作的合集
colleague1.doSomething();
colleague2.doSomething();
}
public abstract void doSomething2(){
colleague1.doSomething();
colleague2.doSomething();
}
}
# 抽象同事类
public absract class Colleague{
protected Mediator mediator;
public Colleague(Mediator mediator){
this.mediator = mediator;
}
}
# 具体抽象类
public class ConcreteColleague1 extends Colleague{
public ConcreteColleague(Mediator mediator){
super(mediator);
}
// 自身私有方法
public void selfMethod(){
}
// 依赖方法
public void depMethod(){
mediator.doSomething1();
}
}
public class ConcreteColleague2 extends Colleague{
public ConcreteColleague(Mediator mediator){
super(mediator);
}
// 自身私有方法
public void selfMethod(){
}
// 依赖方法
public void depMethod(){
mediator.doSomething2();
}
}
# Client - class
public class Client{
public static void main(String []args){
// 定义中介者
Mediator mediator = new ConcreteMediator();
// 定义同事类
Colleague colleague1 = new ConcreteColleague1(mediator);
// 私有方法
colleague1.selfMethod();
// 执行依赖方法
colleague1.depMethod();
}
}
# Caretaker
解释器模式(Interpreter Pattern)
解释器模式(Interpreter Pattern)是一种按照规定语法进行解析的方案,在现在项目中使用较少,其定义如下:
Given a language, define a representation for its grammar alonge with an interpreter that uses the representatin to interpret sentences in the language.(给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。)
- 解释器模式 - 通用类图
Expression: 抽象解释器
TerminalExpression: 终结符表达式
NonterminalExpression: 非终结符表达式
Context: 环境角色
# Expression
public abstract Expression{
// 解析任务
public abstract Object interpreter(Context ctx);
}
public class TerminalExpression extends Expression{
// 通常终结符表达式只有一个,但是有多个对象
public Object interpreter(Context ctx){
return null;
}
}
public class NonterminalExpression extends Expression{
// 每个非终结符表达式都会对其他表达式产生依赖
public NonterminalExpression(Expression ..expression){
}
// 进行解析
public Object interpreter(Context ctx){
return null;
}
}
public class Client{
public static void main(String []args){
Context ctx = new Context();
// 通常定义一个语法容器 容纳一个具体的表达式 通常为 ListArray、LinkedList、Stack等类型
Stack<Expression> stack = new Stack();
for(;;){
// 进行语法判断,产生递归调用
}
//产生一个完整的语法树 由各个具体的语法分析进行解析
Expression exp = stack.pop();
// 具体元素进入场景
exp.interpreter(ctx);
}
}
Reference
[1]. 设计模式之禅
[2]. Java开发中的23种设计模式详解(转)