原型模式(Prototype)-创建型(Creational)设计模式

今天早上起床,突然脑子里面想起来,AbstractBeanDefinition试下了Clonable接口,Spring里面是使用了原型模式

现在一看代码,发现还真是有,所以就记录下来。

org.springframework.beans.factory.support.AbstractBeanDefinition的代码

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
        implements BeanDefinition, Cloneable {

@Override
    public Object clone() {
        return cloneBeanDefinition();
    }

public abstract AbstractBeanDefinition cloneBeanDefinition();

/**
   *
   *实现的深克隆
*/
protected AbstractBeanDefinition(BeanDefinition original) {
        setParentName(original.getParentName());
        setBeanClassName(original.getBeanClassName());
        setScope(original.getScope());
        setAbstract(original.isAbstract());
        setFactoryBeanName(original.getFactoryBeanName());
        setFactoryMethodName(original.getFactoryMethodName());
        setRole(original.getRole());
        setSource(original.getSource());
        copyAttributesFrom(original);

        if (original instanceof AbstractBeanDefinition) {
            AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original;
            if (originalAbd.hasBeanClass()) {
                setBeanClass(originalAbd.getBeanClass());
            }
            if (originalAbd.hasConstructorArgumentValues()) {
                setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
            }
            if (originalAbd.hasPropertyValues()) {
                setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
            }
            if (originalAbd.hasMethodOverrides()) {
                setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
            }
            Boolean lazyInit = originalAbd.getLazyInit();
            if (lazyInit != null) {
                setLazyInit(lazyInit);
            }
            setAutowireMode(originalAbd.getAutowireMode());
            setDependencyCheck(originalAbd.getDependencyCheck());
            setDependsOn(originalAbd.getDependsOn());
            setAutowireCandidate(originalAbd.isAutowireCandidate());
            setPrimary(originalAbd.isPrimary());
            copyQualifiersFrom(originalAbd);
            setInstanceSupplier(originalAbd.getInstanceSupplier());
            setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
            setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
            setInitMethodName(originalAbd.getInitMethodName());
            setEnforceInitMethod(originalAbd.isEnforceInitMethod());
            setDestroyMethodName(originalAbd.getDestroyMethodName());
            setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
            setSynthetic(originalAbd.isSynthetic());
            setResource(originalAbd.getResource());
        }
        else {
            setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
            setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
            setLazyInit(original.isLazyInit());
            setResourceDescription(original.getResourceDescription());
        }
    }

}

AbstractBeanDefinition的子类实现就是调用,AbstractBeanDefinition里面的#AbstractBeanDefinition(BeanDefinition original)实现深克隆

看看org.springframework.beans.factory.support.GenericBeanDefinition的实现方法

public GenericBeanDefinition(BeanDefinition original) {
        super(original);
    }

-------------------------------------------------------------------

现在说说本场主角,原型模式,分为:浅克隆、深克隆

浅克隆:简单的说,就是只克隆基本属性,对象属性没有进行克隆,用的还是同一个,当对象属性改变,所有的基于浅克隆的对象属性值就都改变了

深克隆:简单的说,就是对象属性也进行克隆

简单代码实现:

 

public class ProtoypePraticeDay4 {


    public static class ConstructorArgumentValues{

        public ConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) {
        }

