原型模式

参考:原型模式 | 菜鸟教程

  首先一点,原型模式是用来创建对象的,只不过不是使用new关键字来创建对象,也不是使用工厂模式的静态方法创建,而是使用clone关键字。

  使用new关键字创建的对象,以及使用工厂方法创建的对象,每一个对象创建完成后,这个对象都是新的,这个“新”是指,没有进行过加工。

  原型模式创建对象时,是依靠一个已存在的对象,通过拷贝(克隆)这个已存在的对象的方式来创建对象。这个已存在对象,也许是刚创建的全新的对象,也可能是进行了很多操作的对象(经过加工的对象),比如设置了某些属性值之后的对象。

  举个例子:期末考试之后发成绩通知书,每个学生发一张通知书,通知书上需要填写学生的年级、班级、姓名、总评。可以有两种方式:

  方式1(工厂模式):拿出一张空白的通知书(new一个stu对象),设置这个stu对象的年级、班级、姓名、总评,每个学生都要执行这个操作。这个过程存在一个可以优化的点,因为都是一个班级的同学,那么,年级和班级肯定是一样的吧,如果每次都设置新的stu对象的年级、班级,那么这个操作就有点多余了,因为这个统一设置一次就OK了。

  方式2(原型模式):拿出一张空白的通知书(new一个stu对象),把这张通知书上的年级、班级先写好,然后,复印很多张出来,然后,对于每一张通知书,单独填写姓名和总评。

  

使用普通方法(方式1)来实现:

<?php
    class Student {
        private $grade;
        private $class;
        private $name;
        private $score;
        public function setGrade($grade) {
            $this->grade = $grade; 
        }

        public function setClass($class) {
            $this->class = $class; 
        }

        public function setName($name) {
            $this->name = $name;
        }

        public function setScore($score) {
            $this->score = $score;
        }

        public function showInformation() {
            echo $this->grade, " ", $this->class, " ", $this->name, " ", $this->score, "\n";
        }
    }
    
    //第一个学生
    $stu1 = new Student();
    $stu1->setGrade("大一");
    $stu1->setClass("四班");
    $stu1->setName("张三");
    $stu1->setScore(99);
    $stu1->showInformation();

    //第二个学生
    $stu2 = new Student();
    $stu2->setGrade("大一");
    $stu2->setClass("四班");
    $stu2->setName("李四");
    $stu2->setScore(100);
    $stu2->showInformation();

  

  

使用原型模式——PHP实现

<?php
    class Student {
        private $grade;
        private $class;
        private $name;
        private $score;
        public function setGrade($grade) {
            $this->grade = $grade; 
        }

        public function setClass($class) {
            $this->class = $class; 
        }

        public function setName($name) {
            $this->name = $name;
        }

        public function setScore($score) {
            $this->score = $score;
        }

        public function showInformation() {
            echo $this->grade, " ", $this->class, " ", $this->name, " ", $this->score, "\n";
        }
    }
    
    //创建一个原型
    $prototype = new Student();
    $prototype->setGrade("大一");
    $prototype->setClass("四班");

    //克隆原型,创建第一名同学
    $stu1 = clone $prototype;
    $stu1->setName("张三");
    $stu1->setScore("99");
    $stu1->showInformation();

    //克隆原型,创建第二名同学
    $stu2 = clone $prototype;
    $stu2->setName("张三");
    $stu2->setScore("99");
    $stu2->showInformation();

  

使用原型模式——Java实现

// 实现Cloneable接口
class Student implements Cloneable{
    private String grade;
    private String _class;
    private String name;
    private double score;

    public void setGrade(String grade) {
        this.grade = grade;
    }

    public void setClass(String _class) {
        this._class = _class;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void  setScore(double score) {
        this.score = score;
    }

    public void showInformation() {
        System.out.println(
            "grade: " + this.grade + "\n" +
            "class: " + this._class + "\n" +
            "name : " + this.name +"\n" +
            "score: " + this.score + "\n"
        );
    
    }
    
    // 通过调用super.clone()来实现clone方法
    public Student clone() throws CloneNotSupportedException {
        return (Student)super.clone();
    }
}
    
public class Test{
    public static void main(String[] args) throws Exception{

        // 创建一个原型
        Student prototype = new Student();
        prototype.setGrade("freshman");
        prototype.setClass("four");

        //克隆原型,创建第一名同学
        Student stu1 = prototype.clone();
        stu1.setName("LiMing");
        stu1.setScore(99);

        //克隆原型,创建第二名同学
        Student stu2 = prototype.clone();
        stu2.setName("LiBai");
        stu2.setScore(60);

        stu1.showInformation();
        // grade: freshman
        // class: four
        // name : LiMing
        // score: 99.0

        stu2.showInformation();
        // grade: freshman
        // class: four
        // name : LiBai
        // score: 60.0

        stu1.showInformation();
        // grade: freshman
        // class: four
        // name : LiMing
        // score: 99.0
    }
}

  

  

  

posted @ 2018-04-04 17:05  寻觅beyond  阅读(178)  评论(0编辑  收藏  举报
返回顶部