设计模式-可复用面向对象软件设计的基础-对象创建型模式


设计模式-可复用面向对象软件设计的基础-对象创建型模式

对象创建型模式

对象创建型模式抽象了对象的实例化过程.帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类型创建模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另外一个对象

创建型模式的主要特点是该模式聚焦于对象的创建上,关注于对象创建的过程。因为同一个类不同的实例化过程会对该类所表现出来的行为产生影响。从而在创建时,通过不同的设计模式将该过程抽象出来适应不同的场景

创建型模式主要有以下5种类型:

  1. 抽象工厂模式
  2. 构造器模式
  3. 工厂模式
  4. 原型模式
  5. 单例模式

抽象工厂模式

意图

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

别名

Kit

动机

为解决对象工厂的创建问题。当一个业务场景需要多个工厂实例来创建对象时,如何创建这些工厂就可以使用抽象工厂模式来进行。这个模式操作的对象是是工厂对象,而不是具体工厂对象产生的实例对象。这样设计的好处是对外部来说只需要依赖AbstractFactory和AbstractProduct就可以了,不用关系具体BeanFactory和ProductFactory是怎么样被创建和依赖的。对AbstractFactory内部实现了Factory和Product的聚合。坏处在于增加一个Producty时会同时修改Abstract和创建新的具体的BeanFactory。

结构

抽象工厂模式
抽象工厂模式

实例

简单实现

  • AbstractFactory.java
java
public abstract class AbstractFactory{
    public abstract Object getObject(String type);
}

AbstractFactory抽象类定义获取对象的方法

  • ObjectFactory1
java
public class ObjectFactory1 extends AbstractFactory {
    @Override
    public Shape getObject(String objectType){
        if(objectType.equalsIgnoreCase("object1")){
            return new Object1();
        } 
        if(objectType.equalsIgnoreCase("object2")){
            return new Object1();
        }
        return null;
    }
}

ObjectFactory1作为工厂类继承抽象工厂类,并实现具体的抽象方法生产对象

  • Client
java
public class Client{
    //1. 生成工厂类
    public AbstractFactory getObject(String classType){

    }

    //2. 通过工厂类生成产品
    public void method(){
        AbstractFactory factory = getObject("classType");
        Object obj = factory.getObject("objectType")
    }
}

在客户端中主要有两步,第一个是获取具体的工厂类。第二个是根据工厂类获取对应的产品。从上面的代码中我们可以看到工厂的生成和产品的生成都需要按照不同的类型来选择生成的具体实现。抽象工厂模式管理的是工厂类。

Spring中的抽象工厂模式

AbstractBeanFactory主要有三个实现类XmlBeanFactory(已过时)AbstractAutowireCapableBeanFactoryDefaultListableBeanFactory
其中主要使用的是作为自动装配的工厂类AbstractAutowireCapableBeanFactory

build模式

意图

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同含义的对象。构造者模式要求构造对象足够复杂并且能够按照部分参数进行处理,构造者模式将内部对象初始化的细节封装起来,外部对象之间调用即可

结构

实例

  • lombok中的@Builder
java
    public class UserParam {
        private String userName;
        private String password;
    }

    //DELOMBOK之后的代码
    public class UserParam {
        private String userName;
        private String password;

        UserParam(String userName, String password) {
            this.userName = userName;
            this.password = password;
        }

        public static UserParamBuilder builder() {
            return new UserParamBuilder();
        }

        public static class UserParamBuilder {
            private String userName;
            private String password;

            UserParamBuilder() {
            }

            public UserParamBuilder userName(String userName) {
                this.userName = userName;
                return this;
            }

            public UserParamBuilder password(String password) {
                this.password = password;
                return this;
            }

            public UserParam build() {
                return new UserParam(userName, password);
            }

            public String toString() {
                return "UserParam.UserParamBuilder(userName=" + this.userName + ", password=" + this.password + ")";
            }
        }
}

可以看到lombok的@Builder注解只是在内部设置了一个静态方法和静态类来生成build方式,将Direct的职责交给类的使用者去处理了。

工厂模式

意图

定义一个创建对象的接口,让子类决定实例化具体的类对象。Factort Method使得类的实例化延迟到了子类使用的时候。

别名

虚构造器(Virtual Constructor)

结构

在图中可以看到产品必须抽象出一个接口,然后在通过工厂定义创建产品的方法。通过集成工厂接口实现不同的产品的初始化过程。

实例

spring工厂模式

  • FactoryBean.java
java
public interface FactoryBean<T> {
    
    //获取具体的类
	@Nullable
	T getObject() throws Exception;

    //获取类的类型
	@Nullable
	Class<?> getObjectType();

    //是否是单例
	default boolean isSingleton() {
		return true;
	}
}

泛型T是抽象的产品的接口,在FactoryBean的实现类上可以根据构造器或者在调用getObject()方法之前调用初始化方法来对生成的对象进行自定义的参数配置,这样做的好处是可以不改变调用端的逻辑从而增加一个产品子类

在具体的实现上,工厂模式有两种方式,1. 工厂类作为抽象类,提供抽象方法,由实现该类的子类具体的去做初始化产品的操作;2.工厂类不做为抽象类,并且提供默认的产品创建

原型模式

意图

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象

结构

原型模式是通过拷贝一个现有对象生成一个新的对象,需要主要的是原型模式是深拷贝而不是浅拷贝

单例模式

意图

保证一个全局只有一个类,并且提供一个访问它的全局访问点

结构

实例

Spring中的单例模式