形式设计-适配器、桥接模式

模式设计--适配器、桥接模式

一、适配器模式

1、适配器模式包含的4个角色:(1)目标抽象类定义客户要用的特定的领域的接口(此接口是符合用户需求的);(2)适配器类(核心角色);(3)适配者类,该类已经存在一个接口,但这接口不符合用户需求,需要被适配;(4)客户类,用于编程,实现调用目标抽象类中定义的业务方法。

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

3、实例讲解:
题目:现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[], int),已知类QuickSort(int[])方法实现了快速排序算法,类BinarySearch的binarySearch(int[], int)方法实现了二分查找算法。现使用适配器模式设计一个系统,在不修改源代码的情况下将类QuickSort和类BinarySearch的方法适配到DataOperation接口中。绘制类图并且编程实现。

1)适配器模式实验。
(1)通过分析实验内容,该实例类图如图1所示。
形式设计-适配器、桥接模式

图1 适配器模式数据操作实例类图

(2)创建目标接口类DataOperation,该接口定义了排序方法sort(int[])和查找方法search(int[], int),客户端中调用DataOperation中的sort()和search()方法,实现对数字排序和查找。代码如下:

public interface DataOperation {
    void sort(int[] n);
    int search(int[] arr, int key);
}

(3)适配器者QuickSort(快速排序类),代码如下:

public class QuickSort {    
    public void quickSork(int[] n, int left, int right){
        int dp;
        if (left < right) {
            dp = partition(n, left, right);
            quickSork(n, left, dp - 1);//递归调用
            quickSork(n, dp + 1, right);
        }
    }

    int partition(int n[], int left, int right) {
        int pivot = n[left];
        while (left < right) {
            while (left < right && n[right] >= pivot)
                right--;
            if (left < right)
                n[left++] = n[right];
            while (left < right && n[left] <= pivot)
                left++;
            if (left < right)
                n[right--] = n[left];
        }
        n[left] = pivot;
        return left;
    }
}

(4)适配器者BinarySearch(二分法查找类),代码如下:

public class BinarySearch {
    public int binarySearch(int[] arr, int key) {
           int start = 0;
           int end = arr.length - 1;
           while (start <= end) {
               int middle = (start + end) / 2;
               if (key < arr[middle]) {
                   end = middle - 1;
               } else if (key > arr[middle]) {
                   start = middle + 1;
               } else {
                   return middle;
               }
           }
           return -1;
       }
}

(5)适配器类DataAdapter(排序查找类)。这里使用的是对象适配器,因为此类要实现适配两个类中的方法,而Java是单继承机制,所有不能通过类适配器来实现。代码如下:

public class DataAdapter implements DataOperation { 
    private QuickSort quickSort;//定义QuickSort类型的成员对象
    private BinarySearch binarySearch;//定义BinarySearch类型的成员对象   public DataAdapter() {//这里采用的是构造函数实例化对象的方式,也可以营Setter方法将这两个对象注入进
        quickSort = new QuickSort();//实例化QuickSort对象
        binarySearch = new BinarySearch();//实例化BinarySearch对象
    }
    @Override
    public void sort(int[] n) {
        quickSort.quickSork(n, 0, n.length-1);//在sort()方法中调用对象quickSort中的quickSort()方法,实现快速排序
    }
    @Override
    public int search(int[] arr, int key) {
        return binarySearch.binarySearch(arr,key);//在search()方法中调用对象binarySearch中的binarySearch()方法,实现二分法查找
    }   
}

(6)客户端测试类Client。代码如下:

public class Client {
    public static void main(String[] args) {
        int[] array = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3 };
        DataAdapter adapter = new DataAdapter();//创建适配器DataAdapter实例对象
        adapter.sort(array);//调用DataOperation接口中的sort()方法,实现对数组快速排序
        for (int i = 0; i < array.length; i++) {//输出数组,检验结果
            System.out.print(array[i] + " ");
        }
        System.out.println();
        int find = adapter.search(array, 3);//调用DataOperation接口中的searcht()方法,二分法查找
        if (find != -1) {
            System.out.println("找到数值的下标为:" + find);
        } else {
            System.out.println("找不到数值!");
        }
    }
}

(7)运行适配器模式实例的客户端测试类,结果如图2所示。
形式设计-适配器、桥接模式

图2 适配器模式实例测试类运行结果图

二、桥接模式

1、桥接模式包括的4个角色:(1)抽象类,它一般是抽象类而不是接口,其中定义了一个实现抽象类的对象;(2)扩充抽象类,一般情况下它是个具体的类;(3)实现类接口;(4)具体实现类。

2、桥接模式适用的情况:(1)需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系;(2)抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响;(3)一个类存在来两个独立变化的维度,且这两个维度都需要进行扩展;(4)设计要求独立管理抽象化角色和具体化角色;(5)不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统。

