美文网首页
工厂模式和建造者模式

工厂模式和建造者模式

作者: 风雪围城 | 来源:发表于2017-11-25 20:42 被阅读0次

背景

关于工厂模式和建造者模式,是两个意思比较相近的概念。近期在项目中抽象逻辑层的遇到了这个问题,这里整理区分一下,以便在以后能够更好的使用。
本质上来讲,所有模式都是固定的套路,然而,总是先是熟练使用所有招数,然后才能无招胜有招吧。

工厂模式

顾名思义,工厂是用来生产东西的。自定义工厂,当然就是你让它生产什么,它就该生产什么。这里的什么,其实就是对象。
这样一来,其实这种模式是用来封装对象的创建的。这是非常重要的一个目的。(我认为至少有两个目的)

那么,为什么连创建一个对象的过程,都需要封装吗?答案是看你的使用场景和需求。
比如说一个Bitmap的构建就可以通过工厂来实现,它有一个BitmapFactory。Bitmap可以从本地图片、输入流、数组、文件等不同数据来源构建,BitmapFactory对于生产一个Bitmap是这样处理的:

public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts)
...
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts)
...
public static Bitmap decodeByteArray(byte[] data, int offset, int length)
...
 public static Bitmap decodeResource(Resources res, int id, Options opts)
...

当然,这样行不行呢?

public  Bitmap(FileDescriptor fd, Rect outPadding, Options opts)

即,通过一个构造函数,来实现从不同数据来源生产。这样做我觉得最大的缺点,就是逻辑上不清晰。逻辑上的清晰,在复杂的项目结构中,非常重要。和上面对比,所以,在Android中,根本无法通过构造函数创建一个Bitmap对象。
我自己有时候,也会这么用:

class A extends Alpha
{}
class B extends Alpha
{}
class C extends Alpha
{}
class SimpleFactory
{
    public static Alpha createProduct(String type)   
    {
        if(type.equals("a"))
           return new A();
        else if(type.equals("b"))
            return new B();
        else if(type.equals("c"))
            return new C();
        else
            retrun null;
    }
}

就这么简单?
不,有些书上,甚至不认为它是一个工厂方法。它是封装了对象没错,但是,通常所谓模式,都是一种解耦合、增强代码灵活性的方法,上面所有方法,显然并没有体现到。
所以,这里应该还有工厂方法的第二个主要作用:体现代码的解耦能力。
思路是这样的:对于某人(创建者)来说,当需要生产一种新的商品(产品)的时候,它才会去创建这个工厂,让这个工厂来实现生产该商品。
现在来修改一下上面的Bitmap的构建过程,增加一点需求,即我们需要对Bitmap做一些管理。
Now,增加一个BitmapManager,作为创建者,当它发现需要一种通过流来创建Bitmap产品的方法时,增加一条生产线(创建一个工厂)来生产它就可以了。代码上大概修改成这样:

//BitmapFactory,抽象出来创建Bitmap的方法
public interface SimpleBitmapFactory{
      Bitmap createBitmap();
}
//实际生产Bitmap的一个工厂
public class BitmapFromStreamFactory implements SimpleBitmapFactory{
      public Bitmap createBitmap(){
          ......
      }
}
//Bitmap创建者
public class BitmapManager{
  private Bitmap bitmap ;    
  public Bitmap getBitmap(SimpleBitmapFactory simplebBitmapFactory){
    Bitmap bitmap = simplebBitmapFactory.createBitmap();
    bitmap...//此处可以对bitmap做一些设置
    return bitmap ;
  }
}
//实际使用过程中
bitmapManager.getBitmap(new BitmapFromStreamFactory ());

这个过程和上面BitmapFactory相比主要的差别在哪里?
这个过程更好的体现了设计模式的开闭原则(Open Close Principle)接口隔离原则,即对于软件实体(类、模块等)关闭修改,只进行扩展。同时,各个实体的依赖关系,应该是通过接口解耦,而不是依赖具体实现。
遵循这些原则的妙用,在于当一个系统变得很复杂的时候,还能够保证代码逻辑的清晰,我们在更改需求或者功能的时候,能够减少工作量。同时,不至于发生这样的现象:我们为了需求更改了一个方法,但是该方法在另外一个隐蔽的地方也有调用,更改导致以前已经测试好的功能产生异常。
最后,我觉得有些时候,可能不会想到什么时候该使用这种工厂方法。这,大概就要看对需求的抽象能力和判断能力了。一动一静,静的地方不需要考虑太多,关键就在于这些“动”的地方。

建造者模式

建造者模式也是用来构建一个对象,但是它的侧重点在于基于蓝图,或者说知识,或者说构建流程,来创建出一个新的对象。
我们来看看OkHttp对象的构建过程,通常我们会这么使用:

