结构型模式

  • 如何组合类和对象以获得更大的结构

适配器

将一个接口转换成另一个接口

  • 双向适配器
interface Target{
    void ops();
}

class Adaptee{
    public void run() { }
}

class Adapter implements Target{
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void ops() {
        // do something
        adaptee.run();
    }
}
// 使用
Target target = new Adapter(new Adaptee());
target.ops();

分类:

  • 类适配器
  • 对象适配
  • 接口适配方式

桥接

将抽象部分与实现部分分离,使它们都可以独立地变化

abstract class Window {
    //...
    abstract setMenu(Menu menu)
}
interface Menu{}

class LinuxWindow extends Window{...}
class MacWindow extends Window{...}

class PlainMenu implements Menu{...}
class RichMenu implements Menu{...}

组合

将对象组合成树形结构的部分-整体层次结构,使得客户使用单个对象或组合对象都有一致性

屏幕截图 2021-05-27 162917

interface Route {
    Route segement1, segement2;
} // 路线
class NationalHighway implements Route{} // 国道
class CountryRoad implements Route {} // 乡道

组合模式很重要的一点就是客户端使用所有节点的方式都相同,同时这些节点内部又以组合的方式组合其他节点。

装饰器

给一个对象添加额外的职责

装饰器与被装饰的对象都拥有同一个接口,所以说,装饰器对客户来说是透明的

abstract class InputStream{...}
class FileInputStream extends InpurStream{...}

外观

为系统中的一组接口提供一致的界面

class Facade{
    private SubSystem1 subSystem1;
    private SubSystem2 subSystem2;

    void ops(){
        subSystem1.ops1();
        subSystem2.ops2();
    }
}
// 使用
Facade facade = new Facade();
facade.ops();

享元

共享系统中大量的细粒度对象

  • 提高性能

class MessageFactory{
    Message getHeartBeatMeessage();
}
interface Message{...}
class HeartBeatMessage implements Message{...}

代理

为其他对象提供一个代理访问控制

  • 又称为委托模式

静态代理

  • 结构简单,代码繁琐

interface Subject{
    void run();
}
class Proxy implements Subject{
    private Subject realObject = new RealSubject();
    void run(){
        //before
        realObject.run();
        //after
    }
}

// 使用
Subject subject = new Proxy();
subject.run();

动态代理

  • JDK动态代理
SubjectImpl impl = new SubjectImpl();
Subject proxy = (Subject) Proxy.newProxyInstance(impl.getClass().getClassLoader(), 
                impl.getClass().getInterfaces(), (proxy1, method, args1) -> {
    System.out.println("pre invoke");
    return method.invoke(impl, args1);
});
proxy.request();

如果多个接口重名,则调用接口方法以第一个接口为主

  • cglib动态代理
Enhancer enhancer = new Enhancer();
Object target = new Object();
enhancer.setSuperclass(Object.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> {
    System.out.println(method+" invoke");
    return method.invoke(target, args1);
});
Object o = enhancer.create();
System.out.println(o.hashCode());

generation gap(生成模式)

该模式会生成代码导出行为 再通过编程来丰富程序行为 只修改或扩展一次 而可以生成代码多次 win下的GUI设计好像就这么做的

屏幕截图 2020-12-23 162057

问题:

需求变化导致生成代码的变化

解决方式一是警告禁止修改 二是计算代码差异重新生成 三则是隐藏生成的代码的细节 隔离变与不变

results matching " "

No results matching " "

results matching " "

No results matching " "