不兼容结构的协调——适配器模式(二):没有源码的算法库的适配器模式解决方案

作者:Liuwei-Sunny

出处:https://blog.csdn.net/lovelion


9.3 完整解决方案

Sunny软件公司开发人员决定使用适配器模式来重用算法库中的算法,其基本结构如图9-4所示:

20190609100310_1.png

图9-4 算法库重用结构图

在图9-4中,ScoreOperation接口充当抽象目标,QuickSort和BinarySearch类充当适配者,OperationAdapter充当适配器。完整代码如下所示:

    //抽象成绩操作类:目标接口
    interface ScoreOperation {
        public int[] sort(int array[]); //成绩排序
        public int search(int array[],int key); //成绩查找
    }

    //快速排序类:适配者
    class QuickSort {
        public int[] quickSort(int array[]) {
            sort(array,0,array.length-1);
            return array;
        }

        public void sort(int array[],int p, int r) {
            int q=0;
            if(p<r) {
                q=partition(array,p,r);
                sort(array,p,q-1);
                sort(array,q+1,r);
            }
        }

        public int partition(int[] a, int p, int r) {
            int x=a[r];
            int j=p-1;
            for (int i=p;i<=r-1;i++) {
                if (a[i]<=x) {
                    j++;
                    swap(a,j,i);
                }
            }
            swap(a,j+1,r);
            return j+1;
        }

        public void swap(int[] a, int i, int j) {   
            int t = a[i];   
            a[i] = a[j];   
            a[j] = t;   
        }
    }

    //二分查找类:适配者
    class BinarySearch {
        public int binarySearch(int array[],int key) {
            int low = 0;
            int high = array.length -1;
            while(low <= high) {
                int mid = (low + high) / 2;
                int midVal = array[mid];
                if(midVal < key) {  
    low = mid +1;  
    }
                else if (midVal > key) {  
    high = mid -1;  
    }
                else {  
    return 1; //找到元素返回1  
    }
            }
            return -1;  //未找到元素返回-1
        }
    }

    //操作适配器:适配器
    class OperationAdapter implements ScoreOperation {
        private QuickSort sortObj; //定义适配者QuickSort对象
        private BinarySearch searchObj; //定义适配者BinarySearch对象

        public OperationAdapter() {
            sortObj = new QuickSort();
            searchObj = new BinarySearch();
        }

        public int[] sort(int array[]) {  
    return sortObj.quickSort(array); //调用适配者类QuickSort的排序方法
    }

        public int search(int array[],int key) {  
    return searchObj.binarySearch(array,key); //调用适配者类BinarySearch的查找方法
    }
    }

为了让系统具备良好的灵活性和可扩展性,我们引入了工具类XMLUtil和配置文件,其中,XMLUtil类的代码如下所示:

    import javax.xml.parsers.*;
    import org.w3c.dom.*;
    import org.xml.sax.SAXException;
    import java.io.*;
    class XMLUtil {
    //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
        public static Object getBean() {
            try {
                //创建文档对象
                DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = dFactory.newDocumentBuilder();
                Document doc;                           
                doc = builder.parse(new File("config.xml"));

                //获取包含类名的文本节点
                NodeList nl = doc.getElementsByTagName("className");
                Node classNode=nl.item(0).getFirstChild();
                String cName=classNode.getNodeValue();

                //通过类名生成实例对象并将其返回
                Class c=Class.forName(cName);
                Object obj=c.newInstance();
                return obj;
            }   
            catch(Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }

配置文件config.xml中存储了适配器类的类名,代码如下所示:

    <?xml version="1.0"?>
    <config>
        <className>OperationAdapter</className>
    </config>

编写如下客户端测试代码:

    class Client {
        public static void main(String args[]) {
            ScoreOperation operation;  //针对抽象目标接口编程
            operation = (ScoreOperation)XMLUtil.getBean(); //读取配置文件,反射生成对象
            int scores[] = {84,76,50,69,90,91,88,96}; //定义成绩数组
            int result[];
            int score;

            System.out.println("成绩排序结果:");
            result = operation.sort(scores);

            //遍历输出成绩
            for(int i : scores) {
                System.out.print(i + ",");
            }
            System.out.println();

            System.out.println("查找成绩90:");
            score = operation.search(result,90);
            if (score != -1) {
                System.out.println("找到成绩90。");
            }
            else {
                System.out.println("没有找到成绩90。");
            }

            System.out.println("查找成绩92:");
            score = operation.search(result,92);
            if (score != -1) {
                System.out.println("找到成绩92。");
            }
            else {
                System.out.println("没有找到成绩92。");
            }
        }
    }

编译并运行程序,输出结果如下:

成绩排序结果:
50,69,76,84,88,90,91,96,
查找成绩90:
找到成绩90。
查找成绩92:
没有找到成绩92。

在本实例中使用了对象适配器模式,同时引入了配置文件,将适配器类的类名存储在配置文件中。如果需要使用其他排序算法类和查找算法类,可以增加一个新的适配器类,使用新的适配器来适配新的算法,原有代码无须修改。通过引入配置文件和反射机制,可以在不修改客户端代码的情况下使用新的适配器,无须修改源代码,符合“开闭原则”。

赞(0) 打赏

如未加特殊说明,此网站文章均为原创,转载必须注明出处。Java 技术驿站 » 不兼容结构的协调——适配器模式(二):没有源码的算法库的适配器模式解决方案
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

关注【Java 技术驿站】公众号,每天早上 8:10 为你推送一篇技术文章

扫描二维码关注我!


关注【Java 技术驿站】公众号 回复 “VIP”,获取 VIP 地址永久关闭弹出窗口

免费获取资源

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