zoukankan      html  css  js  c++  java
  • 设计模式笔记之四(原型模式)

    原型模式

    原型模式就是需要创建多个实例的时候,以一个为原型,其他实例复制/克隆这个原型来获得相似的实例。

    我们的实验室最近研究这个模式还是因为市场的原因,市场上由于长久以来的习俗和政策,对女人的需求比较大,所有我们就的扩大女人的生产线,但是由于资金的原因,我们不能投入硬件成本只能改进我们的方法。

    首先我们得分析女人的构成:

    class NvRen {
        private String name;
        private String head;
        private String body;
        private String type;
    
        public NvRen(String name, String head, String body, String type) {
            this.name = name;
            this.head = head;
            this.body = body;
            this.type = type;
        }
    }

    我们以前生产女人的时候我们把预设好的名字,头型,身型,类型在创建女人的时候传入(好吧,我承认女人很难懂,但我们春秋笔法下~~)。

    public class Prototype {
    
        public static void main(String[] args) {
            NvRen nvren1 = new NvRen("小责圆","瓜子脸","葫芦型","气质高雅型");
            NvRen nvren2 = new NvRen("松岛丰","圆脸","葫芦型","邻家御姐型");
            NvRen nvren3 = new NvRen("饭到爱","瓜子脸","葫芦型","可爱型");
            NvRen nvren4 = new NvRen("罗玉风","面瓜脸","水桶型","恶心型");
        }
    }

    研究了很久,我们的市场部经理终于有了想法:由于高富帅客户不需要我们的产品,现在需求我们产品的客户基本上都属于丑矮穷搓撸的类型,他们对我们的产品也没有多少要求,只要有不同名字就行,我觉得我们可以批量生产女人,出厂的时候再给他们设置下不同的名字就行了,所以我们更改了我们的女人类:

    class NvRen implements Cloneable {
        private String name;
        private String head;
        private String body;
        private String type;
    
        public NvRen(String name, String head, String body, String type) {
            this.name = name;
            this.head = head;
            this.body = body;
            this.type = type;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        protected NvRen clone() {
            NvRen nr = null;
            try {
                nr = (NvRen) super.clone();
            } catch (CloneNotSupportedException e) {
                nr = new NvRen(this.name, this.head, this.body, this.type);
            }
            return nr;
        }
    }

    现在我们就可以很Happy的批量生产了

    public class Prototype {
    
        public static void main(String[] args) {
            NvRen nvren1 = new NvRen("小责圆", "瓜子脸", "葫芦型", "气质高雅型");
            NvRen nvren2 = nvren1.clone();
            nvren2.setName("松岛丰");
            NvRen nvren3 = nvren1.clone();
            nvren3.setName("饭到爱");
            NvRen nvren4 = nvren1.clone();
            // nvren4.setName("罗玉风"); //这个实在不好卖,即使只有名字和其他的不一样
            nvren4.setName("苍老师");
        }
    }

    当我们的产品投放到市场的时候,却很是悲摧了,因为他们投诉我们生产的女人只有一个却顶着不同的名字到处卖。

    我们只能再次研究,最后发现我们的一个工程师为了更加方便的生产,对我们的女人类作了些改变:

    class RouTi {
        private String head;
        private String body;
        private String type;
        public RouTi(String head, String body, String type) {
            this.head = head;
            this.body = body;
            this.type = type;
        }
    }
    
    class NvRen implements Cloneable {
        private String name;
        private RouTi routi;
    
        public NvRen(String name, String head, String body, String type) {
            this.name = name;
            this.routi = new RouTi(head, body, type);
        }
        private NvRen(String name, RouTi routi) {
            this.name = name;
            this.routi = routi;
        }
        public void setName(String name) {
            this.name = name;
        }
        public RouTi getRouTi() {
            return this.routi;
        }
        @Override
        protected NvRen clone() {
            NvRen nr = null;
            try {
                nr = (NvRen) super.clone();
            } catch (CloneNotSupportedException e) {
                nr = new NvRen(this.name, this.routi);
            }
            return nr;
        }
    }

    我们做了一些测试发现这些女人虽然有不同的名字,但是她们共用一个肉体

    public class Prototype {
    
        public static void main(String[] args) {
            NvRen nvren1 = new NvRen("小责圆", "瓜子脸", "葫芦型", "气质高雅型");
            System.out.println(nvren1.getRouTi().toString());
            NvRen nvren2 = nvren1.clone();
            nvren2.setName("松岛丰");
            System.out.println(nvren2.getRouTi().toString());
            NvRen nvren3 = nvren1.clone();
            nvren3.setName("饭到爱");
            System.out.println(nvren3.getRouTi().toString());
            NvRen nvren4 = nvren1.clone();
            // nvren4.setName("罗玉风"); //这个实在不好卖,即使只有名字和其他的不一样
            nvren4.setName("苍老师");
            System.out.println(nvren4.getRouTi().toString());
        }
    }
    
    
    //------> output
    //com.pattern.now.RouTi@1fc4bec
    //com.pattern.now.RouTi@1fc4bec
    //com.pattern.now.RouTi@1fc4bec
    //com.pattern.now.RouTi@1fc4bec

    经研究发现:当我们使用clone方法的时候,我们做的只是浅克隆,浅克隆只会复制值类型的属性,引用类型的属性只会复制其引用(即指针)而不会复制整个引用的对象。

    所以我们要克隆女人的时候还得克隆肉体:

    class RouTi implements Cloneable {
        private String head;
        private String body;
        private String type;
    
        public RouTi(String head, String body, String type) {
            this.head = head;
            this.body = body;
            this.type = type;
        }
    
        @Override
        protected RouTi clone() {
            RouTi rt = null;
            try {
                rt = (RouTi) super.clone();
            } catch (CloneNotSupportedException e) {
                rt = new RouTi(this.head, this.body, this.type);
            }
            return rt;
        }
    }
    
    class NvRen implements Cloneable {
        private String name;
        private RouTi routi;
    
        public NvRen(String name, String head, String body, String type) {
            this.name = name;
            this.routi = new RouTi(head, body, type);
        }
    
        private NvRen(String name, RouTi routi) {
            this.name = name;
            this.routi = routi;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public RouTi getRouTi() {
            return this.routi;
        }
    
        @Override
        protected NvRen clone() {
            NvRen nr = new NvRen(this.name, this.routi.clone());
            return nr;
        }
    }

    这时我们就能得到正确的结果:不同的女人有不同的肉体

    //--->output
    //com.pattern.now.RouTi@1fc4bec
    //com.pattern.now.RouTi@dc8569
    //com.pattern.now.RouTi@1bab50a
    //com.pattern.now.RouTi@c3c749

    这是我们的一个宅男工程师提出一个问题: 当我们的的肉体类种新加一个属性叫likeWho,并且 值是女人类:

    private NvRen likeWho;

    哥只能说:遇到这种情况,要么是你的女人类设计得有问题,要么就只能放弃原型模式。

  • 相关阅读:
    #公式与实现# Jacobi迭代 Gauss-Seidel迭代
    数据结构-C:二叉树的遍历
    c++
    Unix Systems Programming
    二进制文件读取写入(一)
    关于理论、模型与算法
    《计算机图形学与几何造型导论》读书笔记1
    petaPar培训文档
    等参元的高斯积分详解
    水平集函数具体实现
  • 原文地址:https://www.cnblogs.com/biglaojiang/p/3071183.html
Copyright © 2011-2022 走看看