Java设计模式之原型模式

Java设计模式之原型模式

  • 1. 概述
  • 2. 主要角色
  • 3. 浅拷贝
  • 4. 深拷贝
  • 5. 原型模式实现
  • 6. 原型模式改进


1. 概述

原型模式: 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。

使用场景:

  1. 对象的创建非常复杂,可以使用原型模式快捷的创建对象。
  2. 性能和安全要求比较高。

2. 主要角色

  • 抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
  • 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象。

3. 浅拷贝

浅拷贝: 对于基本数据类型,会直接复制值给拷贝对象;对于引用数据类型,只拷贝对象地址,指向原来对象的地址。

// 基本类型浅拷贝:

int a = 100;
int b = a;
System.out.println(a); // 100
System.out.println(b); // 100
System.out.println(a==b); // true

// 引用数据类型浅拷贝:

// 定义学生类
class Student{
        private String name;
        int age;

        public Student(String name, int age) {
                this.name = name;
                this.age = age;
        }

        public String getName() {
                return name;
        }

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

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }
}
//测试

Student student1 = new Student("stu",18);
System.out.println(student1); // JavaPackage_1.Student@68b0af6

Student student2 = student1;
System.out.println(student2); // JavaPackage_1.Student@68b0af6
System.out.println(student1==student2); // true,student1和student2指向的是同一地址

student1.setName("newstu");
System.out.println(student2.getName()); // newstu,通过修改student1可以修改student2

4. 深拷贝

深拷贝: 无论基本类型还是引用类型,全部拷贝为一个新的对象,属性中引用的其他对象也会被拷贝,不指向原有对象的地址。


5. 原型模式实现

  • 在Java的Cloneable接口中提供的拷贝机制。
  • Java中的Object类中提供了clone()方法来实现浅拷贝。
  • 虽然对象成功拷贝,但是其内层对象并没有进行拷贝,依然只是对象引用的复制。
// 定义Food类
class Food{

        String food;

        public String getFood() {
                return food;
        }

        public void setFood(String food) {
                this.food = food;
        }

        public Food(String food) {
                this.food = food;
        }
}

// 定义Student类
class Student implements Cloneable{ // Cloneable接口

        @Override //重写clone()方法
        // 提升访问权限为public
        public Object clone() throws CloneNotSupportedException {
                return super.clone();
        }

        private Food food;
        private String name;
        int age;

        public Student() {
        }

        public Student(String name, int age, Food food) {
                this.name = name;
                this.age = age;
                this.food = food;
        }

        public String getName() {
                return name;
        }

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

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

        public void setFood(Food food){
                this.food = food;
        }

        public Food getFood(){
                return food;
        }

}

//测试

Student student1 = new Student("stu", 29,food);
Student student2 = (Student) student1.clone(); // 通过student1克隆student2,不通过new对象的形式创建

System.out.println(student1); // JavaPackage_1.Student@682a0b20
System.out.println(student2); // JavaPackage_1.Student@3d075dc0
System.out.println(student1==student2); // false,student1和student2指向的是不同地址

System.out.println(student1.getFood()); // JavaPackage_1.Food@58b835a
System.out.println(student2.getFood()); // JavaPackage_1.Food@58b835a
System.out.println(student1.getFood()==student2.getFood()); // true,student1.food和student2.food指向同一地址

food.setFood("orange");
System.out.println(student1.getFood().getFood()); // orange
System.out.println(student2.getFood().getFood()); // orange

这样,使用了clone()方法实现了浅拷贝,由测试结果知道,对象student1和student2中的food仍是指向的同一地址。下面,对上述代码进行改进,实现原型模式的深拷贝


6. 原型模式改进

Java设计模式之原型模式_第1张图片

下面,通过修改clone()方法实现深拷贝:

@Override
public Object clone() throws CloneNotSupportedException { // 提升访问权限
        Student student = (Student) super.clone();
        //针对成员变量进行拷贝
        student.name = new String(name);
        student.food = new Food(food.getFood());
        return student;
}

//测试

Food food  = new Food("apple");
System.out.println(food); // JavaPackage_1.Food@6d311334

//Java深拷贝,对内层的对象也进行拷贝。
Student student1 = new Student("stu", 29,food);
// 通过student1克隆student2,不通过new对象的形式创建
Student student2 = (Student) student1.clone(); 

System.out.println(student1); // JavaPackage_1.Student@3d075dc0
System.out.println(student2); // JavaPackage_1.Student@214c265e
System.out.println(student1==student2); // false,student1和student2指向的是不同地址

System.out.println(student1.getFood()); // JavaPackage_1.Food@6d311334
System.out.println(student2.getFood()); // JavaPackage_1.Food@448139f0
System.out.println(student1.getFood()==student2.getFood()); // false,student1.food和student2.food指向不同地址

food.setFood("orange");
System.out.println(student1.getFood().getFood()); // orange
System.out.println(student2.getFood().getFood()); // apple

——————END-2022-06-16——————

你可能感兴趣的:(java,原型模式,设计模式,建造者模式,java基础)