zoukankan      html  css  js  c++  java
  • 原型模式


    title: 原型模式
    date: 2021-07-27 21:54:36
    tags:

    • 设计模式
      categories:
    • 程序设计基础

    原型模式

    概述

    原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。

    场景

    如果有一个对象,希望生成与其完全相同的一个复制品。最直接的步骤就是创建一个相同的类,然后遍历所有成员变量赋值到新对象中。

    问题

    有些对象可能拥有私有的成员变量在本身之外不可见,同时还有一个问题:必须知道所属的类才能创建复制品,所以代码必须依赖该类,但于此同时你可能仅知道这个对象所实现的接口,但还并不知道所属具体类。

    解决方法

    让对象实现克隆的功能。调用这个克隆的功能会生成一个完全一样的对象。

    代码实例

    // 原型类
    public abstract class Shape implements Cloneable {
    
        public int positionX;
    
        public int positionY;
    
        private Ref ref;
    
        public Ref getRef() {
            return ref;
        }
    
      	// 测试深浅拷贝
        public void setRef(Ref ref) {
            this.ref = ref;
        }
    
        public Shape(int positionX, int positionY) {
            this.positionX = positionX;
            this.positionY = positionY;
        }
    
        public int getPositionX() {
            return positionX;
        }
    
        public void setPositionX(int positionX) {
            this.positionX = positionX;
        }
    
        public int getPositionY() {
            return positionY;
        }
    
        public void setPositionY(int positionY) {
            this.positionY = positionY;
        }
    
        @Override
        protected Shape clone() throws CloneNotSupportedException {
            System.out.println("原型克隆成功");
            return (Shape) super.clone();
        }
    }
    
    
    public class Rectangle extends Shape {
    
        public Rectangle(int positionX, int positionY, int width, int length) {
            super(positionX, positionY);
            this.width = width;
            this.length = length;
        }
    
        public Rectangle(int positionX, int positionY) {
            super(positionX, positionY);
        }
    
        private int width;
    
        private int length;
    
    
    
        public void setWidth(int width) {
            this.width = width;
        }
    
        public void setLength(int length) {
            this.length = length;
        }
    
        @Override
        public String toString() {
            return "Rectangle{" +
                    "width=" + width +
                    ", length=" + length +
                    ", positionX=" + positionX +
                    ", positionY=" + positionY +
                    '}';
        }
    }
    
    // 测试引用类
    public class Ref {
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    // 测试类
    public class Client {
        public static void main(String[] args) throws CloneNotSupportedException {
            // 在x=4,y=5 坐标下创建一个长为4,宽为2的矩形
            Rectangle rectangle = new Rectangle(4, 5, 4, 2);
    
            Ref ref = new Ref();
            ref.setName("jack");
            rectangle.setRef(ref);
    
            // 复制一下
            Shape rectangleClone = rectangle.clone();
            // 查看一下位置和大小
            System.out.println(rectangleClone);
            // 查看是否是同一个对象
            System.out.println(rectangle == rectangleClone);
    
            // 验证clone是浅克隆:结果是浅拷贝
            rectangleClone.getRef().setName("rose");
            System.out.println(rectangle.getRef().getName());
        }
    }
    

    总结

    1. clone方法是浅拷贝,如果要实现深拷贝需要用流来处理
    2. 克隆包含循环引用的对象很麻烦
    3. 克隆对象要实现Cloneable接口
  • 相关阅读:
    解决Vss链接问题清除Windows共享登录的用户名密码记录(转)
    C# 激活正在运行的程序
    Log4Net 使用方法
    对Javascript闭包的一些理解
    根据数据库获取表名集合,根据表名获取字段信息
    C#引用类型和值类型的区别(转)
    c++强制类型转换:dynamic_cast、const_cast 、static_cast、reinterpret_cast
    理解VC工程文件类型
    MFC中的UpdateData()
    字节对齐
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/15068430.html
Copyright © 2011-2022 走看看