原型模式(五)

Andy 2023年06月06日 538次浏览

是用于创建重复的对象,同时又能保证性能,是通过克隆的模式来创建的,但是分浅克隆和深克隆
必须实现 Cloneable 接口
深克隆可以实现 Serializable 接口序列化读取二进制流

关于应用场景,优点,缺点等等,请参考https://www.runoob.com/design-pattern/prototype-pattern.html

看一个原型模式的例子
看下图
菜鸟的案例
我们将创建一个抽象类 Shape 和扩展了 Shape 类的实体类。下一步是定义类 ShapeCache,该类把 shape 对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆。

PrototypePatternDemo,我们的演示类使用 ShapeCache 类来获取 Shape 对象。
image.png

这个就好理解很多,,比构建者模式好多了,左边最大的框一个是抽象类和扩展它的实体类,当然抽象类你可以一样用实体类,不用抽象类,这里用抽象类是因为Hashtable ** 存储的是Shape类型,而实体类写了一些东西想让输出出来,如果不用抽象类的抽象方法可以覆盖一个父类的方法来表示
左边最大的框就是需要克隆的类,当然是它的实体类。右边的ShapeCache** 是它的缓存,或则池子,把克隆的实体类放在Hashtable 中,开头的main方法需要左边的对象时就从**Hashtable **中给它一个克隆的

直接上代码,更好理解
1、创建一个实现了 Cloneable 接口的抽象类。
Shape.java

public abstract class Shape implements Cloneable {
   
   private String id;
   protected String type;
   abstract void draw();
   
   public String getType(){
      return type;
   }
   
   public String getId() {
      return id;
   }
   
   public void setId(String id) {
      this.id = id;
   }
   //必须要重写clone
   public Object clone() {
      Object clone = null;
      try {
         clone = super.clone();
      } catch (CloneNotSupportedException e) {
         e.printStackTrace();
      }
      return clone;
   }
}

2、创建扩展了上面抽象类的三个实体类。
Rectangle.java

   public class Rectangle extends Shape {
       public Rectangle(){
         type = "Rectangle";
       }
     
       @Override
       public void draw() {
          System.out.println("Inside Rectangle::draw() method.");
       }
    }

Square.java

 public class Square extends Shape {
     
       public Square(){
         type = "Square";
       }
     
       @Override
       public void draw() {
          System.out.println("Inside Square::draw() method.");
       }
    }

Circle.java

    public class Circle extends Shape {
     
       public Circle(){
         type = "Circle";
       }
     
       @Override
       public void draw() {
          System.out.println("Inside Circle::draw() method.");
       }
    }

3、创建一个类,从数据库获取实体类,并把它们存储在一个 Hashtable 中。
ShapeCache.java

import java.util.Hashtable;
 
public class ShapeCache {
    
   private static Hashtable<String, Shape> shapeMap 
      = new Hashtable<String, Shape>();
 
   public static Shape getShape(String shapeId) {
   //根据ShapeIID来判别它需要哪个的克隆
      Shape cachedShape = shapeMap.get(shapeId);
      //返回它的克隆
      return (Shape) cachedShape.clone();
   }
 
   // 对每种形状都运行数据库查询,并创建该形状
   // shapeMap.put(shapeKey, shape);
   // 例如,我们要添加三种形状
   public static void loadCache() {
      Circle circle = new Circle();
      circle.setId("1");
      shapeMap.put(circle.getId(),circle);
 
      Square square = new Square();
      square.setId("2");
      shapeMap.put(square.getId(),square);
 
      Rectangle rectangle = new Rectangle();
      rectangle.setId("3");
      shapeMap.put(rectangle.getId(),rectangle);
   }
}

4、PrototypePatternDemo 使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。
PrototypePatternDemo.java

public class PrototypePatternDemo {
   public static void main(String[] args) {
      ShapeCache.loadCache();
 
      Shape clonedShape = (Shape) ShapeCache.getShape("1");
      System.out.println("Shape : " + clonedShape.getType());        
 
      Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
      System.out.println("Shape : " + clonedShape2.getType());        
 
      Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
      System.out.println("Shape : " + clonedShape3.getType());        
   }
}

步骤 5
执行程序,输出结果:

Shape : Circle
Shape : Square
Shape : Rectangle

这里演示的是浅克隆,而不是深克隆,深克隆可以通过Shape实现Serializable 接口,序列化通过二进制流进行输入再读取来实现,
可以参考我另一个关于深克隆和浅克隆的博客java的浅克隆和深克隆
————————————————
版权声明:本文为CSDN博主「胖墩的IT」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43113679/article/details/99338971