结构型模式(Structural Pattern)
-
适配器模式(包装器(Wrapper))(Adapter)
- 类适配器(通过继承)、对象适配器(通过组合(成员变量))、接口适配器(通过抽象类/接口方法空实现)
- 将一个接口转换成另一个接口,使接口不兼容的那些类可以一起工作
- 一个对象适配器可以把多个不同的适配者适配到同一个目标,但Java单继承,不支持
- 模式应用:JDBC驱动软件都是一个介于JDBC接口和数据库引擎接口之间的适配器软件
-
桥接模式(Bridge)
- 对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式
- 如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”
- 最密切的维度设计为“抽象类”层次结构(抽象部分),而将另一个维度设计为“实现类”层次结构(实现部分)
Abstraction pa = new RefinedAbstraction(new ConcreteImplementorA()); pa.operation(); Abstraction pb = new RefinedAbstraction(new ConcreteImplementorB()); pb.operation();
-
组合模式(Composite)
- 又称部分整体模式,是用于把一组相似的对象当作一个单一的对象。
- 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
- 典型应用:操作系统的文件/目录结构
-
装饰者模式(Decorator)
- 别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合
- 装饰模式也有人称之为“油漆工模式”,它是一种对象结构型模式
- 装饰模式,突出的是运行期增加行为,这和继承是不同的,继承是在编译期增加行为
- 装饰模式包含四个角色:
- 抽象构件定义了对象的接口,可以给这些对象动态增加职责(方法);
- 具体构件定义了具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法);
- 抽象装饰类是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现;
- 具体装饰类是抽象装饰类的子类,负责向构件添加新的职责
//抽象构件 public abstract class Person { public abstract void eat(); } //具体构件 public class NormalPerson extends Person { public void eat() println("吃饭"); } //抽象装饰类 public class PersonFood extends Person { private Person person; public PersonFood(Person person){ this.person = person; } public void eat() { person.eat(); } } //具体装饰类 public class ExpensiveFood extends PersonFood { public ExpensiveFood(Person person) { super(person); } public void eat() { super.eat(); eatSteak(); drinkRedWine(); } public void eatSteak() println("吃牛排"); public void drinkRedWine() println("喝拉菲"); }
-
外观模式(门面模式)(Facade)
- 外观模式又称为门面模式,它是一种对象结构型模式
- 外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,
- 外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
-
享元模式(Flyweight)
- 享元模式通过共享技术实现相同或相似对象的重用:
- 可以共享的相同内容称为内部状态(IntrinsicState),
- 那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State)
- 在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象
- 典型应用:String常量池,数据库连接池
public abstract class Flyweight { public String intrinsic = "Flyweight";//内部状态 protected final String extrinsic;//外部状态 //要求享元角色必须接受外部状态 public Flyweight(String extrinsic) { this.extrinsic = extrinsic; } //定义业务操作 public abstract void operate(int extrinsic); //TODO intrinsic内部状态的get/set方法 } public class ConcreteFlyweight extends Flyweight { public ConcreteFlyweight(String extrinsic) { super(extrinsic); } public void operate(int extrinsic) { System.out.println("具体Flyweight:" + extrinsic); } } 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); System.out.print("已有 " + extrinsic + " 直接从池中取---->"); } else { flyweight = new ConcreteFlyweight(extrinsic); pool.put(extrinsic, flyweight); System.out.print("创建 " + extrinsic + " 并从池中取出---->"); } return flyweight; } public static int getCount(){ return pool.size(); } }
- 享元模式通过共享技术实现相同或相似对象的重用:
-
代理模式(Proxy)
- 可分为三类:静态代理,动态代理,Cglib代理(Code Generation Library)子类代理)
- VS装饰者模式:
- 代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,
- 而装饰者能够在运行时递归地被构造