参考:原型模式 | 菜鸟教程
首先一点,原型模式是用来创建对象的,只不过不是使用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, " "; } } //第一个学生 $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, " "; } } //创建一个原型 $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 + " " + "class: " + this._class + " " + "name : " + this.name +" " + "score: " + this.score + " " ); } // 通过调用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 } }