设计模式(Java)—Bridge模式

Bridge模式的作用是将两样东西连接起来,它们分别是类的功能层次结构与类的实现层次结构。该模式在类的功能层次结构与类的实现层次结构之间搭建桥梁。

类的层次结构的两个作用
1.类的功能层次结构
当要增加新的功能时,我们可以从各个层次的类中找出最符合自己需求的类,然后以它为父类编写子类,并在子类中增加新的功能。这就是“类的功能层次结构”。

通常来说,类的层次结构关系不应当关系过深。

2.类的实现层次结构
希望增加新的实现时,父类通过声明抽象方法来定义接口(API),子类通过实现具体方法来实现接口(API),这种层次结构被称为“类的实现层次结构”。

示例程序:显示一些东西
这里写图片描述

类的功能层次结构:Display类
Display类的功能是抽象的,负责显示一些东西,该类位于“类的功能层次结构”的最上层。
在impl字段中保存的是实现了Display类的具体功能的实例,该实例通过Display类的构造函数传递给Display类,然后保存在impl字段中,以供后面的处理使用。

package Bridge;

//类的功能层次上层
public class Display {
    //连接功能层次结构和实现层次结构的桥梁,使用委托这种弱联系的方式
    private DisplayImpl impl;
    public Display(DisplayImpl impl) {
        // TODO Auto-generated constructor stub
        this.impl = impl;
    }
    //利用实现层次类的实例调用其中的方法
    public void open(){
        impl.rawOpen();
    }
    public void print(){
        impl.rawPrint();
    }
    public void close(){
        impl.rawClose();
    }
    public void display(){
        open();
        print();
        close();
    }

}

类的功能层次结构:CountDisplay类
CountDisplay类在Display类的基础上增加了一个新功能。Display类只有“显示”的功能,CountDisplay类则具有“只显示规定的次数”的功能。

package Bridge;

//继承父类,在子类中添加新的功能
public class CountDisplay extends Display {
    public CountDisplay(DisplayImpl impl) {
        // TODO Auto-generated constructor stub
        super(impl);
    }
    public void multiDisplay(int times){
        open();
        for(int i=0;i<times;i++){
            print();
        }
        close();

    }
}

类的实现层次结构:DisplayImpl类
DisplayImpl类位于“类的实现层次结构”的最上层。
DisplayImpl类是抽象类,他声明了三个抽象方法。

package Bridge;

//类的实现层次接口类
public abstract class DisplayImpl {
    public abstract void rawOpen();
    public abstract void rawPrint();
    public abstract void rawClose();

}

类的实现层次结构:StringDisplayImpl类

package Bridge;

//继承类的实现层次类,实现接口中的抽线方法
public class StringDisplayImpl extends DisplayImpl {
    private String string;
    private int width;
    public StringDisplayImpl(String string) {
        // TODO Auto-generated constructor stub
        this.string = string;
        width = string.getBytes().length;
    }

    @Override
    public void rawOpen() {
        // TODO Auto-generated method stub
        printLine();

    }

    @Override
    public void rawPrint() {
        // TODO Auto-generated method stub
        System.out.println("|"+string+"|");

    }

    @Override
    public void rawClose() {
        // TODO Auto-generated method stub
        printLine();

    }
    private void printLine() {
        // TODO Auto-generated method stub
        System.out.print("+");
        for(int i=0;i<width;i++){
            System.out.print("-");
        }
        System.out.println("+");


    }


}

DisplayImpl和StringDisplayImpl这两个类相当于“类的实现层次结构”。

Main类:

package Bridge;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //父类实例可以调用功能和接口
        //功能子类可以调用功能和接口
        Display d1 = new Display(new StringDisplayImpl("Hello world"));
        Display d2 = new CountDisplay(new StringDisplayImpl("Hello china"));
        CountDisplay d3 = new CountDisplay(new StringDisplayImpl("hello guys"));
        d1.display();
        d2.display();
        d3.multiDisplay(3);


    }

}

总结:将类的这两个层次结构离开有利于独立地对它们进行扩展,虽然使用继承很容易扩展类,但是类之间也形成了一种强关联关系,只要不修改代码,就无法改变这种关系。
如果想要很轻松地改变类之间的关系,使用继承就不合适了,因为每次改变类之间关系时都需要修改程序,这时,我们可以使用“委托”来代替“继承”关系。
继承是强关联关系,但委托是弱关联关系,这时因为只有Display类的实例生成时,才与作为参数被传入的类构成关联。

练习1:
在示例程序中增加一个类,实现“显示字符串若干(随机)次”的功能。

package Bridge;

import java.util.Random;

public class RandomDisplay extends CountDisplay {
    private Random random = new Random();
    public RandomDisplay(DisplayImpl impl) {
        // TODO Auto-generated constructor stub
        super(impl);
    }
    public void randomDisplay(int times){
        multiDisplay(random.nextInt(times));

    }
}

练习2:
在示例程序中增加一个类,实现“显示文本文件的内容”的功能。

package Bridge;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class FileDisplay extends DisplayImpl {
    private String filename;
    private BufferedReader reader;
    private final int MAX_READHEAD_LIMIT = 4096;
    public FileDisplay(String filename) {
        // TODO Auto-generated constructor stub
        this.filename = filename;
    }
    @Override
    public void rawOpen() {
        // TODO Auto-generated method stub
        try {
            reader = new BufferedReader(new FileReader(filename));
            reader.mark(MAX_READHEAD_LIMIT);
        } catch (IOException e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        System.out.println("==========="+filename+"============");

    }

    @Override
    public void rawPrint() {
        // TODO Auto-generated method stub
        try {
            String line;
            reader.reset();
            while ((line = reader.readLine()) != null){
                System.out.println(">"+line);

            }
        } catch (IOException e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }

    @Override
    public void rawClose() {
        // TODO Auto-generated method stub
        System.out.println("==============");
        try {
            reader.close();
        } catch (IOException e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }

}
发布了167 篇原创文章 · 获赞 21 · 访问量 5万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览