结构型模式--设计模式详解?

简介: 结构型模式--设计模式详解?


适配器模式:

将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由某个接口不匹配所造成的类的兼容性问题。

类的适配器模式,对象的适配器模式,接口的适配器模式。

类的适配器模式 :可以通过多重继承目标接口和被适配者方法来实现适配。当希望一个类转换满足另一个类的新接口时候,可以使用类适配器创建新类继承原有的类。

对象的适配器模式:使用了不同的方法实现适配,对象适配器使用组合,类的适配器使用继承。当希望将一个对象满足另一个新接口对象时,可以创建wrapper类。

接口的适配器模式:当不需要全部接口实现方法时候,可设计一个抽象类实现接口,并为该接口每个方法提供默认的实现方法,那么该抽象子类可以有选择的覆盖父类某些方法来实现,它使用接口不想使用所有方法的情况。

装饰者模式:

定义:动态的将新功能附加到对象上。增加对象功能扩展性,比继承更有弹性。

装饰者和被装饰者之间必须是一样的类型,也就是共同的超类。因为装饰者和被装饰者是同一个类型,因此装饰者可以取代被装饰者,这样就使被装饰者拥有了装饰者独有的行为。根据这个理解,我们可以在任何时候实现新的装饰者增加新的行为。

代理模式:

定义:给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

静态代理:

public interface BuyBus {

void buyBus();

}

public class BuyBusProxy implements BuyBus{

private BuyService buyService;

BuyBusProxy(BuyService buyService){
    this.buyService = buyService;
}

@Override
public void buyBus() {
    // 买车前干啥
    buyService.buyBus();
    // 买车后干啥
}

}

public class BuyService implements BuyBus{

@Override
public void buyBus() {
    System.out.println("买车");
}

}

优点:复合开闭原则对代码扩展的情况下不修改原有的代码。

缺点:每次都需要新增代理类,工作量大,代码多,一旦改变代理类也要改变。

动态代理:

利用jdk的api来实现代理对象的生成,动态的在内存中构建代理对象,代理的类不需要实现接口,但是要求被代理的对象必须有接口。

public class DynamicProxyHandler implements InvocationHandler {

private Object object;

public DynamicProxyHandler(final Object object) {
    this.object = object;
}

@Override
public Object invoke(Object object, Method method, Object[] args) throws Throwable {
    System.out.println("执行前");
    Object result = method.invoke(object, args);
    System.out.println("执行后");
    return result;
}

}

public static void main(String[] args) {

    BuyServiceImpl buyServiceImpl = new BuyServiceImpl();
    BuyBusService proxyBuy =(BuyBusService) Proxy.newProxyInstance(BuyBusService.class.getClassLoader(),
            new Class[]{BuyBusService.class}, new DynamicProxyHandler(buyServiceImpl));
    proxyBuy.buyBus();
}

动态代理相对于静态代理,节俭了很多代码,提高了复用性,但一样依赖于接口。

cglib代理

动态生成一个要代理的子类,子类重写要代理类的所有不是final方法,子类中采用方法拦截技术拦截所有父类方法调用,横切逻辑,优于jdk动态代理。

缺点是对final方法无法进行代理。

public class CglibProxy implements MethodInterceptor {

private Object object;
public Object getInstance(Object object){
    this.object = object;
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(this.object.getClass());
    enhancer.setCallback(this);
    return enhancer;
}

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    System.out.println("执行前准备");
    Object result = methodProxy.invoke(o,objects);
    System.out.println("执行后准备");
    return result;
}

}

public static void main(String[] args) {

    BuyBusService buyBusService = new BuyServiceImpl();
    CglibProxy cglibProxy = new CglibProxy();
    BuyServiceImpl proxyBuy = (BuyServiceImpl)cglibProxy.getInstance(buyBusService);
    proxyBuy.buyBus();
}

cglib的性能比jdk动态代理性能更好,但是cglib创建对象比jdk创建对象耗时更多,所以单例模式下,无需频繁创建对象用cglib更合适,而且cglib因为动态创建子类,所以final修饰的无法代理。

外观模式

隐藏系统的复杂性,并且向客户端提供一个可以访问的接口。

核心的功能就是门面角色 整合所有子系统角色,方便外部统一访问。

public class Fang {

private Deng deng;
private Door door;

public void open(){
    System.out.println("进入房间");
    deng.open();
    door.open();
}
public void close(){
    System.out.println("出去房间");
    deng.close();
    door.close();
}

}

public class Door {

public void open(){
    System.out.println("开门");
}
public void close(){
    System.out.println("关门");
}

}

public class Deng {

public void open(){
    System.out.println("开灯");
}
public void close(){
    System.out.println("关灯");
}

}

外观模式优点是访问对于客户端更简洁明了,不需要在乎他内部调用多少服务。

桥接模式

定义:将抽象部分与它的实现部分分离,使他们可以独立变化。

public interface Software {

public void run();

}

public abstract class Phone {

public abstract void run();

}

public class AppStore implements Software{

@Override
public void run() {
    System.out.println("app start run");
}

}

public class Camera implements Software{

@Override
public void run() {
    System.out.println("Camera start run");
}

}

继承是一种强耦合,通过桥接把他们关联起来,如同弱耦合,从这里可以看出聚合是一种比继承要弱的关系,两个都可以独立进行变化,不会相互影响。

当两个类存在独立的变化维度,且两个类都需要独立扩展的时候。

组合模式

又叫做部分-整体模式,将对象组合成树状的层次结构模式,表示部分-整体的关系,使用户对单个对象和组合对象具有一定访问一致性。

模糊了简单元素与复杂元素的概念,客户端可以处理简单元素一样来处理复杂元素,从而使客户程序与复杂元素内部解耦。

缺点就是客户端需要花费更多的时间来处理层次关系。

享元模式

通过共享的方式高效的支持大量细颗粒对象。

当有大对象的时候,可能会造成内存溢出,我们把其中共同部分抽象出来,如果有相同的业务请求,直接返回内存已有对象。

用唯一标识码,如果在内存中有,则返回唯一标识码标识的对象。hashmap,java中的String如果有则返回,没有则创建一个字符串保存在字符串缓存池中

相关文章
|
7月前
|
设计模式 前端开发 调度
中介者模式--设计模式
中介者模式--设计模式
72 0
中介者模式--设计模式
|
7月前
|
设计模式
装饰器模式--设计模式
装饰器模式--设计模式
44 0
|
7月前
|
设计模式 Java Linux
适配器模式--设计模式
适配器模式--设计模式
41 0
|
7月前
|
设计模式
抽象工厂模式--设计模式
抽象工厂模式--设计模式
48 0
|
7月前
|
设计模式 缓存 容器
组合模式--设计模式
组合模式--设计模式
33 0
|
7月前
|
设计模式 存储 数据库
享元模式--设计模式
享元模式--设计模式
37 0
|
设计模式 Java
设计模式(15) -- 装饰者模式
设计模式(15) -- 装饰者模式
设计模式(15) -- 装饰者模式
|
设计模式 前端开发 调度
设计模式(25) -- 中介者模式
设计模式(25) -- 中介者模式
设计模式(25) -- 中介者模式
|
设计模式 Java
设计模式(16) -- 组合模式
设计模式(16) -- 组合模式
设计模式(16) -- 组合模式
|
设计模式 Java
设计模式(12) -- 建造者模式
设计模式(12) -- 建造者模式
设计模式(12) -- 建造者模式