原型模式【构建模式】

原型模式

Specify the kinds of objects to create using a prototypical instance,
and create new objects by coping the prototype。
通过原型实例指定创建对象的种类,并通过拷贝这个原型实例来创建新的对象。
public class Prototype {
    /**
     * 原型模式:
     * Specify the kinds of objects to create using a prototypical instance,
     * and create new objects by coping the prototype。
     * 通过原型实例指定创建对象的种类,并通过拷贝这个原型实例来创建新的对象。
     */
    @Test
    public void testlone() throws CloneNotSupportedException {
        final User user = new User();
        user.setName("name");

        /**
         * clone 操作直接基于内存实现,不会调用构造函数,执行速度快,原型模式适合在创建大量的相同实例时使用。
         */
        final User clone = user.clone();
        assertEquals("name", clone.getName());
    }

    @Test
    public void shadowDeepCopy() throws CloneNotSupportedException {
        final List<String> alias = Lists.newArrayList();
        alias.add("first");

        final ShadowCopy shadowCopy = ShadowCopy.builder().alias(alias).build();
        final ShadowCopy clone = shadowCopy.clone();
        /**
         * 浅拷贝:对象属性直接引用原实例,修改克隆实例的此属性会影响原对象
         */
        clone.getAlias().add("second");
        assertEquals(shadowCopy.getAlias(), clone.getAlias());

        final DeepCopy deepCopy = DeepCopy.builder().alias(Arrays.asList("third")).build();
        final DeepCopy deepClone = deepCopy.clone();
        deepClone.getAlias().add("fourth");

        assertEquals(1, deepCopy.getAlias().size());
        assertEquals(2, deepClone.getAlias().size());
    }
}

@Data
@Slf4j
class User implements Cloneable {
    private String name;

    public User() {
        log.info("invoke constructor {}", getClass().getName());
    }

    @Override
    protected User clone() throws CloneNotSupportedException {
        return (User) super.clone();
    }
}

@Data
@Builder
class ShadowCopy implements Cloneable{
    private List<String> alias;

    @Override
    protected ShadowCopy clone() throws CloneNotSupportedException {
        return (ShadowCopy) super.clone();
    }
}

@Data
@Builder
class DeepCopy implements Cloneable{
    private List<String> alias;

    @Override
    protected DeepCopy clone() throws CloneNotSupportedException {
        final DeepCopy deepCopy = (DeepCopy) super.clone();
        /**
         * 重新设置 alias 属性的值:基于当前 alias 创建新的实例
         */
        deepCopy.setAlias(Lists.newArrayList(alias));
        return deepCopy;
    }
}
原文地址:https://www.cnblogs.com/zhuxudong/p/10163877.html