容器模式

Posted yxysuanfa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了容器模式相关的知识,希望对你有一定的参考价值。

我认为这个设计模式对于那些相似提供平台的公司是很适用的一种模式:

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

    如果有一家公司提供了一个这种平台。就是它提供了測量随意一个对象的最大值。最小值,并设置了它的測量方法。

    这样我们是不是就有一个疑问:别人用我这个平台。你怎么知道别人一定是依照你的方法去測量呢。这个问题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

 

以上是关于容器模式的主要内容,如果未能解决你的问题,请参考以下文章

DrawerLayout 的项目点击 - 啥时候更换片段合适?

如何在 Android 中的特定片段容器中显示片段

尝试将片段添加到我的片段容器 FrameLayout

尝试将片段添加到我的片段容器 FrameLayout

尝试使用片段保存夜间模式状态

使用 BottomBar 和片段容器禁用 Android 片段重新加载