结构型模式

Wu Jun 2020-01-06 07:43:49
Categories: > Tags:

1. Adapter(适配器)

将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,别名包装器(Wrapper)。

如非必要,可以重构

模式应用
待适配

待适配

public class Source {
    public void method1() {}
}

目标接口

public interface Targetable {

    /* 与原类中的方法相同 */
    public void method1();

    /* 新类的方法 */
    public void method2();
}

1 类的适配器模式

Adapter 类继承 Source 类,实现 Targetable 接口

public class Adapter extends Source implements Targetable {

    @Override
    public void method2() {
        System.out.println("this is the targetable method!");
    }
}

2 对象的适配器模式

持有 Source 类的实例

public class Wrapper implements Targetable {

    private Source source;
    
    public Wrapper(Source source){
        super();
        this.source = source;
    }

    @Override
    public void method1() {
        source.method1();
    }
    
    @Override
    public void method2() {
        System.out.println("this is the targetable method!");
    }
}

3 接口的适配器模式

不希望实现一个接口中所有的方法时,通过抽象类实现该接口,再继承抽象类

public abstract class Wrapper2 implements Targetable{
    public void method1(){}
    public void method2(){}
}

public class SourceSub1 extends Wrapper2 {
    public void method1(){
        System.out.println("the sourceable interface's first Sub1!");
    }
}

2. Bridge(桥接)

将类的功能层次结构和实现层次结构相分离,使二者能够独立地变化,并在两者之间搭建桥梁,实现桥接。

模式应用

实现

1.桥接接口,实体类 RedCircle、GreenCircle 实现了 DrawAPI 接口

public interface DrawAPI {
   public void drawCircle(int radius, int x, int y);
}

2.使用桥接的抽象类

public abstract class Shape {
   protected DrawAPI drawAPI;
   protected Shape(DrawAPI drawAPI){
      this.drawAPI = drawAPI;
   }
   public abstract void draw();  
}

3.抽象类的实体类。

public class Circle extends Shape {
   private int x, y, radius;
 
   public Circle(int x, int y, int radius, DrawAPI drawAPI) {
      super(drawAPI);
      this.x = x;  
      this.y = y;  
      this.radius = radius;
   }
 
   public void draw() {
      drawAPI.drawCircle(radius,x,y);
   }
}

4.使用

Shape redCircle = new Circle(100,100, 10, new RedCircle());
Shape greenCircle = new Circle(100,100, 10, new GreenCircle());

redCircle.draw();
greenCircle.draw();

3. Composite(组合)

将对象组合成树形结构来表示“整体/部分”层次关系,允许用户以相同的方式处理单独对象和组合对象。

组件(Component)类是组合类(Composite)和叶子类(Leaf)的父类,可以把组合类看成是树的中间节点。

组合对象拥有一个或者多个组件对象,因此组合对象的操作可以委托给组件对象去处理,而组件对象可以是另一个组合对象或者叶子对象。

4. Decorator(装饰器)

向一个现有的对象添加新的功能,同时又不改变其结构。

模式应用

JAVA IO 中 FilterInputStream

实现

装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者或者具体组件。所谓装饰,就是把这个装饰者套在被装饰者之上,从而动态扩展被装饰者的功能。装饰者的方法有一部分是自己的,这属于它的功能,然后调用被装饰者的方法实现,从而也保留了被装饰者的功能。可以看到,具体组件应当是装饰层次的最低层,因为只有具体组件的方法实现不需要依赖于其它对象。

适配器模式与装饰器模式的区别

装饰器与适配器都有一个别名叫做 包装模式(Wrapper),它们看似都是起到包装一个类或对象的作用,但是使用它们的目的很不一一样。适配器模式的意义是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的。

而装饰器模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方式而提升性能。所以这两个模式设计的目的是不同的。

5. Facade(外观)

为子系统中的一组接口提供一个一致的界面,定义了一个高层接口,这个接口使得这一子系统更加容易使用。又称为门面模式。

6. Flyweight(享元)

运用共享技术有效地支持大量细粒度的对象。

工厂类、享元池

享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。

区分内部状态和外部状态
模式应用

7. Proxy(代理)

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

模式应用
和适配器、装饰器的区别

8. Filter(过滤器)

允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。

模式应用

java8 的 stream 分组操作

Map<Integer, List<Person >> groupMap = persons.stream().collect(Collectors.groupingBy(Person::getGender));