设计模式学习(4)分开考虑

桥接模式

将类功能的层次结构和实现结构分离开

实现层次结构:在模板方法模式中,我们通过重写父类的方法来达到实现自己的功能的目的。这里使用的继承只是子类为了在父类的接口下实现自己的方法。

功能层次结构:继承一个类,写一个新的方法。这里使用继承是为了给父类添加新的方法,但是又能继续用父类的方法。

桥接模式可以将实现层次结构和功能层次结构分离开。将这两种继承显示出来。

例子

我们用桥接模式实现这样一个功能。现在有一个显示类(Display),它可以显示一个字符串。

现在我们希望添加两个功能,一个是能显示的时候添加一个包围盒,另一个是能输出5次。

首先,显示的时候添加包围盒,就是怎么显示的问题。这个可以通过派生父类并重写父类的模板函数来实现。

其次,输出5次是新的功能,这个可以通过派生父类,并新增加一个方法来实现。

但是这样实现会导致功能层次和实现层次的继承混乱。

所以我们这里单独把两个抽出来,功能层次的继承,当作类的继承。而实现层次的继承,放到一个xxxImpl类中,并通过继承这个类来实现子类需要的实现方法。

// 这是个显示的基类,里面保存了一个DisplayImpl来指代不同的显示方法实现
public class Display {
    private DisplayImpl impl;

    public Display(DisplayImpl impl) {
        this.impl = impl;
    }

    public void open() {
        impl.rawOpen();
    }

    public void print() {
        impl.rawPrint();
    }

    public void close() {
        impl.rawClose();
    }

    public final void display() {
        open();
        print();
        close();
    }
}

// 这是实现显示的方法
public abstract class DisplayImpl {
    public abstract void rawOpen();
    public abstract void rawPrint();
    public abstract void rawClose();
}

// 这个继承是子类实现了自己的方法
public class StringDisplayImpl extends DisplayImpl{

    private String string;
    private int width;
    public StringDisplayImpl(String string) {
        this.string = string;
        this.width = string.getBytes().length;
    }

    @Override
    public void rawOpen() {
        printLine();
    }

    @Override
    public void rawPrint() {
        System.out.println("|" + string + "|");
    }

    @Override
    public void rawClose() {
        printLine();
    }

    private void printLine() {
        System.out.print("+");
        for (int i = 0; i < width;i ++) {
            System.out.print("-");
        }
        System.out.println("+");
    }
}

// 这个继承是为了给display添加新功能
public class CountDisplay extends Display{
    public CountDisplay(DisplayImpl impl) {
        super(impl);
    }

    public void multiDisplay(int times) {
        open();
        for (int i = 0; i < times; i++) {
            print();
        }
        close();
    }
}

注意

  • 为什么要分开呢?更容易扩展。
  • 继承是强关联,委托是弱关联

相关设计模式

  • 模板方法模式
  • 抽象工厂模式
  • 适配器模式

策略模式

为了解决问题,程序会编写算法。使用策略模式可以很容易的去替换这些算法。

例子

用策略模式模拟一下猜拳

现在有两种出拳算法

  • 如果上一把赢了,下一把用同样手势(Winning Strategy)
  • 根据上一局的手势,从概率上计算下一句的手势(Prob Strategy)

代码太复杂了。。就不贴了,以后再说

策略模式比较简单,就是把一些解决问题的算法抽象成一个Strategy的派生类。然后在运行过程中就可以替换这些算法了。

其实去调用不同的函数也是可以的。

相关设计模式

  • 享元模式,不重要
  • 抽象工厂模式
  • 状态模式
posted @ 2022-08-17 20:34  Destiny233  阅读(25)  评论(0)    收藏  举报