设计模式系列---简单工厂、工厂方法、抽象工厂

前言,最近看spring的源代码。发现之前没有完全弄懂(工厂方法、抽象工厂)的区别。

spring中代理对象的产生,是通过代理工厂(工厂模式),首先spring中的代理是使用jdk或者cglib的代理,只要看目标类是否实现接口。

public class ProxyFactory extends ProxyCreatorSupport {
   //createAopProxy()方法是通过AopProxyFactory获取AopProxy(JDK,CGLIB)
    public Object getProxy() {
        return createAopProxy().getProxy();
    }
}

  这里典型应用了工厂模式

  工厂接口:

public interface AopProxyFactory {
    AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}

  目标产品:

  AopProxy

    ----CglibAopProxy------ObjenesisCglibAopProxy

    ----JdkDynamicAopProxy

  工厂实现类:

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }
}

  (这其实是一个简单的抽象工程模式),待会再来分析。我们先进入主题

  1  简单工程模式

  产品接口(抽象产品)

public interface AOPProxy {

}

  产品实现类(具体产品)

public class JDKAOPProxy implements AOPProxy{

}
public class CGLIBAOPProxy implements AOPProxy{

}

  工厂类(简单工程)

public class AopProxyFactory {
    AOPProxy createJDKAOPProxy(){
        return new JDKAOPProxy();
    }
    AOPProxy createCGLIBAOPProxy(){
        return new CGLIBAOPProxy();
    }
}

  说明:这便是简单工厂模式了,首先,符合现实中的情况;而且客户端免除了直接创建产品对象的责任,而仅仅负责“消费”产品。下面我们从开闭原则上来分析下简单工厂模式。当未来增加了一个AopProxy的时候(MYAOPProxy),只要符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。(即创建一个新的子类(MYAOPProxy),继承抽象产品AOPProxy)那么 对于产品部分来说,它是符合开闭原则的——对扩展开放、对修改关闭;但是工厂类不太理想,因为每增加AopProxy,都要在工厂类中增加相应的商业逻辑和判 断逻辑,这显自然是违背开闭原则的。

  而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝类坏了。
正如我前面提到的简单工厂模式适用于业务简单的情况下或者具体产品很少增加的情况。而对于复杂的业务环境可能不太适应了。这就应该由工厂方法模式来出场了!!

  2  工程方法模式

  抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
  具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
  抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
  具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

  来用类图来清晰的表示下的它们之间的关系:

  抽象产品

public interface AOPProxy {

}

  具体产品

public class JDKAOPProxy implements AOPProxy{

}
public class CGLIBAOPProxy implements AOPProxy{

}

  抽象工厂接口

public interface AopProxyFactory {
    AOPProxy createAOPProxy();
}

  工厂实现

public class CGLIBAopProxyFactory implements AopProxyFactory{
    @Override
    public AOPProxy createAOPProxy() {
        return new CGLIBAOPProxy();
    }
}
public class JDKAopProxyFactory implements AopProxyFactory{
    @Override
    public AOPProxy createAOPProxy() {
        return new JDKAOPProxy();
    }
}

  说明:使用开闭原则来分析下工厂方法模式。当有新的产品(MYAOPProxy)产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。(即当有新产品时,只要创建并基础抽象产品;新建具体工厂继承抽象工厂;而不用修改任何一个类)工厂方法模式是完全符合开闭原则的!

  使用工厂方法模式足以应付我们可能遇到的大部分业务需求。但是当产品种类非常多时,就会出现大量的与之对应的工厂类,这不应该是我们所希望的。所以我建议在这种情况下使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。
  当然特殊的情况,就要特殊对待了:对于系统中存在不同的产品树,而且产品树上存在产品族(下一节将解释这个名词)。那么这种情况下就可能可以使用抽象工厂模式了。

  3  抽象工厂模式

  加入现在有一个新的产品叫做OOPProxy也有两种实现JDKOOPProxy、CGLIBOOPProxy,这样工厂方法模式实现(工厂方法模式只有单一的产品组)。

  抽象产品AOPProxy

public interface AOPProxy {
}

  抽象产品AOPProxy实现

public class JDKAOPProxy implements AOPProxy{
}
public class CGLIBAOPProxy implements AOPProxy{
}

  抽象产品OOPProxy

public interface OOPProxy {
}

  抽象产品OOPProxy实现

public class JDKOOPProxy implements OOPProxy{
}
public class CGLIBOOPProxy implements OOPProxy{
}

  抽象工厂ProxyFacoty

public interface ProxyFactory {
    AOPProxy createAOPProxy();
    OOPProxy createOOPProxy();
}

  抽象工厂实现JDKProxyFactory

public class JDKProxyFactory implements ProxyFactory{
    @Override
    public AOPProxy createAOPProxy() {
        return new JDKAOPProxy();
    }

    @Override
    public OOPProxy createOOPProxy() {
        return new JDKOOPProxy();
    }
}

  抽象工厂实现OOPAOPFacoty

public class CGLIBProxyFactory implements ProxyFactory{
    @Override
    public AOPProxy createAOPProxy() {
        return new CGLIBAOPProxy();
    }

    @Override
    public OOPProxy createOOPProxy() {
        return new CGLIBOOPProxy();
    }
}

  

  其中:JDKAOPProxy和CGLIBAOPProxy属于产品树、同理JDKOOPProxy和CGLIBOOPProxy。而JDKAOPProxy和JDKOOPProxy属于产品族。

  所以抽象工厂模式一般用于具有产品树和产品族的场景下。

  抽象工厂模式的缺点:如果需要增加新的产品树,那么就要新增三个产品类,比如TOPProxy,JDKTOPProxy, CGLIBTOPProxy,修改三个工厂类。这样大批量的改动是很丑陋的做法。