        public ConstructorArgumentValues() {
        }
    }

    public static class PropertyValues{

        public PropertyValues(PropertyValues propertyValues) {
        }

        public PropertyValues() {
        }
    }

    public static interface IncenseDefinition{
        public Integer getRole();

        public void setRole(Integer role);

        public String getScope();

        public void setScope(String scope);

        public String getParentName() ;

        public void setParentName(String parentName);

        public Boolean getPrimaryFlag() ;

        public void setPrimaryFlag(Boolean primaryFlag);

        public Boolean getAutowiredCandidateFlag();

        public void setAutowiredCandidateFlag(Boolean autowiredCandidateFlag);

        public Boolean getLazyInitFlag() ;

        public void setLazyInitFlag(Boolean lazyInitFlag);

        public Boolean getAbstractFlag() ;

        public void setAbstractFlag(Boolean abstractFlag) ;

        public String getIncenseFactoryBeanName() ;

        public void setIncenseFactoryBeanName(String incenseFactoryBeanName);

        public String getIncenseFactoryMethodName() ;

        public void setIncenseFactoryMethodName(String incenseFactoryMethodName);

        public String getIncenseClassName();

        public void setIncenseClassName(String incenseClassName);

        public ConstructorArgumentValues getConstructorArgumentValues();

        public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues);

        public PropertyValues getPropertyValues() ;

        public void setPropertyValues(PropertyValues propertyValues);

    }

    /**
     * 实现Cloneable接口
     */
    public static abstract class AbstractIncenseDefinition implements IncenseDefinition, Cloneable{

        private Boolean primaryFlag;

        private Boolean autowiredCandidateFlag;

        private Boolean lazyInitFlag;

        private Boolean abstractFlag;

        private String incenseFactoryBeanName;

        private String incenseFactoryMethodName;

        private String incenseClassName;

        private ConstructorArgumentValues constructorArgumentValues;

        private PropertyValues propertyValues;

        /**
         * 父incenseName
         */
        private String parentName;

        private String scope;

        private Integer role;

        @Override
        public Integer getRole() {
            return role;
        }

        @Override
        public void setRole(Integer role) {
            this.role = role;
        }

        @Override
        public String getScope() {
            return scope;
        }

        @Override
        public void setScope(String scope) {
            this.scope = scope;
        }

        @Override
        public String getParentName() {
            return parentName;
        }

        @Override
        public void setParentName(String parentName) {
            this.parentName = parentName;
        }

        @Override
        public Boolean getPrimaryFlag() {
            return primaryFlag;
        }

        @Override
        public void setPrimaryFlag(Boolean primaryFlag) {
            this.primaryFlag = primaryFlag;
        }

        @Override
        public Boolean getAutowiredCandidateFlag() {
            return autowiredCandidateFlag;
        }

        @Override
        public void setAutowiredCandidateFlag(Boolean autowiredCandidateFlag) {
            this.autowiredCandidateFlag = autowiredCandidateFlag;
        }

        @Override
        public Boolean getLazyInitFlag() {
            return lazyInitFlag;
        }

        @Override
        public void setLazyInitFlag(Boolean lazyInitFlag) {
            this.lazyInitFlag = lazyInitFlag;
        }

        @Override
        public Boolean getAbstractFlag() {
            return abstractFlag;
        }

        @Override
        public void setAbstractFlag(Boolean abstractFlag) {
            this.abstractFlag = abstractFlag;
        }

        @Override
        public String getIncenseFactoryBeanName() {
            return incenseFactoryBeanName;
        }

        @Override
        public void setIncenseFactoryBeanName(String incenseFactoryBeanName) {
            this.incenseFactoryBeanName = incenseFactoryBeanName;
        }

        @Override
        public String getIncenseFactoryMethodName() {
            return incenseFactoryMethodName;
        }

        @Override
        public void setIncenseFactoryMethodName(String incenseFactoryMethodName) {
            this.incenseFactoryMethodName = incenseFactoryMethodName;
        }

        @Override
        public String getIncenseClassName() {
            return incenseClassName;
        }

        @Override
        public void setIncenseClassName(String incenseClassName) {
            this.incenseClassName = incenseClassName;
        }

        @Override
        public ConstructorArgumentValues getConstructorArgumentValues() {
            return constructorArgumentValues;
        }

        @Override
        public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) {
            this.constructorArgumentValues = constructorArgumentValues;
        }

        @Override
        public PropertyValues getPropertyValues() {
            return null;
        }

        @Override
        public void setPropertyValues(PropertyValues propertyValues) {

        }

        /**
         * 克隆抽象方法,子类去实现
         * @return
         */
        public abstract AbstractIncenseDefinition cloneIncenseDefinition();

        /**
         * 使用cloneIncenseDefinition()实现深克隆
         * @return
         * @throws CloneNotSupportedException
         */
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return cloneIncenseDefinition();
        }

        public AbstractIncenseDefinition() {
        }

        /**
         * 这就是真正的深克隆构造方法实现
         * @param original
         */
        public AbstractIncenseDefinition(IncenseDefinition original){
            setParentName(original.getParentName());
            setIncenseClassName(original.getIncenseClassName());
            setScope(original.getScope());
            setAbstractFlag(original.getAbstractFlag());
            setIncenseFactoryBeanName(original.getIncenseFactoryBeanName());
            setIncenseFactoryMethodName(original.getIncenseFactoryMethodName());
            setRole(original.getRole());

            if (original instanceof AbstractIncenseDefinition){
                AbstractIncenseDefinition abstractIDF = (AbstractIncenseDefinition) original;
                setConstructorArgumentValues(new ConstructorArgumentValues(abstractIDF.constructorArgumentValues));
                setPropertyValues(new PropertyValues(abstractIDF.getPropertyValues()));
                setLazyInitFlag(abstractIDF.getLazyInitFlag());
                //还有设置很多属性
            }else{
                //不是AbstractIncenseDefinition这一类型的,就只能克隆IncenseDefinition上定义的方法
                setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
                setPropertyValues(new PropertyValues(original.getPropertyValues()));
            }
        }
    }

    public static class GenericIncenseDefinition extends AbstractIncenseDefinition{

        private String parentName;

        @Override
        public String getParentName() {
            return parentName;
        }

        @Override
        public void setParentName(String parentName) {
            this.parentName = parentName;
        }

        public GenericIncenseDefinition() {
            super();
        }

        public GenericIncenseDefinition(AbstractIncenseDefinition original) {
            super(original);
        }

        /**
         * 子类调用父类的构造方法
         * 这里也是精髓,直接new GenericIncenseDefinition(this)
         * 没有在父类里面去创建一个对象出来,再返回,我也是第一次见过这种,涨见识了
         * @return
         */
        @Override
        public AbstractIncenseDefinition cloneIncenseDefinition() {
            return new GenericIncenseDefinition(this);
        }
    }

}

