【设计模式】工厂模式

工厂方法模式介绍

在OO编程中,创建对象实例的方法一般都是通过new操作符,但是在某些情况下,new操作符直接生成对象会带来问题,比如对象的创造需要一系列的步骤;需要计算后才能得到对象的初始值;选择生成哪个子类对象。对于上述的情况,一个对象的创建就好像是一个过程,为了屏蔽复杂的创建过程,提出了工厂模式的设计思想。

工厂方法的定义

定义一个用于创建对象的接口,让子类决定实例化哪个对象。

工厂方法的使用场景

在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new可以完成创建的对象无需使用工厂模式

工厂方法的UML类图

工厂方法中一般有四大模块:

  1. 抽象工厂:是工厂方法模式的核心
  2. 具体工厂:实现了具体的业务逻辑
  3. 抽象产品:工厂方法模式所创建的产品的父类
  4. 具体产品:实现抽象产品的某个具体产品的对象。

工厂方法多有个表现形式:

  1. 简单工厂方法(又称静态工厂模式)
  2. 工厂方法
  3. 抽象工厂方法

简单工厂方法(静态工厂模式)

简单工厂方法,明确了工厂类只有一个,因此不需要为工厂提供抽象类,因此将工厂方法改为静态方法即可。
在这里插入图片描述

简单工厂方法如下:

public class PizzaStore {

    public Pizza orderPizza(String type) {
        Pizza pizza;
        pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
    
    //简单工厂方法(静态工厂方法)
    public static Pizza createPizza(String type) {
        if ("CHINA".equals(type)) {
            return new ChinaStyleOnePizza();
        } else if ("NY".equals(type)) {
            return new NYStyleOnePizza();
        }
        return null;
    }
}

工厂方法

工厂方法的UML类图如下:
在这里插入图片描述

在图中,Pizza是抽象产品,ChinaStylePizza、NYStylePizza是具体产品,PizzaStore是抽象工厂,ChinaStylePizzaStore、NYStylePizzaStore是具体的工厂。
ChinaStylePizzaStore的代码如下:

public class ChinaStyleStore extends PizzaStore {
    @Override
    protected <T extends Pizza> T createPizza(Class<T> clz) {
        Pizza pizza = null;
        try {
            pizza = (Pizza) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) pizza;
    }
}

在该具体工厂中使用反射的方式,更加简洁的生产具体产品对象。

抽象工厂方法

抽象工厂方法主要是具有多个产品,多个工厂,属于工厂方法的变种。暂不做讨论
在这里插入图片描述

工厂方法的简单实例

Pizza抽象产品:

public abstract class Pizza {
    protected String name;    //名称
    protected String dough;   //面团类型
    protected String sauce;   //酱料类型
    protected ArrayList toppings = new ArrayList();   //佐料

    void prepare(){
        System.out.println("Preparing " + name);
        System.out.println("Tossing dough...");     //搅拌面团
        System.out.println("Adding sauce...");      //添加酱料
        System.out.println("Adding toppings: ");    //添加佐料
        for (Object topping : toppings) {
            System.out.println("    " + topping);
        }
    }

    void bake(){
        System.out.println("Bake for 25 minutes at 350");
    }

    void cut(){
        System.out.println("Cutting the pizza into diagonal slices");
    }

    void box(){
        System.out.println("Please pizza in official PizzaStore box");
    }

    public String getName(){
        return name;
    }
}

抽象工厂PizzaStore类

public abstract class PizzaStore {

    public Pizza orderPizza(Class clz){
        Pizza pizza;
        pizza = createPizza(clz);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }

    protected abstract <T extends Pizza> T createPizza(Class<T> clz);
}

具体产品

public class NYStyleOnePizza extends Pizza {
    public NYStyleOnePizza() {
        name = "NY Style and One Pizza";
        dough = "NY Style One dough";
        sauce = "NY Style One sauce";
        toppings.add("NY Style One topping");
    }
}

public class ChinaStyleOnePizza extends Pizza {
    public ChinaStyleOnePizza() {
        name = "China Style One Pizza";
        sauce = "China Style One sauce";
        dough = "China Style One dough";
        toppings.add("China Style One toppings");
    }
}

具体工厂

public class ChinaStyleStore extends PizzaStore {
    @Override
    protected <T extends Pizza> T createPizza(Class<T> clz) {
        Pizza pizza = null;
        try {
            pizza = (Pizza) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) pizza;
    }
}

Retrofit中的工厂方法

retrofit使用了工厂方法,其中一个例子就是CallAdapter。

//通过converter转换器将call<T>对象转换成java对象
public interface CallAdapter<R, T> {
  
  //type代表实参
  Type responseType();

  //返回一个代表call的实例
  T adapt(Call<R> call);

  abstract class Factory {
    
    //返回call adapter的接口方法的调用适配器,如果工厂未处理,则返回null
    public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);

    //从{@code type}中提取{@code index}处的泛型参数的上限。例如,{@code Map <String的索引1,? extends Runnable>}返回{@code Runnable}。
    protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }

