title: 原型模式
author: rack-leen
avatar: /images/favicon.png
authorDesc: 脱发典范
comments: true
copyright: true
date: 2019-5-19 00:00:00
tags:
Specify the kinds of objects to create using a prototypical instance , and create new objects by copying this prototye.
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建对象。
我们为幼儿园小朋友发成绩表,他们的年龄和成绩都一样,我们只需要改成绩表的名字就行了。
/**
* 原型模式需要实现Cloneable接口
*/
@Data
@ToString
public class Student implements Cloneable {
private String name ;
private String age ;
private String score ;
private ArrayList<Student> students = new ArrayList<>();
private final ArrayList<Student> finalStudent = new ArrayList<>();
public Student(String name, String age, String score) {
this.name = name;
this.age = age;
this.score = score;
System.out.println(name + "创建成功");
}
/**
* 这个方法是原型模式的基础
* @return
* @throws CloneNotSupportedException
*/
public Student clone() {
System.out.println("学生拷贝成功");
Student student = null ;
try {
// 这是一种浅拷贝,只能拷贝基本类型(包括string),其他的数组这些引用类型就与原型对象共享。
student = (Student) super.clone() ;
// 这个是深拷贝,将数组和引用一起拷贝,每个拷贝的对象有自己的数组和引用
this.students = (ArrayList<Student>) this.students.clone();
// 这个finalStudent是由final修饰,,不能重新赋值,不能拷贝
// this.finalStudent = (ArrayList<Student>) this.finalStudent.clone() ;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return student ;
}
}
public class Test {
public static void main(String[] args) {
Student rack = new Student("rack", "12", "16");
Student clone = (Student) rack.clone();
clone.setName("leen");
System.out.println(rack);
System.out.println(clone);
}
}
为原型模式增加一个原型管理器,用来管理原型的创建。
现在我们要创建一个学校,学校里面有教师,学生等实体,我们需要以一个教师和学生作为原型,创建出多个教师和学生。
public interface School extends Cloneable {
public School clone();
}
@Data
@ToString
public class Student implements School {
private String name ;
private String age ;
private String score ;
private ArrayList<Student> students = new ArrayList<>();
private final ArrayList<Student> finalStudent = new ArrayList<>();
public Student(String name, String age, String score) {
this.name = name;
this.age = age;
this.score = score;
System.out.println(name + "创建成功");
}
/**
* 这个方法是原型模式的基础
* @return
* @throws CloneNotSupportedException
*/
public Student clone() {
System.out.println("学生拷贝成功");
Student student = null ;
try {
// 这是一种浅拷贝,只能拷贝基本类型(包括string),其他的数组这些引用类型就与原型对象共享。
student = (Student) super.clone() ;
// 这个是深拷贝,将数组和引用一起拷贝,每个拷贝的对象有自己的数组和引用
this.students = (ArrayList<Student>) this.students.clone();
// 这个finalStudent是由final修饰,,不能重新赋值,不能拷贝
// this.finalStudent = (ArrayList<Student>) this.finalStudent.clone() ;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return student ;
}
}
@Data
@ToString
public class Teacher implements School {
private String name ;
private String age ;
private String subject ;
public Teacher(String name, String age, String subject) {
this.name = name;
this.age = age;
this.subject = subject;
}
public Teacher clone(){
Teacher teacher = null ;
try {
teacher = (Teacher) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return teacher ;
}
}
public class PrototypeManager {
public Map<String , School> map = new HashMap<>();
/**
* 增加除了教师学生之外的学校职位
* @param key
* @param value
*/
public void add(String key , School value){
this.map.put(key , value);
}
/**
* 从原型池中获取原型,如果原型不存在,抛异常
* @param key
* @return
*/
public School get(String key){
School school = null;
try {
school = this.map.get(key);
}catch (Exception e){
e.printStackTrace();
}
return school ;
}
}
public class Test {
public static void main(String[] args) {
PrototypeManager prototypeManager = new PrototypeManager();
prototypeManager.add("teacher" , new Teacher("teacher1" , "21" , "数学"));
Teacher teacher1 = (Teacher)prototypeManager.get("teacher");
Teacher teacher2 = teacher1.clone();
teacher2.setName("teacher2");
prototypeManager.add("student" , new Student("student1" , "12" , "45"));
Student student1 = (Student)prototypeManager.get("student");
Student student2 = student1.clone();
student2.setName("student2");
System.out.println(teacher1);
System.out.println(teacher2);
System.out.println(student1);
System.out.println(student2);
}
}