3、实例讲解
题目:桥接模式实验:海尔(Haier)、TCL、海信(Hisense)都是家电制造商,它们都生产电视机(Television)、空调(AirConditioner)、冰箱(Refrigeratory)。现需要设计一个系统,描述这家电制造商以及它们制造的电器,要求绘制类图并用Java代码模拟实现。

(1)通过分析实验内容,该实例类图如图3所。
形式设计-适配器、桥接模式

图3 桥接模式电器实例类图

(2)实现类接口ElectricEquipment(家用电器类),该类定义了基本操作beProduce(),用于说明电器的名称,在其子类中提供实现,它位于桥接模式的抽象层。代码如下:

public interface ElectricEquipment {
     void beProduce(String makerName);
}

(3)具体实现类Television(电视机类),该类是实现了ElectricEquipment 接口的具体类,它实现了基本操作beProduce(),用于说明电器为电视机。代码如下:

public class Television implements ElectricEquipment {
    @Override
    public void beProduce(String makerName) {
        System.out.println(makerName + "电视机~");
    }
}

(4)具体实现类AirConditioner(空调类),该类是实现了ElectricEquipment 接口的具体类,它实现了基本操作beProduce(),用于说明电器为空调。代码如下:

public class AirConditioner implements ElectricEquipment {
    @Override
    public void beProduce(String makerName) {
        System.out.println(makerName + "空调~");
    }
}

(5)具体实现类Refrigeratory(冰箱类),该类是实现了ElectricEquipment 接口的具体类,它实现了基本操作beProduce(),用于说明电器为冰箱。代码如下:

public class Refrigeratory implements ElectricEquipment {
    @Override
    public void beProduce(String makerName) {
        System.out.println(makerName + "冰箱~");
    }
}

(6)抽象类ElectronicsMaker,该类定义一个ElectricEquipment类型对象,与ElectricEquipment接口之间存在关联关系,让ElectronicsMaker和它的之类可以调用ElectricEquipment中定义的方法。该类还定义了抽象业务方法produce(),在其子类中将实现该方法。代码如下:

public abstract class ElectronicsMaker {
protected ElectricEquipment equipment;//定义ElectricEquipment类型对象
    public void setEquipment(ElectricEquipment equipment) {
        this.equipment = equipment;
    }
    public abstract void produce();
}

(7)扩充抽象类Haier(海尔类),该类是ElectronicsMaker的子类,实现了ElectronicsMaker定义的抽象方法produce(),使用海尔厂商来生产电器。代码如下:

public class Haier extends ElectronicsMaker {
    @Override
    public void produce() {
        String makerName="海尔 厂商生产 ";
        this.equipment.beProduce(makerName);
    }
}

(8)扩充抽象类Hisense(海信类),该类是ElectronicsMaker的子类,实现了ElectronicsMaker定义的抽象方法produce(),使用海信厂商来生产电器。代码如下:

public class Hisense extends ElectronicsMaker {
    @Override
    public void produce() {
        String makerName="海信 厂商生产 ";
        this.equipment.beProduce(makerName);
    }
}

(9)客户端测试类Client。代码如下:

public class Client {
    public static void main(String[] args) {
        ElectricEquipment quipment;
        ElectronicsMaker maker;

        maker = new Haier();//创建一个ElectronicsMaker的子类Haier的实例对象(海尔厂商)
        quipment = new Television();//创建一个ElectricEquipment的子类Television的实例对象
        maker.setEquipment(quipment);//将Haier的实例对象和Television的实例对象关联
        maker.produce();//调用Haier的对象produce()方法,让这方法去调用Television对象中的beProduce()方法

        quipment = new AirConditioner();//空调
        maker.setEquipment(quipment);//将海尔厂商与空调关联
        maker.produce();

        quipment = new Refrigeratory();//冰箱
        maker.setEquipment(quipment);//将海尔厂商与冰箱关联
        maker.produce();

        System.out.println("---------------------------");

        maker = new Hisense();//创建Hisense的实例对象(海信厂商)
        quipment = new Television();//创建Television的实例对象
        maker.setEquipment(quipment);//将Hisense的实例对象和Television的实例对象关联
        maker.produce();//调用Hisense对象的produce()方法,让这方法去调用Television对象中的beProduce()方法

        quipment = new AirConditioner();//空调
        maker.setEquipment(quipment);//将海信厂商与空调关联
        maker.produce();

        quipment = new Refrigeratory();//冰箱
        maker.setEquipment(quipment);//将海信厂商与冰箱关联
        maker.produce();
    }
}

(10)运行桥接模式实例的客户端测试类,结果如图4所示。
形式设计-适配器、桥接模式

图4 桥接模式实例测试类运行结果图

实例代码下载

本博客的实例代码已上传,需要的可以参考一下。http://download.****.net/detail/leyezhiqiu/9507267