我的理解:所谓的结构化,就是根据对应的业务场景,通过实现、继承、组合等各种方式调整对象之间的结构来达到需求目的。结构化设计模式当中,代理模式、装饰器模式、外观模式在编码的形式上的风格都非常的类似,在学习的过程当中其实更应该关注设计模式对应解决的问题;另,代码是手敲的,可能存在错误
适配器模式
概念
- 适配器模式是将一个接口A的功能,转换成接口B的功能。目的是提升接口A的复用性
- 目的:降低coding成本
应用场景
- 实际应用中多用于系统重构。在新的系统结构代码中,设计了新的接口,但是为了复用老系统结构中的接口服务,就可以采用适配器模式,将老系统结构中的接口适配都新的系统结构中
UML
code
- Adaptee Object -> 输出250v电压
public class Adaptee {
public Integer supplyInterPower() {
return 250;
}
}
- Target 接口 -> 需要220v电压
public interface Target {
//need 220v volatge
public Integer supplyInnerPower();
}
- Adapter -> 适配Apdatee,将250v电压转换成220v
public class Adapter implement Target {
private Adaptee adaptee;
public Integer supplyInnerPower() {
return adaptee.supplyInterPower() - 30;
}
}
组合模式
概念
- 组合模式是将一组相似对象组合成一个单个对象来进行使用。通常是以树形结构出现,然后暴露根节点给客户端(使用方),客户端通过根节点调度这一组相似对象
- 目的:降低客户端使用成本。操作一组对象转换成操作单个对象
UML
应用场景
- java.util.concurrent.CompletableFuture#allOf
code
- Base Component
public interface Shape {
public void draw();
}
- Leaf Compnent
public class Circle implement Shape {
public void draw() {
System.out.println("draw a circle");
}
}
public class Square implement Shape {
public void draw() {
System.out.println("draw a square");
}
}
public class Triangle implement Shape {
public void draw() {
System.out.println("draw a triangle");
}
}
- Composite
- 此处用List的形式,常见是树结构
public class Drawing implement Shape {
private List<Shape> shapes;
public void draw() {
shapes.forEach(Shape::draw);
}
}
代理模式
概念
- 当对象不能够直接被访问的时候,增加代理类作为中间层
UML
应用场景
- jdk copy-on-write proxy
code
public interface Query {
public String queryCertificateNo(String userName);
}
public class UnSafeQuery implement Query {
private String certificateNo;
public String queryCertificateNo(String userName) {
return
}
}
public class ProxyQuery implement Query {
private Query unSafeQuery;
public String queryEncryptCertificateNo(String userName) {
String no = unSafeQuery.queryCertificateNo();
return "123" + no + "789";
}
public String queryCertificateNo(String userName) {
throw new UnsupportedOperationException();
}
}
装饰器模式
概念
- 在不影响其它实例的场景下,动态的给其中一个实例添加更多功能,并且实例和实例之间可以随意组装其和代理模式的差别在于:代理模式是为了屏蔽真实对象,装饰器模式是为了增强对象
应用场景
- 没有找到著名case
UML
Code
- Car
public interface Car {
public void assemble();
}
- BasicCar
public class BasicCar implements Car {
public void assemble() {
System.out.println("assemble basic car")
}
}
- CarDecorator
public class CarDecorator implements Car {
//被装饰的对象
protected Car car;
public CarDecorator(Car car) {
this.car = car;
}
public void assemble() {
System.out.println("assemble basic car")
}
}
- SportsCar
public class SportsCar extends CarDecorator {
public SportsCar(Car c) {
super(c);
}
public void assemble() {
car.assemble();
System.out.println("add sports element");
}
}
- LuxuryCar
public class LuxuryCar extends CarDecorator {
public SportsCar(Car c) {
super(c);
}
public void assemble() {
car.assemble();
System.out.println("add luxury element");
}
}
- ClientDemo
- 重点在客户端使用的时候随意组装
public class ClientDemo {
public static void main(String[] args) {
//1. 组装sports元素
Car car = new SportsCar(new BasicCar());
car.assemble();
//2. 组装luxury元素
Car newCar = new LuxuryCar(car);
newCar.assemble();
}
}
外观模式
概念
- 向客户端隐藏系统复杂度,降低客户端使用成本,好处是子系统相对独立,而客户端使用简便
应用场景
- 著名case: slf4j-api -> 大型facade
示意图
Code
- 没有源代码
亨元模式
概念
- 对象维护在一个容器当中,避免构造相同对象,降低内存使用率。目的是为了避免重复建造对象,多体现在工厂模式当中
应用场景
- Java中的String
- 连接池技术
UML
Code
- org.apache.tomcat.jdbc.pool.ConnectionPool
- tomcat-jdbc ConnectionPool中维护了两个
- BlockingQueue busy;
- BlockingQueue idle;
桥接模式
概念
-
桥接是用于把抽象化与实现化解耦,使得二者可以独立变化,防止通过继承发生类的个数爆炸的场景,注意,这只是一个相对的情况。具体场景可设想为:有一个图形接口Shape,通过继承实现接口,衍生了多个实现类,红色的正方形(RedSquare)和黄色的正方形(YellowSquare)等,为了满足不同的颜色和不同的形状的组合,会产生多个实现类,这个时候,可以通过桥接模式,将两个变化的元素抽离,让颜色和形状可以独立变化
-
目的解耦抽象化的部分,保证顶层设计不变
应用场景
- java.sql.DriverInfo
UML
Code
背景
- Shape
public interface Shape {
public void applyColor();
}
- RedSquare
public class RedSquare implements Shape {
public void applyColor() {
//do something with red square
}
}
- YellowCircle
public class YellowSquare implements Shape {
public void applyColor() {
//do something with yellow circle
}
}
- 随着诉求的不断迭代,Shape的实现类个数,会呈现指数增长
运用桥接模式来拆解Shape
- Shape
public abstract class Shape {
protected Color color;
public Shape(Color c){
this.color=c;
}
abstract public void applyColor();
}
- Color
public interface Color {
public void supplyColor();
}
- Square
public class Square extends Shape {
public Square(Color c) {
super(c);
}
@Override
public void applyColor() {
//do something with private member 'color'
}
}
- Red
public class Red implements Color {
@Override
public void supplyColor() {
//supply red
}
}
- Yellow
public class Yellow implements Color {
@Override
public void supplyColor() {
//supply yellow
}
}
- Demo
public class Demo {
public static void main(String[] args) {
Shape RedSqaure = new Square(new Red());
Shape YellowSquare = new Square(new Yellow());
//后续诉求如果出现其他颜色的Sqaure,Square可以复用
//后续诉求如果针对现有颜色需要提供其它形状,现有的Color的实现类可以独立变化
//将颜色和形状解耦,保持独立变化,提高类的复用性
}
}