爽,那现在来运行看看

public static void main(String[] args) {
        GenericIncenseDefinition genericIncenseDefinition = new GenericIncenseDefinition();
        genericIncenseDefinition.setParentName("testService");
        genericIncenseDefinition.setAbstractFlag(false);
        genericIncenseDefinition.setPrimaryFlag(false);
        genericIncenseDefinition.setConstructorArgumentValues(new ConstructorArgumentValues());
        GenericIncenseDefinition cloneIncenseDefiniton = (GenericIncenseDefinition) genericIncenseDefinition.cloneIncenseDefinition();
        System.out.println(genericIncenseDefinition);
        System.out.println(cloneIncenseDefiniton);

        System.out.println(genericIncenseDefinition.getConstructorArgumentValues());
        System.out.println(cloneIncenseDefiniton.getConstructorArgumentValues());
    }

结果如下,跟预想的一般,打印出来的hashCode地址是不一样的。

giao,这个花了我一个小时的时间整理出来,还行吧,有空有问题,望指出啊

com.lg.designpattern.prototype.ProtoypePraticeDay4$GenericIncenseDefinition@7f31245a
com.lg.designpattern.prototype.ProtoypePraticeDay4$GenericIncenseDefinition@6d6f6e28
com.lg.designpattern.prototype.ProtoypePraticeDay4$ConstructorArgumentValues@135fbaa4
com.lg.designpattern.prototype.ProtoypePraticeDay4$ConstructorArgumentValues@45ee12a7

posted @ 2021-12-31 09:49  正能量教官  阅读(128)  评论(0编辑  收藏  举报