【设计模式】设计模式之结构型模式(适配器、桥接、组合、装饰、外观、享元、代理)

1、设计模式

2、结构型模式

2.1 概述
  • 结构型模式(Structural Pattern): 描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构
  • 结构型模式可以分为类结构型模式和对象结构型模式:

1、类结构型模式关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。

2、对象结构型模式关心类与对象的组合,通过关联关系使得在一个类中定义另一个类的实例对象,然后通过该对象调用其方法。根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。

2.2 七大结构型设计模式
2.2.1 适配器模式

2.2.1.1 概念

  • 适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,使接口不兼容的类可以一起工作,别名包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
  • 适配器模式主要目的组合两个不相干类。常用有两种方法,第一种解决方案是修改各自类的接口,但如果没有源码,或不愿意为一个应用而修改各自的接口,则需要使用 Adapter 适配器,在两种接口之间创建一个混合接口。
  • 图解:
    在这里插入图片描述
  • 适用环境:

1、系统需要使用现有的类,而这些类的接口不符合系统的需要。

2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作

2.2.1.2 适配器模式代码案例:

/**
 * 定义客户端使用的接口,与业务相关
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/4
 */
public interface Target {
   

    /**
     * 客户端请求处理的方法
     */
    void request();
}

/**
 * 已经存在的接口,这个接口需要配置
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/4
 */
@Slf4j
public class Adaptee {
   

    /**
     * 原本存在的方法
     */
    public void specificRequest(){
   

        log.info("【已经存在的接口】");
    }
}

/**
 * 适配器
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/4
 */
public class Adapter implements Target{
   
    /**
     * 持有需要被适配的接口对象
     */
    private Adaptee adaptee;
    /**
     * 构造方法,传入需要被适配的对象
     * @param adaptee 需要被适配的对象
     */
    public Adapter(Adaptee adaptee){
   
        this.adaptee = adaptee;
    }
    @Override
    public void request() {
   
        adaptee.specificRequest();
    }

}
/**
 * 使用适配器的客户端
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/4
 */
public class Client {
   
    public static void main(String[] args){
   
        //创建需要被适配的对象
        Adaptee adaptee = new Adaptee();
        //创建客户端需要调用的接口对象
        Target target = new Adapter(adaptee);
        //请求处理
        target.request();
    }
}

2.2.1.3 JDK 中的适配器使用:

  • 使用适配器模式的类

java.util.Arrays#asList()
java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)

  • Java I/O 库大量使用了适配器模式,如 ByteArrayInputStream 是一个适配器类,它继承了 InputStream 的接口,并且封装了一个 byte 数组。换言之,它将一个 byte 数组的接口适配成 InputStream 流处理器的接口。

  • 在 OutputStream 类型中,所有的原始流处理器都是适配器类。ByteArrayOutputStream 继承了 OutputStream 类型,同时持有一个对 byte 数组的引用。它将一个 byte 数组的接口适配成 OutputString 类型的接口,因此也是一个对象形式的适配器模式的应用。

  • FileOutputStream 继承了 OutputStream 类型,同时持有一个对 FileDiscriptor 对象的引用。这是一个将 FileDiscriptor 接口适配成 OutputStream 接口形式的对象型适配器模式。

  • Reader 类型的原始流处理器都是适配器模式的应用。StringReader 是一个适配器类,StringReader 类继承了 Reader 类型,持有一个对 String 对象的引用。它将 String 的接口适配成 Reader 类型的接口。

2.2.1.4 适配器模式总结:

1、适配器模式用于将一个接口转换成客户希望的另一个接口,使接口不兼容的类可以一起工作,别名包装器。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

2、适配器模式包含四个角色:1、目标抽象类定义客户要用的特定领域的接口;2、适配器类可以调用另一个接口,作为一个转换器,对适配者和抽象目标类进行适配,它是适配器模式的核心;3、适配者类是被适配的角色,它定义了一个已经存在的接口,这个接口需要适配;4、在客户类中针对目标抽象类进行编程,调用在目标抽象类中定义的业务方法。

3、在类适配器模式中,适配器类实现了目标抽象类接口并继承了适配者类,并在目标抽象类的实现方法中调用所继承的适配者类的方法;在对象适配器模式中,适配器类继承了目标抽象类并定义了一个适配者类的对象实例,在所继承的目标抽象类方法中调用适配者类的相应业务方法。

4、适配器模式的主要优点是将目标类和适配者类解耦,增加了类的透明性和复用性,同时系统的灵活性和扩展性都非常好,更换适配器或者增加新的适配器都非常方便,符合“开闭原则”;类适配器模式的缺点是适配器类在很多编程语言中不能同时适配多个适配者类,对象适配器模式的缺点是很难置换适配者类的方法。

5、适配器模式适用情况包括:系统需要使用现有的类,而这些类的接口不符合系统的需要;想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类一起工作。

2.2.2 桥接模式

2.2.2.1 概念

  • 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
  • 桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则。
  • 举例:绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,则需要4*3=12个类,这时候我们就可以用桥接模式,一个形状,一个颜色,将这两个维度分离开来,每一个维度都可以独立扩展。
  • 结构 :

1、Abstraction:抽象类(形状绘制抽象类)

2、RefinedAbstraction:具体类:具体形状绘制抽象类

3、Implementor:实现类接口,这里指颜色

4、ConcreteImplementor:具体实现类,具体颜色

2.2.2.2 桥接模式代码案例:

/**
 * 填充色
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/5
 */
public interface Colour {
   

    /**
     * 填充
     */
    void fill();
}
/**
 * 红色填充色
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/5
 */
@Slf4j
public class RedColour implements Colour {
   
    @Override
    public void fill() {
   

        log.info("填充红色!");
    }
}
/**
 * 蓝色填充色
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/5
 */
@Slf4j
public class BlueColour implements Colour {
   
    @Override
    public void fill() {
   

        log.info("填充蓝色!");
    }
}
/**
 * 绘制图形抽象类
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/5
 */
public abstract class AbstractionShape {
   

    public Colour colour;

    public void SetColour(Colour colour){
   
        this.colour = colour;
    }

    public  abstract  void Shape();
}

/**
 * 圆形
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/4/5
 */
@Slf4j
public class 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值