美文网首页设计模式
设计模式-原型模式

设计模式-原型模式

作者: isLJli | 来源:发表于2020-05-16 19:07 被阅读0次

    原型设计模式的定义

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
    这里重点在拷贝,就像电脑的拷贝和复制粘贴。

    java的浅拷贝和深拷贝的区别
    浅拷贝:类里的类对象是共同一个引用。
    深拷贝:类里的类对象不是同一个引用
    系统自带的拷贝:实现Cloneable,复写clone()方法。

    原型模式的例子:

    UML图

    UML图
    public abstract class IBox implements Cloneable {
      
      abstract void setNumber(int number); //设置数量
    
      abstract int getNumber();
    
      @NonNull
      @Override
      protected IBox clone() throws CloneNotSupportedException {
          return (IBox) super.clone();
      }
    }
    
    public class CarPartBox extends IBox {
    
      private int number;
    
      private String name;
    
      private String carBrand;
    
      @Override
      public void setNumber(int number) {
          this.number = number;
      }
    
      @Override
      public int getNumber() {
          return number;
      }
    
    
      public String getName() {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
    
      public String getCarBrand() {
          return carBrand;
      }
    
      public void setCarBrand(String carBrand) {
          this.carBrand = carBrand;
      }
    }
    
    public class PlasticClampBox extends IBox {
    
      private int number;
    
      private String name;
    
      @Override
      public void setNumber(int number) {
          this.number = number;
      }
    
      @Override
      public int getNumber() {
          return number;
      }
    
    
      public String getName() {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
    }
    
    public class TruckCar {
    
      public IBox mIBox;
    
      public void addBox(IBox box){
          this.mIBox = box;
      }
      
      public IBox remove(){
          return mIBox;
      }
    
    }
    
    public class SplitService {
    
      public static List<TruckCar> splitBox(IBox box) {
          List<TruckCar> carList = new ArrayList<>();
    
          while (box.getNumber() > 200) {
    
              IBox newBox = null;
              try {
                  newBox = box.clone();
              } catch (CloneNotSupportedException e) {
                  e.printStackTrace();
              }
              newBox.setNumber(200);
              TruckCar truckCar = new TruckCar();
              truckCar.addBox(newBox);
              carList.add(truckCar);
              box.setNumber(box.getNumber() - 200);
    
          }
    
          TruckCar truckCar = new TruckCar();
          truckCar.addBox(box);
          carList.add(truckCar);
          return carList;
      }
    }
    

    浅拷贝的实现方式

    拷贝构造方法实现浅拷贝

    /* 拷贝构造方法实现浅拷贝 */
     @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          TextView textView = findViewById(R.id.ff);
          Person.Address mAddress = new Person.Address("广州市");
    
          Person person1 = new Person(mAddress, "tony");
    
          Person person2 = new Person(person1);
    
          System.out.println("p1是" + person1.toString());
          System.out.println("p2是" + person2.toString());
    
          person1.setName("小傻瓜");
          mAddress.setAddress("深圳市");
          System.out.println("修改后的p1是"+person1.toString());
          System.out.println("修改后的p2是"+person2.toString());
      }
    
    public class Person {
      private String name;
    
      private Address mAddress;
    
      public Person(Address address, String name) {
          this.mAddress = address;
          this.name = name;
      }
    
      public Person(Person person){
          this.mAddress = person.mAddress;
          this.name = person.name;
      }
    
      public String getName() {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
    
      public Address getAddress() {
          return mAddress;
      }
    
      public void setAddress(Address address) {
          mAddress = address;
      }
    
      @NonNull
      @Override
      public String toString() {
          String s ="姓名="+name+",地址="+mAddress.address;
          return s;
      }
    
      public static class Address {
          private String address;
    
          public Address(String address){
              this.address = address;
          }
    
          public String getAddress() {
              return address;
          }
    
          public void setAddress(String address) {
              this.address = address;
          }
      }
    }
    

    打印结果:

    p1是姓名=tony,地址=广州市
    p2是姓名=tony,地址=广州市
    修改后的p1是姓名=小傻瓜,地址=深圳市
    修改后的p2是姓名=tony,地址=深圳市

    通过重写clone方法来实现深拷贝

     @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          TextView textView = findViewById(R.id.ff);
          Person.Address mAddress = new Person.Address("广州市");
    
          Person person1 = new Person(mAddress, "tony");
    
          Person person2 = new Person(person1);
    
          System.out.println("p1是" + person1.toString());
          System.out.println("p2是" + person2.toString());
    
          person1.setName("小傻瓜");
          mAddress.setAddress("深圳市");
          System.out.println("修改后的p1是"+person1.toString());
          System.out.println("修改后的p2是"+person2.toString());
      }
    
    
    public class Person implements Cloneable{
      private String name;
    
      private Address mAddress;
    
      public Person(Address address, String name) {
          this.mAddress = address;
          this.name = name;
      }
    
      public Person(Person person){
          this.mAddress = person.mAddress;
          this.name = person.name;
      }
    
      public String getName() {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
    
      public Address getAddress() {
          return mAddress;
      }
    
      public void setAddress(Address address) {
          mAddress = address;
      }
    
      @NonNull
      @Override
      protected Person clone() throws CloneNotSupportedException {
          return (Person) super.clone();
      }
    
      @NonNull
      @Override
      public String toString() {
          String s ="姓名="+name+",地址="+mAddress.address;
          return s;
      }
    
      public static class Address {
          private String address;
    
          public Address(String address){
              this.address = address;
          }
    
          public String getAddress() {
              return address;
          }
    
          public void setAddress(String address) {
              this.address = address;
          }
      }
    }
    

    打印结果:
    p1是姓名=tony,地址=广州市
    p2是姓名=tony,地址=广州市
    修改后的p1是姓名=小傻瓜,地址=深圳市
    修改后的p2是姓名=tony,地址=深圳市

    深拷贝的实现方式

    通过重写clone方法来实现深拷贝

    public class DeepCopy {
      public static void main(String[] args) {
          Age a=new Age(20);
          Student stu1=new Student("摇头耶稣",a,175);
          
          //通过调用重写后的clone方法进行浅拷贝
          Student stu2=(Student)stu1.clone();
          System.out.println(stu1.toString());
          System.out.println(stu2.toString());
          System.out.println();
          
          //尝试修改stu1中的各属性,观察stu2的属性有没有变化
          stu1.setName("大傻子");
          //改变age这个引用类型的成员变量的值
          a.setAge(99);
          //stu1.setaAge(new Age(99));    使用这种方式修改age属性值的话,stu2是不会跟着改变的。因为创建了一个新的Age类对象而不是改变原对象的实例值
          stu1.setLength(216);
          System.out.println(stu1.toString());
          System.out.println(stu2.toString());
      }
    }
    
    /*
    * 创建年龄类
    */
    class Age implements Cloneable{
      //年龄类的成员变量(属性)
      private int age;
      //构造方法
      public Age(int age) {
          this.age=age;
      }
      
      public int getAge() {
          return age;
      }
      
      public void setAge(int age) {
          this.age = age;
      }
      
      public String toString() {
          return this.age+"";
      }
      
      //重写Object的clone方法
      public Object clone() {
          Object obj=null;
          try {
              obj=super.clone();
          } catch (CloneNotSupportedException e) {
              e.printStackTrace();
          }
          return obj;
      }
    }
    /*
    * 创建学生类
    */
    class Student implements Cloneable{
      //学生类的成员变量(属性),其中一个属性为类的对象
      private String name;
      private Age aage;
      private int length;
      //构造方法,其中一个参数为另一个类的对象
      public Student(String name,Age a,int length) {
          this.name=name;
          this.aage=a;
          this.length=length;
      }
      public String getName() {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
      
      public Age getaAge() {
          return this.aage;
      }
      
      public void setaAge(Age age) {
          this.aage=age;
      }
      
      public int getLength() {
          return this.length;
      }
      
      public void setLength(int length) {
          this.length=length;
      }
      public String toString() {
          return "姓名是: "+this.getName()+", 年龄为: "+this.getaAge().toString()+", 长度是: "+this.getLength();
      }
      //重写Object类的clone方法
      public Object clone() {
          Object obj=null;
          //调用Object类的clone方法——浅拷贝
          try {
              obj= super.clone();
          } catch (CloneNotSupportedException e) {
              e.printStackTrace();
          }
          //调用Age类的clone方法进行深拷贝
          //先将obj转化为学生类实例
          Student stu=(Student)obj;
          //学生类实例的Age对象属性,调用其clone方法进行拷贝
          stu.aage=(Age)stu.getaAge().clone();
          return obj;
      }
    }
    

    姓名是: 摇头耶稣, 年龄为: 20, 长度是: 175
    姓名是: 摇头耶稣, 年龄为: 20, 长度是: 175
    姓名是: 大傻子, 年龄为: 99, 长度是: 216
    姓名是: 摇头耶稣, 年龄为: 20, 长度是: 175

    相关文章

      网友评论

        本文标题:设计模式-原型模式

        本文链接:https://www.haomeiwen.com/subject/ljdxohtx.html