• 原型模式(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

  • 相关阅读:
    关于我这个bilibili主题的炫酷博客园css
    WSL(Windows Subsystem for Linux)的安装与使用【OI选手的不二选择】
    JSOI2019 round2 游记
    JSOI2019&12省联考退役记
    Thuwc 2019&Noi WC 2019 游记
    CF284A Cows and Primitive Roots
    CF261B Maxim and Restaurant
    洛谷P5840 [COCI2015]Divljak
    CF1295E Permutation Separation
    CF1295A Display The Number
  • 原文地址:https://www.cnblogs.com/fuckingPangzi/p/15751717.html
Copyright © 2020-2023  润新知