时间: 2024-10-11 00:29:35

设计模式系列---简单工厂、工厂方法、抽象工厂的相关文章

详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)

园子里关于23种设计模式的博文已经可以说是成千上万.车载斗量.屯街塞巷.不计其数.数不胜数.摩肩接踵.汗牛充栋.车水马龙.门庭若市.琳琅满目直至让人眼花缭乱了.在这样的大环境下之所以来写设计模式类的博文,并不是像一些"非主流"的爱情观那样"宁缺毋滥". 只是其一呢,因为相当于给自己做一个总结,加深一下自己这方面的认识,因为掌握了和把它写出来我感觉后者还可以对技能有一个提升,其二呢是因为最近公司有一个内部的training需要讲设计模式. v写在前面 在这里呢,需要向

创建和使用解耦——工厂模式详解(工厂方法+抽象工厂)

1.前言 直接new一个对象是最简单的创建对象的方式,但大量出现在业务代码中会带来至少两个问题.1:创建对象的细节直接暴露在业务代码中,修改实现细节必须修改相关的大量客户端代码.2:直接面向具体类型编程,违反了面向接口编程的原则,系统进行扩展时也不得不进行大量修改.要使得系统具有的良好的可扩展性以及后期易于维护,必须实现对产品的获取和对产品的使用解耦.要做到这两点,首先要对客户端代码屏蔽掉创建产品的细节,其次,客户端必须面向产品的抽象编程,利用java的多态特性在运行时才确定具体的产品.而这,正

设计模式学习笔记(十一:抽象工厂模式)

1.1概述 提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类.这就是抽象工厂模式的定义. 设计某些系统时可能需要为用户提供一系列相关的对象,但系统不希望用户直接使用new运算符实例化这些对象,而是应当由系统来控制这些对象的创建,否则用户不仅要清楚地知道使用哪些类来创建这些对象,而且还必须要清楚对象之间是如何关联的,使得用户的代码和这些类形成紧耦合.缺乏弹性.不利于维护. 例如,军队要为士兵(用户)提供机关枪.手枪以及相应的子弹,但军队系统不希望由士兵提供来生产机关枪.手枪以及子弹,

2 简单工厂模式、工厂模式、抽象工厂模式

简单工厂模式: -----------------------------------Pizza.java-------------------- package com; public abstract class Pizza { public abstract void prepare(); public abstract void bake(); public abstract void cut(); } -----------------------------------APizza.

《大话设计模式》学习笔记11:抽象工厂模式

切换数据库类型示例: 1.User类: public class User { public int Id { get; set; } public string Name { get; set; } } 2.AbstractProduct(以User为例): public interface IUser { void Insert(User user); User GetUser(int id); } 3.Product(以User.SQL Server为例): public class Sq

Delphi 设计模式:《HeadFirst设计模式》Delphi代码---工厂模式之抽象工厂[转]

 1 2 {<HeadFirst设计模式>工厂模式之抽象工厂 } 3 { 抽象工厂的产品                       } 4 { 编译工具:Delphi7.0                  } 5 { E-Mail :[email protected]          } 6 7unit uPizzaIngredient; 8 9interface1011type12  TDough = class(TObject)13  end;1415  TThinCrustDoug

工厂模式之抽象工厂模式

图显示有问题.可直接看: 点击打开链接 场景问题 举个生活中常见的样例--组装电脑,我们在组装电脑的时候.通常须要选择一系列的配件,比方CPU.硬盘.内存.主板.电源.机箱等. 为讨论使用简单点,仅仅考虑选择CPU和主板的问题. 其实.在选择CPU的时候.面临一系列的问题,比方品牌.型号.针脚数目.主频等问题.仅仅有把这些问题都确定下来,才干确定详细的CPU. 相同,在选择主板的时候.也有一系列问题.比方品牌.芯片组.集成芯片.总线频率等问题,也仅仅有这些都确定了,才干确定详细的主板. 选择不同

工厂模式[3] 抽象工厂 Abstract Factory

简介 1.简单工厂,或静态工厂,产品接口 定义:专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类或实现同一接口 优点:客户端可以直接消费产品,而不必关心具体产品的实现(不关心对象的构造方法是怎么new的),消除了客户端直接创建产品对象的责任,实现了对责任的分割. 缺点:工厂类记录了所有产品的创建逻辑,一旦不能正常工作,整个系统都会受到影响:而且当产品种类多.结构复杂的时候,把所有创建工作放进一个工厂中来,会使后期程序的扩展较为困难. 2.工厂方法,工厂接口+产品接口 定义:在

6创建型模式之工厂模式与抽象工厂模式

工厂模式 概念 工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 . 工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品. 类图角色和职责 抽象工厂(Creator)角色 工厂方法模式的核心,任何工厂类都必须实现这个接口. 具体工厂( Concrete  Creator)角

工厂模式和抽象工厂模式

工厂模式: 定义一个用于创建对象的接口,让他的子类决定实例化哪个类.使类的实例化延迟到子类. 1.普通的工厂模式: public class GoodProduct implements Product { private String prodInfo = "Iam the good prod"; public String getProductInfo() { // TODO Auto-generated method stub return this.prodInfo; } pu