容器模式

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

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

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

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

时间: 2024-08-29 12:40:08

容器模式的相关文章

从匿名函数(闭包特性)到 PHP 设计模式之容器模式

匿名函数(匿名函数) 匿名函数,也叫闭包函数,它允许临时创建一个没有指定名称的函数,常用作回调函数参数的值,也可以作为变量的值来使用.具体的使用见以下示例代码: /* 示例一:声明一个简单匿名函数,并赋值给一个变量,通过变量名调用这个匿名函数 */ $anonFunc = function($param){ echo $param; }; $anonFunc('这里是一个匿名函数'); // 通过变量名调用匿名函数,和普通函数没什么区别 /* 示例二:通过在函数内部使用匿名函数动态创建函数 */

设计模式课程 设计模式精讲 8-9 单例设计模式-容器模式

1 课程讲解 1.1 应用场景 2 代码演练 1.1 容器单例 1 课程讲解 1.1 应用场景 应用于在程序初始化的时候把多个单例对象放入到singletonMap中,使用的时候直接通过key获取对象.可以应用在懒汉模式中,不适用于饿汉模式(饿汉模式由于每次都要重新初始化会出现多线程安全问题) 使用hashtable会线程安全,但是由于其同步锁,会影响性能. 2 代码演练 1.1 容器单例 test类: package com.geely.design.pattern.creational.si

docker容器网络通信原理分析

概述 自从docker容器出现以来,容器的网络通信就一直是大家关注的焦点,也是生产环境的迫切需求.而容器的网络通信又可以分为两大方面:单主机容器上的相互通信和跨主机的容器相互通信.而本文将分别针对这两方面,对容器的通信原理进行简单的分析,帮助大家更好地使用docker. docker单主机容器通信 基于对net namespace的控制,docker可以为在容器创建隔离的网络环境,在隔离的网络环境下,容器具有完全独立的网络栈,与宿主机隔离,也可以使容器共享主机或者其他容器的网络命名空间,基本可以

虚拟化之容器docker基本操作

docker 是一个开源的应用容器引擎,主要利用 linux 内核 namespace 实现沙盒隔离,用cgroup 实现资源限制. Docker 支持三种不同的镜像层次存储的 drivers: aufs.devicemapper.btrfs ; Aufs: AUFS (AnotherUnionFS) 是一种 Union FS, 简单来说就是支持将不同目录挂载到同一个虚 拟 文 件 系 统 下 (unite several directories into a single virtual fi

[转]MVP模式开发

转自:http://www.jianshu.com/p/f7ff18ac1c31 基于面向协议MVP模式下的软件设计-(iOS篇) 字数9196 阅读505 评论3 喜欢11 基于面向协议MVP模式下的软件设计-(iOS篇) 传统模式下的开发 MVC MVVM 基于面向协议MVP的介绍 MVP实战开发 说在前面:相信就算你是个iOS新手也应该听说过MVC的,MVC是构建iOS App的标准模板.随着时间的推移,在iOS平台上MVC也逐渐开始面临着越来越多的问题,最近又开始流行MVVM,MVVM使

Docker容器学习梳理--容器间网络通信设置(Pipework和Open vSwitch)

自从Docker容器出现以来,容器的网络通信就一直是被关注的焦点,也是生产环境的迫切需求.容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信.下面将分别针对这两方面,对容器的通信原理进行简单的分析,帮助大家更好地使用docker.前面已经在Docker容器学习梳理--基础知识(2)这一篇中详细介绍了Docker的网络配置以及pipework工具. docker单主机容器通信 基于对net namespace的控制,docker可以为在容器创建隔离的网络环境,在隔离的

深入解析阿里 PouchContainer 如何实现容器原地升级

PouchContainer 是阿里巴巴集团开源的高效.轻量级企业级富容器引擎技术,拥有隔离性强.可移植性高.资源占用少等特性.可以帮助企业快速实现存量业务容器化,同时提高超大规模下数据中心的物理资源利用率.已助力阿里巴巴集团实现在线业务 100% 容器化,双 11 容器规模达到百万级. 背景阿里巴巴集团内部,容器使用方式有很大一部分是富容器模式,像这种基于传统虚拟机运维模式下的富容器,其中也有一定数量容器仍然是有状态的.有状态服务的更新和升级是企业内部频率很高的一个日常操作,对于以镜像为交付的

技术解析系列 | PouchContainer 富容器技术

划重点 本文将从什么是富容器.富容器适用场景.富容器技术实现三个角度全方位向大家解释富容器技术,同时对富容器感兴趣的同学可以扫描文章末尾二维码参与关于富容器的技术讨论.本文作者 PouchContainer 团队孙宏亮,更多信息扫描二维码见真人. PouchContainer 是阿里巴巴集团开源的高效.轻量级企业级富容器引擎技术,拥有隔离性强.可移植性高.资源占用少等特性.可以帮助企业快速实现存量业务容器化,同时提高超大规模下数据中心的物理资源利用率. PouchContainer 源自阿里巴巴

什么是容器编排?

什么是容器编排? 应用一般由单独容器化的组件(通常称为微服务)组成,且必须按顺序在网络级别进行组织,以使其能够按照计划运行.以这种方法对多个容器进行组织的流程即称为容器编排. 容器编排定义 在现代开发当中,整体式的应用早已成为过去时,如今的应用由数十乃至数百个松散结合的容器式组件构成,而这些组件需要通过相互间的协同合作,才能使既定的应用按照设计运作.容器编排是指对单独组件和应用层的工作进行组织的流程. 容器编排的工作原理是什么? 虽然诸如 Apache Mesos.Google Kubernet