likes
comments
collection
share

结构型-桥接、装饰、适配、代理(笔记整理)

作者站长头像
站长
· 阅读数 38

结构型-桥接模式

桥接:强调类的组合(函数抽象自由组合)

// 颜色 → 实现部分
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
评论
请登录