结构型-桥接、装饰、适配、代理(笔记整理)
结构型-桥接模式
桥接:强调类的组合(函数抽象自由组合)
// 颜色 → 实现部分
public interface IColor {
String draw();
}
// 红色、蓝色 → 实现部分具体实现
public class Red implements IColor {
@Override public String draw() { return "红色"; }
}
public class Blue implements IColor {
@Override
public String draw() { return "蓝色"; }
}
// 形状 → 抽象部分
abstract class Shape {
// 形状持有颜色引用,颜色引用通过构造函数注入,这就是桥接过程
protected IColor color;
public Shape(IColor color) { this.color = color; }
abstract void show();
}
// 圆型、矩形 → 抽象部分扩展
public class Circle extends Shape {
public Circle(IColor color) { super(color); }
@Override void show() { System.out.println(color.draw() + "圆形"); }
}
public class Square extends Shape {
public Square(IColor color) { super(color); }
@Override void show() { System.out.println(color.draw() + "矩形"); }
}
// 测试用例
public class CircleTest {
public static void main(String[] args) {
Shape redCircle = new Circle(new Red());
Shape blueSquare = new Square(new Blue());
redCircle.show();
blueSquare.show();
}
}
上述大概是形状和颜色之分,各自有不同分类,如矩形、圆形,红色、蓝色。 以其中一个作为基准如shape类,组合IColor。 如不使用桥接可能是这种代码
abstract class Shape {
abstract void show();
}
public class Circle extends Shape {
@Override void show() { System.out.println("圆形"); }
}
public class Square extends Shape {
@Override void show() { System.out.println("矩形"); }
}
public class RedCircle extends Shape {
@Override void show() { System.out.println("红色圆形"); }
}
public class RedSquare extends Shape {
@Override void show() { System.out.println("红色矩形"); }
}
public class BlueCircle extends Shape {
@Override void show() { System.out.println("蓝色圆形"); }
}
public class BlueSquare extends Shape {
@Override void show() { System.out.println("蓝色矩形"); }
}
装饰器模式
装饰:强调对现有类(如BaseDecorator)的功能新增而不改变其自有结构
// 抽象组件(接口和抽象类都可以)
interface IShape {
String show();
}
// 抽象装饰类(内部有一个指向组件对象的引用,用来调装饰前对象的方法)
public abstract class BaseDecorator implements IShape {
private IShape shape;
public BaseDecorator(IShape shape) { this.shape = shape; }
@Override public String show() { return shape.show(); }
}
// 具体组件类
public class CircleShape implements IShape {
@Override public String show() { return "圆形"; }
}
public class SquareShape implements IShape {
@Override public String show() { return "矩形"; }
}
// 颜色具体装饰类(可调用抽象装饰类中定义的方法,也可新增方法来扩展对象行为)
public class RedDecorator extends BaseDecorator {
public RedDecorator(IShape shape) { super(shape); }
@Override public String show() { return "红色" + super.show(); }
}
public class BlueDecorator extends BaseDecorator {
public BlueDecorator(IShape shape) { super(shape); }
@Override public String show() { return "蓝色" + super.show(); }
}
// 材质具体装饰类
public class SmoothDecorator extends BaseDecorator {
public SmoothDecorator(IShape shape) { super(shape); }
@Override public String show() { return "光滑" + super.show(); }
}
public class MatteDecorator extends BaseDecorator {
public MatteDecorator(IShape shape) { super(shape); }
@Override public String show() { return "磨砂" + super.show(); }
}
// 大小具体装饰类
public class BigDecorator extends BaseDecorator {
public BigDecorator(IShape shape) { super(shape); }
@Override public String show() { return "大" + super.show(); }
}
public class MiddleDecorator extends BaseDecorator {
public MiddleDecorator(IShape shape) { super(shape); }
@Override public String show() { return "中" + super.show(); }
}
public class SmallDecorator extends BaseDecorator {
public SmallDecorator(IShape shape) { super(shape); }
@Override public String show() { return "小" + super.show(); }
}
// 测试用例
public class DecoratorTest {
public static void main(String[] args) {
IShape circle = new CircleShape();
IShape square = new SquareShape();
IShape redCircle = new RedDecorator(circle);
IShape smoothBlueSquare = new SmoothDecorator(new BlueDecorator(square));
IShape bigMatteRedCircle = new BigDecorator(new MatteDecorator(redCircle));
System.out.println(circle.show());
System.out.println(square.show());
System.out.println(redCircle.show());
System.out.println(smoothBlueSquare.show());
System.out.println(bigMatteRedCircle.show());
}
}
结构型-适配器模式
适配器:强调对现有类函数的功能补全
// 需要适配的接口
public class English {
void speakEnglish(String talk) {
System.out.println("【英语】" + talk);
}
}
// 目标接口
interface Chinese {
void speakChinese(String talk);
}
// 适配器角色
public class ClassTranslator extends English implements Chinese {
@Override
public void speakChinese(String talk) {
// 可调用父类方法或直接进行重写
super.speakEnglish(talk);
System.out.println("假装请求了翻译接口,输出翻译结果:【中文】玛卡巴卡");
}
}
// 测试用例
public class AdapterTest {
public static void main(String[] args) {
Chinese translator = new ClassTranslator();
translator.speakChinese("Ma ka ba ka");
}
}
结构型-代理模式
适配器:将类中需要代理的接口抽象
静态代理
// 抽象主题
public interface ShoppingOverseas {
void shopping(String thing);
}
// 主题实现类
public class OverseasShop implements ShoppingOverseas {
@Override
public void shopping(String thing) {
System.out.println("海外商家卖出一件:" + thing);
}
}
// 代理类
public class ShoppingProxy implements ShoppingOverseas {
OverseasShop shop = new OverseasShop();
@Override
public void shopping(String thing) {
System.out.println("代购收到你的下单信息");
shop.shopping(thing);
System.out.println("代购帮你在海外商家买了:" + thing);
}
}
// 测试用例
public class ProxyTest {
public static void main(String[] args) {
ShoppingProxy proxy = new ShoppingProxy();
proxy.shopping("鞋子");
}
}
动态代理
JDK动态代理
→ 底层依赖反射机制,被代理类要实现接口方法,通过invokeHandler对所需方法进行增强;- ① 定义代理接口;
- ② 真实对象实现这个代理接口;
- ③ 定义动态代理类,实现 InvocationHandler 接口,重写invoke()方法,做些小动作;
- ④ 调用Proxy类创建的代理类;
// 代理接口
public interface Shopping {
void shopping(String thing);
void pay();
}
// 实现代理接口的真实对象(这里定义了2个)
public class FirstShoppingImpl implements Shopping {
@Override
public void shopping(String thing) { System.out.println("在一号商家购买:" + thing); }
@Override
public void pay() { System.out.println("在一号商家付款"); }
}
public class SecondShoppingImpl implements Shopping {
@Override
public void shopping(String thing) { System.out.println("在二号商家购买:" + thing); }
@Override
public void pay() { System.out.println("在二号商家付款"); }
}
// 动态代理类
public class DynamicShoppingProxy implements InvocationHandler {
private Shopping object; // 委托类对象
public DynamicShoppingProxy(Shopping object) {
this.object = object;
}
/**
* @param proxy 被代理的对象
* @param method 被代理对象的方法
* @param args 方法的参数
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("shopping")) {
System.out.println("开始购物...");
// 反射调用类里的实际方法,返回方法的返回值,没有返回值的话返回null
method.invoke(object, args);
System.out.println("结束购物...");
} else if (method.getName().equals("pay")) {
System.out.println("开始付款...");
method.invoke(object, args);
System.out.println("结束付款...");
}
return null;
}
}
// 测试用例:调用Proxy类创建的代理类
public class DynamicProxyTest {
public static void main(String[] args) {
// 生成的动态代理文件保存到当前项目的com/sun/proxy目录下
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
// 创建动态代理实例
DynamicShoppingProxy proxy1 = new DynamicShoppingProxy(new FirstShoppingImpl());
DynamicShoppingProxy proxy2 = new DynamicShoppingProxy(new SecondShoppingImpl());
// newProxyInstance()动态生成代理类,参数依次为:类加载器(要仅限代理的类)、被代理类实现的接口,动态代理实例
Shopping s1 = (Shopping) (Proxy.newProxyInstance(Shopping.class.getClassLoader(),
new Class[]{Shopping.class}, proxy1));
System.out.println(s1.getClass().getName());
s1.shopping("鞋子");
Shopping s2 = (Shopping) (Proxy.newProxyInstance(Shopping.class.getClassLoader(),
new Class[]{Shopping.class}, proxy2));
System.out.println(s2.getClass().getName());
s2.shopping("衣服");
s2.pay();
}
}
CGLIB代理
→ 利用ASM框架,修改字节码生成子类来处理; CGLIB需要用到两个jar包,asm.jar
→ 字节码增强技术的核心,cglib.jar
→ CGLIB库
// 被代理类
public class Store {
public void sell(String thing) {
System.out.println("商家卖:" + thing);
}
public void close() {
System.out.println("关门大吉");
}
}
// 方法增强类
public class StoreTrade implements MethodInterceptor {
/**
* @param o 要增强的对象
* @param method 要拦截的方法
* @param objects 方法中的参数
* @param methodProxy 对方法的处理
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable{
System.out.println("Before Method === " + method.getName());
System.out.println("传入的方法参数:" + Arrays.toString(objects));
methodProxy.invokeSuper(o, objects);
System.out.println("After Method === " + method.getName());
return null;
}
}
// 测试用例
public class StoreTest {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer(); // 增强类对象
enhancer.setSuperclass(Store.class); // 设置要增强的类
StoreTrade store = new StoreTrade();
enhancer.setCallback(store); // 设置要增强的方法
Store s = (Store) enhancer.create(); // 生成增强过的子类encodings
s.sell("牛奶");
s.close();
}
}
转载自:https://juejin.cn/post/6987275049640132615