容器模式
那我们来谈谈这是怎么样的一个原理呢,首先我们来模拟一个 场景:
如果有一家公司提供了一个这种平台。就是它提供了測量随意一个对象的最大值。最小值,并设置了它的測量方法。
这样我们是不是就有一个疑问:别人用我这个平台。你怎么知道别人一定是依照你的方法去測量呢。这个问题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); }
接受者:
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; } }
那假设接收者要求要对数据进行排序呢这又该怎样解决呢
同理有:
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); } } }
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); } } }