• java设计模式-策略模式


    背景:将一个数组排序,并且打印;
    1.下面使用选择排序、和冒泡排序来写:                        
    public class Test {
    
        public static void main(String[] args) {
            int a[] = {9, 5, 3, 7, 1, 10};
            DataSorter.sort(a);
            DataSorter.p(a);
        }
    
    }

    DataSort:

    package com.cy.dp.strategy;
    
    public class DataSorter {
        
        /**
         * 选择排序法
         * @param a
        public static void sort(int[] a) {
            int temp;
            for(int i=0; i<a.length; i++){
                for(int j=i+1; j<a.length; j++){
                    if(a[i]>a[j]){
                        temp = a[i];
                        a[i] = a[j];
                        a[j] = temp;
                    }
                }
            }
        } */
        
        /**
         * 冒泡排序法
         * @param a
         */
        public static void sort(int[] a) {
            int temp;
            for(int i=a.length; i>0; i--){
                for(int j=0; j<i-1; j++){
                    if(a[j]>a[j+1]){
                        temp = a[j];
                        a[j] = a[j+1];
                        a[j+1] = temp;
                    }
                }
            }
        }
    
        public static void p(int[] a) {
            for(int i=0; i<a.length; i++){
                System.out.print(a[i] + " ");
            }
            System.out.println();
        }
        
        
    }

    但是上面有个问题:

    sort方法里面现在只能排序int类型的;

    如果我想对于float类型进行排序,怎么办?--可以重载方法sort(float[] a);

    如果想对于double类型的进行排序,怎么办?--再重载一个double参数的;

    因为sort方法里面a[j]和a[j+1]的int类型的,能直接比较,这还好办,但是如果现在想DataSorter对猫、狗、Car、等等...进行排序,怎么办?

     
    2.对所有对象的数组都能够进行排序
    定义比较接口Comparable:
    //实现这个接口的类,表示是可以比较的
    public interface Comparable {
        
        public int compareTo(Object o);
    }

    DataSort可以排序任何类(该类实现Comparable接口),打印任何类;

    写完一次排序方法,再也不用改变了;

    package com.cy.dp.strategy;
    
    public class DataSorter {
        
        /**
         * 冒泡排序法,排序任何类型,Object类型
         * 假设Object[]里面对象都实现了Comparable接口,都是可以比较大小的;
         * @param a
         */
        public static void sort(Object[] a) {
            Object temp;
            for(int i=a.length; i>0; i--){
                for(int j=0; j<i-1; j++){
                    Comparable o1 = (Comparable)a[j];
                    Comparable o2 = (Comparable)a[j+1];
                    if(o1.compareTo(o2) > 0){
                        temp = a[j];
                        a[j] = a[j+1];
                        a[j+1] = temp;
                    }
                }
            }
        }
    
        public static void p(Object[] a) {
            for(int i=0; i<a.length; i++){
                System.out.print(a[i] + " ");
            }
            System.out.println();
        }
        
        
    }

    Cat实现Compareble接口:

    package com.cy.dp.strategy;
    
    public class Cat implements Comparable{
        private int height;
        private int weight;
        
        public Cat(int height, int weight) {
            super();
            this.height = height;
            this.weight = weight;
        }
        public int getHeight() {
            return height;
        }
        public void setHeight(int height) {
            this.height = height;
        }
        public int getWeight() {
            return weight;
        }
        public void setWeight(int weight) {
            this.weight = weight;
        }
        
        @Override
        public int compareTo(Object o) {
            if(o instanceof Cat){
                Cat c = (Cat) o;
                if(this.getHeight()>c.getHeight()) return 1;
                else if(this.getHeight() < c.getHeight()) return -1;
                else return 0;
            }
            return -100;    //简单写法,如果o不是cat,表示出错;实际要抛异常
        }
        
        
        @Override
        public String toString() {
            return height + "|" + weight;
        }
    }
    View Code

    Dog实现Comparable接口:

    package com.cy.dp.strategy;
    
    public class Dog implements Comparable{
        private int food;
        
        public Dog(int food) {
            super();
            this.food = food;
        }
        public int getFood() {
            return food;
        }
        public void setFood(int food) {
            this.food = food;
        }
        
        //对狗按照饭量大小进行排序
        @Override
        public int compareTo(Object o) {
            Dog d = (Dog) o;
            if(this.food > d.getFood()) return 1;
            else if(this.food < d.getFood()) return -1;
            else return 0;
        }
        @Override
        public String toString() {
            return "Dog [food=" + food + "]";
        }
        
    }
    View Code

    测试:

    public class Test {
    
        public static void main(String[] args) {
            Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)};
            DataSorter.sort(a);
            DataSorter.p(a);
            
            Dog d[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)};
            DataSorter.sort(d);
            DataSorter.p(d);
        }
    
    }

    输出

    1|1 3|3 5|5 
    Dog [food=1] Dog [food=3] Dog [food=4] Dog [food=5] 

    现在DataSort类可以对任何实现Comparable的类进行排序了,但是上面还是存在问题:

    当前比较猫的大小的时候,只是根据猫的height,假如哪天要根据猫的weight、或者胡子的长度,或者别的来比较大小呢?怎么办?

    也就是说现在Cat等实现的compareTo方法只能有一种实现,当还有其他不确定的实现时,这时候该怎么设计?

    3.实现Comparable接口的类,其compareTo方法,交给具体的比较策略,让它去实现;
    而不是说我自己固定写死;
     
    Comparator:
    //比较器
    public interface Comparator {
        
        int compare(Object o1, Object o2);
    }

    猫的高度比较器:

    //两只猫之间根据高度比较大小的  比较器
    public class CatHeightComparator implements Comparator {
    
        @Override
        public int compare(Object o1, Object o2) {
            Cat c1 = (Cat) o1;
            Cat c2 = (Cat) o2;
            if(c1.getHeight()>c2.getHeight()) return 1;
            else if(c1.getHeight() < c2.getHeight()) return -1;
            else return 0;
        }
    }

    猫的重量比较器:

    //两只猫之间根据重量比较大小的  比较器
    public class CatWeightComparator implements Comparator {
    
        @Override
        public int compare(Object o1, Object o2) {
            Cat c1 = (Cat) o1;
            Cat c2 = (Cat) o2;
            if(c1.getWeight()>c2.getWeight()) return -1;
            else if(c1.getWeight() < c2.getWeight()) return 1;
            else return 0;
        }
    
    }

    Cat类下面compareTo方法交给具体的比较器来实现:

    package com.cy.dp.strategy;
    
    public class Cat implements Comparable{
        private int height;
        private int weight;
        //默认是高度的比较器
        //private Comparator comparator = new CatHeightComparator();
        private Comparator comparator = new CatWeightComparator();
        
        public Cat(int height, int weight) {
            super();
            this.height = height;
            this.weight = weight;
        }
        public Comparator getComparator() {
            return comparator;
        }
        public void setComparator(Comparator comparator) {
            this.comparator = comparator;
        }
        public int getHeight() {
            return height;
        }
        public void setHeight(int height) {
            this.height = height;
        }
        public int getWeight() {
            return weight;
        }
        public void setWeight(int weight) {
            this.weight = weight;
        }
        
        @Override
        public int compareTo(Object o) {
            
            return comparator.compare(this, o);
        
        }
        
        
        @Override
        public String toString() {
            return height + "|" + weight;
        }
    }

    测试程序:

    public class Test {
    
        public static void main(String[] args) {
            Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)};
            //Dog a[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)};
            DataSorter.sort(a);
            DataSorter.p(a);
            
        }
    
    }

    输出:5|5 3|3 1|1 

    4.看看JDK是怎么做的:我们使用jdk里面的Comparable接口、Comparator接口:

    Cat:

    package com.cy.dp.strategy;
    
    public class Cat implements java.lang.Comparable<Cat>{
        private int height;
        private int weight;
        //默认是高度的比较器
        private java.util.Comparator<Cat> comparator = new CatHeightComparator();
        
        public Cat(int height, int weight) {
            super();
            this.height = height;
            this.weight = weight;
        }
        public java.util.Comparator<Cat> getComparator() {
            return comparator;
        }
        public void setComparator(java.util.Comparator<Cat> comparator) {
            this.comparator = comparator;
        }
        public int getHeight() {
            return height;
        }
        public void setHeight(int height) {
            this.height = height;
        }
        public int getWeight() {
            return weight;
        }
        public void setWeight(int weight) {
            this.weight = weight;
        }
    
        @Override
        public int compareTo(Cat o) {
            return comparator.compare(this, o);
        }
        
        @Override
        public String toString() {
            return height + "|" + weight;
        }
        
    }

    根据高度的比较器CatHeightComparator:

    //两只猫之间根据高度比较大小的  比较器
    public class CatHeightComparator implements java.util.Comparator<Cat> {
    
        @Override
        public int compare(Cat c1, Cat c2) {
            if(c1.getHeight()>c2.getHeight()) return 1;
            else if(c1.getHeight() < c2.getHeight()) return -1;
            else return 0;
        }
    }

    DataSort也改一下,就是使用java.lang.Comparable,其他不变:

    package com.cy.dp.strategy;
    import java.lang.Comparable;
    
    public class DataSorter {
        
        /**
         * 冒泡排序法,排序任何类型,Object类型
         * 假设Object[]里面对象都实现了Comparable接口,都是可以比较大小的;
         * @param a
         */
        public static void sort(Object[] a) {
            Object temp;
            for(int i=a.length; i>0; i--){
                for(int j=0; j<i-1; j++){
                    Comparable o1 = (Comparable)a[j];
                    Comparable o2 = (Comparable)a[j+1];
                    if(o1.compareTo(o2) > 0){
                        temp = a[j];
                        a[j] = a[j+1];
                        a[j+1] = temp;
                    }
                }
            }
        }
    
        public static void p(Object[] a) {
            for(int i=0; i<a.length; i++){
                System.out.print(a[i] + " ");
            }
            System.out.println();
        }
        
        
    }

    测试代码:

    public class Test {
    
        public static void main(String[] args) {
            Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)};
            //Dog a[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)};
            DataSorter.sort(a);
            DataSorter.p(a);
            
        }
    
    }

    输出:1|1 3|3 5|5 

    完美和JDK融合;基本模拟了JDK里面的Comparable接口和Comparator接口;

    5.而且其实不用自己写DataSort,用Arrays就行了:

    public static void main(String[] args) {
            Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)};
            //Dog a[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)};
            //DataSorter.sort(a);
            
            java.util.Arrays.sort(a);  //Arrays.sort(Object[] a)   注:a必须实现Comparable接口
            DataSorter.p(a);
        }

    也可以:

    public static void main(String[] args) {
            Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)};
            //Dog a[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)};
            //DataSorter.sort(a);
            //java.util.Arrays.sort(a);
            
            java.util.Arrays.sort(a, new java.util.Comparator<Cat>(){
                @Override
                public int compare(Cat o1, Cat o2) {
                    return o1.getHeight()>o2.getHeight()?1
                            :o1.getHeight()<o2.getHeight()?-1
                            :0;
                }
            });
            
            DataSorter.p(a);
        }

    小结:

    策略模式就是说,当我进行比较大小的时候,我定义一个策略的比较器,然后由具体的比较策略来决定谁大谁小;

    使用例子,比如:

    1.封装一下商场的打折策略;

      周六打折,过年打折,两种加在一块就打折,等等。所以打折策略最好不要写死它,因为将来可能有不能确定的各种各样的打折策略;所以最好把打折策略定义成一个可以扩展的内容;这就是策略模式;

    2.封装一下坦克的发射炮弹的策略;

      有的时候打一发,有的时候打多发,等等,具体由我发射炮弹的策略决定;

     
  • 相关阅读:
    【android tools】内存、网络、界面性能响应优化的工具
    mysql命令(数据库备份与恢复)
    mysql中一些简单但是新手容易犯的错误
    Mysql bench执行sql语句批量操作数据所遇到的问题
    Excel “此单元格中的数字为文本格式,或者其前面有撇号” 设成数字格式
    VC程序异常中断的原因
    vs dump调试
    winsock.h与winsock2.h出现重定义或不同的链接
    QT中QString与string的转化,解决中文乱码问题
    线程中CreateEvent和SetEvent及WaitForSingleObject的用法
  • 原文地址:https://www.cnblogs.com/tenWood/p/9085680.html
Copyright © 2020-2023  润新知