    //返回type
    protected static Class<?> getRawType(Type type) {
      return Utils.getRawType(type);
    }
  }
}

与上述Pizza的例子不同的是,这里的工厂方法的抽象产品使用了interface接口类,而不是抽象类。在CallAdapter这个抽象类中,定义了内部抽象类Factory,而Factory中定义了get()这个抽象工厂方法,因此不同的工厂需要对这个get方法进行适配。

具体工厂类就有RxJava2CallAdapterFactory、RxJavaCallAdapterFactory、GuavaCallAdapterFactory等,这里以RxJava2为例

public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
  /**
   * Returns an instance which creates synchronous observables that do not operate on any scheduler
   * by default.
   */
  public static RxJava2CallAdapterFactory create() {
    return new RxJava2CallAdapterFactory(null, false);
  }

  /**
   * Returns an instance which creates asynchronous observables. Applying
   * {@link Observable#subscribeOn} has no effect on stream types created by this factory.
   */
  public static RxJava2CallAdapterFactory createAsync() {
    return new RxJava2CallAdapterFactory(null, true);
  }

  /**
   * Returns an instance which creates synchronous observables that
   * {@linkplain Observable#subscribeOn(Scheduler) subscribe on} {@code scheduler} by default.
   */
  @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
  public static RxJava2CallAdapterFactory createWithScheduler(Scheduler scheduler) {
    if (scheduler == null) throw new NullPointerException("scheduler == null");
    return new RxJava2CallAdapterFactory(scheduler, false);
  }

  private final @Nullable Scheduler scheduler;
  private final boolean isAsync;

  private RxJava2CallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
    this.scheduler = scheduler;
    this.isAsync = isAsync;
  }

  @Override public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    Class<?> rawType = getRawType(returnType);

    if (rawType == Completable.class) {
      // Completable is not parameterized (which is what the rest of this method deals with) so it
      // can only be created with a single configuration.
      return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
          false, true);
    }

    boolean isFlowable = rawType == Flowable.class;
    boolean isSingle = rawType == Single.class;
    boolean isMaybe = rawType == Maybe.class;
    if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
      return null;
    }

    boolean isResult = false;
    boolean isBody = false;
    Type responseType;
    if (!(returnType instanceof ParameterizedType)) {
      String name = isFlowable ? "Flowable"
          : isSingle ? "Single"
          : isMaybe ? "Maybe" : "Observable";
      throw new IllegalStateException(name + " return type must be parameterized"
          + " as " + name + "<Foo> or " + name + "<? extends Foo>");
    }

    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
    Class<?> rawObservableType = getRawType(observableType);
    if (rawObservableType == Response.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Response must be parameterized"
            + " as Response<Foo> or Response<? extends Foo>");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
    } else if (rawObservableType == Result.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Result must be parameterized"
            + " as Result<Foo> or Result<? extends Foo>");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
      isResult = true;
    } else {
      responseType = observableType;
      isBody = true;
    }

    return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
        isSingle, isMaybe, false);
  }
}

在RxJava2CallAdapterFactory方法中,get方法配置了RxJava2所需要属性,然后返回一个RxJava2CallAdapter对象。

产品类有RxJava2CallAdapter、 RxJavaCallAdapter等

final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
  private final Type responseType;
  private final @Nullable Scheduler scheduler;
  private final boolean isAsync;
  private final boolean isResult;
  private final boolean isBody;
  private final boolean isFlowable;
  private final boolean isSingle;
  private final boolean isMaybe;
  private final boolean isCompletable;

  RxJava2CallAdapter(Type responseType, @Nullable Scheduler scheduler, boolean isAsync,
      boolean isResult, boolean isBody, boolean isFlowable, boolean isSingle, boolean isMaybe,
      boolean isCompletable) {
    this.responseType = responseType;
    this.scheduler = scheduler;
    this.isAsync = isAsync;
    this.isResult = isResult;
    this.isBody = isBody;
    this.isFlowable = isFlowable;
    this.isSingle = isSingle;
    this.isMaybe = isMaybe;
    this.isCompletable = isCompletable;
  }

  @Override public Type responseType() {
    return responseType;
  }

  @Override public Object adapt(Call<R> call) {
    Observable<Response<R>> responseObservable = isAsync
        ? new CallEnqueueObservable<>(call)
        : new CallExecuteObservable<>(call);

    Observable<?> observable;
    if (isResult) {
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
      observable = new BodyObservable<>(responseObservable);
    } else {
      observable = responseObservable;
    }

    if (scheduler != null) {
      observable = observable.subscribeOn(scheduler);
    }

    if (isFlowable) {
      return observable.toFlowable(BackpressureStrategy.LATEST);
    }
    if (isSingle) {
      return observable.singleOrError();
    }
    if (isMaybe) {
      return observable.singleElement();
    }
    if (isCompletable) {
      return observable.ignoreElements();
    }
    return RxJavaPlugins.onAssembly(observable);
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值