• 容器模式


    我觉得这个设计模式对于那些类似提供平台的公司是非常适用的一种模式:

      那我们来谈谈这是怎么样的一个原理呢,首先我们来模拟一个 场景:

        假设有一家公司提供了一个这样的平台,就是它提供了测量任意一个对象的最大值,最小值,并设置了它的测量方法。

        这样我们是不是就有一个疑问:别人用我这个平台,你怎么知道别人一定是按照你的方法去测量呢。这个问题Good!!

        这个平台的通用性在于对于任意一个对象都可以,要怎么去实现呢,我们提供了一个设置测量的接口,让你去实现这个

        接口的具体的实现方法。

      具体怎么实现呢,让我们通过一段代码来带入:

      首先设置提供一个测量的接口:

    package com.yc;
    public interface Measurable {
        /*
         * 测量方法
         * @param Objec
         */
        public double measure(Object object);
                
    }

      然后我们在来提供一个容器(平台):

      在这里我们对于上面的接口对象(Measruable)提供了set方法进行注值

    package com.yc;
    
    public class Container {
        public static final int NUM=10;
        private Object[] objects; //对象
        private Object max; 
        private Object min;
        private double avg;
        private double total; //总和
        
        private Integer index; //数组中存的真实数据有多少个
        private Measurable measurable; //测量设备
        
        private Filter filter;    //对数据有效性的过滤性
        
        
        
        public void setFilter(Filter filter) {
            this.filter = filter;
        }
    
        public Container(){
            objects=new Object[NUM];
            max=null;
            min=null;
            avg=0;
            total=0;
            index=0;
            measurable=null;
        }
        
        /*
         * 添加要测量的对象到容器的方法
         * 功能: 测量obj的值,并记录最大值,最小值,平均值,并将obj存到Objects数组中
         */
        public void add(Object obj) throws Exception{
            if(obj==null){
                throw new RuntimeException("要测量的对象不能为空,您传入的对象为"+obj);  //非受检
            }
            if(this.measurable==null){
                throw new Exception("测量不能为空");  //受检异常,受检异常一定要抛出
            }
            //判断是否有过滤器
            if(this.filter!=null){
                if(this.filter.doFilter(obj)==false){
                    throw new RuntimeException("要过率的对象不是有效对象");
                }
            }
            double value=this.measurable.measure(obj);
            if(index==0){
                max=obj;
                min=obj;        
            }else{
                double maxvalue=this.measurable.measure(max);
                double minvalue=this.measurable.measure(min);
                
                if(maxvalue<value){
                    max=obj;
                }
                //这里不能加 else 要进行两次判断:有可能刚好是中间值,既是最大,有时最小
                if(minvalue>value){
                    min=obj;
                }
            }
            //扩展object数组的大小,防止它存满溢出
            enlargeArray();
            objects[index]=obj;
            //自增index
            index++;
            total+=value;
            avg=total/index;
        }
        
        //更优方案:按照比例进行扩充,不一定要一两倍
        //或者不一定等数组满了之后才进行复制,达到%80
        private void enlargeArray() {
            if(index>=objects.length){
                Object[] newobjects=new Object[objects.length*2];
                //将原数组的数据存到新数组中
                System.arraycopy(objects, 0, newobjects, 0, index);
                //将newobject的地址复制给objects
                objects=newobjects;
                System.gc();  //gc() 垃圾回收,告诉jvm回收空间     【根本方案:重写虚拟机】
            }
        }
    
        //设置测量的方法
        public void setMeasurable( Measurable measurable){
            this.measurable=measurable;
        }
        
        //所有测量过后的数据,object默认10,只能返回有效的数据
        public Object[] getAllData(){
            Object[] newobject=new Object[index];
            System.arraycopy(objects, 0, newobject, 0, index);
            return newobject;
        }
        
        //测量过的数据
        public int size(){
            return index;
        }
    
        public Object[] getObjects() {
            return objects;
        }
    
        public Object getMax() {
            return max;
        }
    
        public Object getMin() {
            return min;
        }
    
        public double getAvg() {
            return avg;
        }
    
        public double getTotal() {
            return total;
        }
        
        /*
         * 这是容器要用的排序方法
         */
        
        public void sort(){
            Object tem=null;
            //循环一次把最大数放到最后
            for(int i=0;i<index;i++){
                for( int j=0;j<index-i-1;j++){
                    Object objJ=objects[j];
                    Object objJ1=objects[j+1];
                    //判断objJ是否实现了 Sort接口的对象
                    if(objJ instanceof Sort){
                        Sort s=(Sort) objJ;
                        int result=s.doSort(objJ1);
                        if( result>0){
                            tem=objects[j];
                            objects[j]=objects[j+1];
                            objects[j+1]=tem;
                            
                        }
                    }
                }
            }
        }
        
        
    }

    这上面的就属于提供平台的那个公司所管理的内容

    而下面我们就对那个使用这个平台的公司进行实现

      首先我们要实现他的测量方案

      首先是实现它的测量方法的接口

      

    package com.lining;
    
    import com.yc.Measurable;
    
    public class Bmi implements Measurable{
    
        @Override
        public double measure(Object obj) {
            if(obj==null){
                throw new RuntimeException("要测量的对象不能为空");
            }
            if(!( obj instanceof Person)){
                throw new RuntimeException("要测量的对象必须是一个人");
            }
            //将Object强制类型转换成Person ,以取height,weight
            Person p=(Person) obj;
            double height=p.getHeight();
            double weight=p.getWeight();
            return weight/(height*height);
        }
        
    }

    那么问题又来了,这个对象是否合理呢,我要测量的是人,那他给我一头猪的话,那我也只能跟他说say good bye 了 ,所以在这里还要设置一个过虑器来顾虑

    以下就用提供者(表示平台公司),接受者(表示要使用这个平台的公司)

      所以就又可以在提供者里提供一个他的过滤的接口:

      

    package com.yc;
    
    public interface Filter {
        public boolean doFilter(Object obj);
    }
    View Code

       接受者:

    package com.lining;
    
    import com.yc.Filter;
    
    public class BmiDataFilter implements Filter {
    
        @Override
        public boolean doFilter(Object obj) {
            if(obj==null){
                throw new RuntimeException("要过滤的对象不能为空");
            }
            if(!( obj instanceof Person)){
                throw new RuntimeException("要过滤的对象必须是一个人");
            }
            
            //将Object强制类型转换成Person ,以取height,weight
            Person p=(Person) obj;
            double height=p.getHeight();
            double weight=p.getWeight();
            
            if( height<1 || height>2.5){
                return false;
                //throw new RuntimeException("身高数据不合理。。。。"+height);
            }
            if( weight<40|| weight>200){
                return false;
                //throw new RuntimeException("体重数据不合理..."+weight);
            }
            return true;
        }
    
    }
    View Code

       那如果接收者要求要对数据进行排序呢这又该如何解决呢

      同理有:

    package com.yc;
    
    public interface Sort {
        /*
         * 比较两个对象的大小
         * 正数表示当前对象大,负数表示ob大, 0相等
         */
        public int doSort(Object obj);
    }

    接受者:

      

    package com.lining;
    
    import com.yc.Sort;
    
    public class Person implements Sort{
        private String name;
        private double weight;
        private double height;
    
        public Person(String name, double weight, double height) {
            super();
            this.name = name;
            this.weight = weight;
            this.height = height;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public double getWeight() {
            return weight;
        }
        public void setWeight(double weight) {
            this.weight = weight;
        }
        public double getHeight() {
            return height;
        }
        public void setHeight(double height) {
            this.height = height;
        } 
        @Override
        public String toString() {
            return "Person [name=" + name + ", weight=" + weight + ", height=" + height + "]";
        }
        @Override
        public int doSort(Object obj) {
            if(obj==null){
                throw new RuntimeException("要比较的对象不能为空");
            }
            if(!(obj instanceof Person)){
                throw new RuntimeException("要比较的对象必须是一个人");
            }
            Person p=(Person)obj;
            
            return (int)(this.weight-p.weight);
        }
        
        
    }

      

    测试的类

      

    import org.junit.Test;
    
    import com.lining.Bmi;
    import com.lining.BmiDataFilter;
    import com.lining.Person;
    import com.yc.Container;
    import com.yc.Filter;
    
    public class test1 {
        @Test
        public void test() throws Exception{
            Bmi bmi=new Bmi();
            Container c=new Container();
            Filter filter=new BmiDataFilter();
            c.setMeasurable(bmi);
            c.setFilter(filter);
            
            
            Person p1=new Person("张三1",700,2.23);
            Person p2=new Person("张三2",700,1.3);
            Person p3=new Person("张三3",140,1.8);
            
            //
            
            
            try{
                c.add(p1);
                c.add(p2);
            }catch(Exception e){
                e.printStackTrace();
            }
            
            c.add(p3);
            
            //取最大值
            Object max=c.getMax();
            Person maxPerson=(Person)max;
            
            //取出最小值
            Object min=c.getMax();
            Person minPerson=(Person)min;
            
            System.out.println("+++++++所有的值+++++++++++++");
            Object[] objs=c.getAllData();
            for(Object o:objs){
                Person p=(Person)o;
                System.out.println(p);
            }
        }
    }
    View Code
    import org.junit.Test;
    
    import com.lining.Bmi;
    import com.lining.BmiDataFilter;
    import com.lining.Person;
    import com.yc.Container;
    import com.yc.Filter;
    
    public class test2 {
        //按体重进行排序
        @Test
        public void test() throws Exception{
            Bmi bmi=new Bmi();
            Container c=new Container();
            Filter filter=new BmiDataFilter();
            c.setMeasurable(bmi);
            c.setFilter(filter);
            
            
            Person p1=new Person("张三1",100,2.23);
            Person p2=new Person("张三2",70,1.3);
            Person p3=new Person("张三3",140,1.8);
            Person p4=new Person("张三3",144,1.8);
            Person p5=new Person("张三3",86,1.8);
            //
            
            
            try{
                c.add(p1);
                c.add(p2);
            }catch(Exception e){
                e.printStackTrace();
            }
            
            c.add(p3);
            c.add(p4);
            c.add(p5);
            
            //取最大值
            Object max=c.getMax();
            Person maxPerson=(Person)max;
            
            //取出最小值
            Object min=c.getMax();
            Person minPerson=(Person)min;
            
            System.out.println("+++++++未排序所有的值+++++++++++++");
            Object[] objs=c.getAllData();
            for(Object o:objs){
                Person p=(Person)o;
                System.out.println(p);
            }
            
            c.sort();
            System.out.println("+++++++排序好的所有的值+++++++++++++");
            objs=c.getAllData();
            for(Object o:objs){
                Person p=(Person)o;
                System.out.println(p);
            }
        }
    }
    View Code
  • 相关阅读:
    环求解点值
    汉诺塔(记录每种路径次数)
    快速排序
    选择排序
    冒泡排序
    桶排序
    异或后最大lowerbit
    计数三角形
    nico和niconiconi
    提高程序设计能力的一般方法
  • 原文地址:https://www.cnblogs.com/yaobolove/p/5318951.html
Copyright © 2020-2023  润新知