okHttpClient = new OkHttpClient.Builder()
                .readTimeout(10, SECONDS)
                .writeTimeout(10, SECONDS)
                .connectTimeout(10, SECONDS)
                .cache(cache)
                .pingInterval(5, SECONDS)
                .sslSocketFactory(defaultSslSocketFactory)
                .addInterceptor(new LoggingInterceptor())
                .build();

我们build出来了一个OkHttpClient,但是构建的流程已经设置好了,如果我们需要自定义其中一部分的构建流程,在其中添加即可。这里的Builder是OkHttpClient的一个静态内部类。
build过程实际上如下:

OkHttpClient(Builder builder) {
    this.dispatcher = builder.dispatcher;
    this.proxy = builder.proxy;
    this.protocols = builder.protocols;
    this.connectionSpecs = builder.connectionSpecs;
    this.interceptors = Util.immutableList(builder.interceptors);
    this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
    this.eventListenerFactory = builder.eventListenerFactory;
    this.proxySelector = builder.proxySelector;
    this.cookieJar = builder.cookieJar;
    this.cache = builder.cache;
    this.internalCache = builder.internalCache;
    this.socketFactory = builder.socketFactory;

    boolean isTLS = false;
    for (ConnectionSpec spec : connectionSpecs) {
      isTLS = isTLS || spec.isTls();
    }

    if (builder.sslSocketFactory != null || !isTLS) {
      this.sslSocketFactory = builder.sslSocketFactory;
      this.certificateChainCleaner = builder.certificateChainCleaner;
    } else {
      X509TrustManager trustManager = systemDefaultTrustManager();
      this.sslSocketFactory = systemDefaultSslSocketFactory(trustManager);
      this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
    }

    this.hostnameVerifier = builder.hostnameVerifier;
    this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
        certificateChainCleaner);
    this.proxyAuthenticator = builder.proxyAuthenticator;
    this.authenticator = builder.authenticator;
    this.connectionPool = builder.connectionPool;
    this.dns = builder.dns;
    this.followSslRedirects = builder.followSslRedirects;
    this.followRedirects = builder.followRedirects;
    this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
    this.connectTimeout = builder.connectTimeout;
    this.readTimeout = builder.readTimeout;
    this.writeTimeout = builder.writeTimeout;
    this.pingInterval = builder.pingInterval;
  }

有时候,我会这么用:

public abstract BaseClass{
  public abstract initPageParams();
  private void initMsg(){
    ...
  }
  private void initHandler(){
    ...
  }
  public BaseClass(){
    initMsg();
    initHandler();
    initParams();
  }
}

然后让具体实现类继承BaseClass。算是一种变体吧。

总结

好的代码,在前期,越早越好,需要充分考虑好动态和静态部分,做好抽象工作。好好运用好设计原则和设计模式,会为后来的道路减少很多不必要的麻烦。
ok,就到这里。不到之处,还请指出。

相关文章

  • Builder模式

    建造者模式与工厂模式的区别 我们可以看到,建造者模式与工厂模式是极为相似的,总体上,建造者模式仅仅只比工厂模式多了...

  • 创建型模式(二):建造者,原型,单例模式

    4.建造者模式 建造者模式和抽象工厂模式很相似,如果抽象工厂模式时一个汽车配件生产厂,那么建造者模式就是一个汽车组...

  • 设计模式之builder模式

    建造者模式也叫生成器模式,和抽象工厂模式相似,也是一种构建复杂对象的模式。 建造者模式中的角色分类: 抽象建造者...

  • Retrofit

    Retrofit设计模式 动态代理,装饰模式,建造者模式,抽象工厂模式,适配器模式 建造者模式创建Retrofit...

  • 【程序员面试】+设计模式+创建型

    单例模式 抽象工厂 工厂方法 建造者模式 原型模式

  • 简单工厂模式

    创建型设计模式: 简单工厂模式、工厂方法模式、抽象工厂模式、单例模式、原型模式和建造者模式。 统共六种。 本此分享...

  • Javascript 设计模式

    创建型模式 工厂模式 建造者模式 行为模式 中介者模式 职责链模式 观察者模式 工厂模式 描述: 通过不同的typ...

  • 23种设计模式

    创建型 工厂模式 ( 工厂方法模式, 抽象工厂模式, 建造者模式 ) 单例模式 原型模式 结构型 适配器模式 装饰...

  • 工厂模式和建造者模式

    背景 关于工厂模式和建造者模式,是两个意思比较相近的概念。近期在项目中抽象逻辑层的遇到了这个问题,这里整理区分一下...

  • 设计模式汇总(ongoing)

    单例模式 工厂方法模式 抽象工厂模式 模板方法模式 建造者模式 代理模式Binder 通信retrofit 使用动...

网友评论

      本文标题:工厂模式和建造者模式

      本文链接:https://www.haomeiwen.com/subject/yjuxbxtx.html