工厂模式(创建型)

Posted 无名小厨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工厂模式(创建型)相关的知识,希望对你有一定的参考价值。

工厂模式是用工厂方法代替new操作的一种模式。工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量(降低耦合)。
一、简单工厂模式
简单工厂模式包含如下三种角色:
抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
具体产品:实现或者继承抽象产品的子类。
具体工厂:提供了创建产品的方法,使用者通过该方法来获取产品。
实例
//抽象产品角色

public interface Produce 
    void doProduce();

//产品实例 1

public class SpicyChickenHamburg implements Produce
    @Override
    public void doProduce() 
        System.out.println("offer SpicyChickenHamburg ");
    

//产品实例 2 鸡腿堡

public class ChickenDrumsticksHamburg implements  Produce
    public void doProduce() 
        System.out.println("do ChickenDrumsticksHamburg ");
    

//工厂

public class MacDonaldHamburgFactory 
    public Produce getProduct(String productName) 
        if ("SpicyChickenHamburg".equals(productName)) 
            return new SpicyChickenHamburg();
         else if ("ChickenDrumsticksHamburg".equals(productName)) 
            return new ChickenDrumsticksHamburg();
         else 
            return null;
        
    

优点:客户端免除了直接创建产品对象的责任,而仅仅负责“消费”产品
缺点:每增加一样商品,简单工厂就需要修改相应的商业逻辑和判断逻辑,这显自然是违背开闭原则的。
在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以对于复杂的业务环境可能不太适应。
由此引出工厂方法模式。
二.工厂方法模式(扩展不属于23种设计模式)
角色分析
抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。

抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
实例如下:
//抽象产品角色

public interface Produce

void doProduce();


//产品实例 1-1 麦辣鸡翅汉堡

public class SpicyChickenHamburg implements Produce

	public void doProduce() 
	
	System.out.println(“offer SpicyChickenHamburg);

	

//产品实例 1-2 鸡腿堡

public class ChickenDrumsticksHamburg  implements Produce
    @Override
    public void doProduce() 
            System.out.println("do ChickenDrumsticksHamburg ");
    

//产品实例 2-1 小杯可乐

public class SmallCola implements Produce
	public void doProduce() 
	System.out.println(do SmallCola);
	

//产品实例 2-2 大杯可乐

public class BigCola implements Produce
	public void doProduce() 
	System.out.println(do BigCola);
	

//抽象工厂角色

public interface MacDonaldFactory
  Produce getProduct(String productName);

//汉堡包工厂

public class HamburgFactory implements MacDonaldFactory
    @Override
    public Produce getProduct(String productName) 
        if ("SpicyChickenHamburg".equals(productName)) 
            return new SpicyChickenHamburg();
         else if ("ChickenDrumsticksHamburg".equals(productName)) 
            return new ChickenDrumsticksHamburg();
         else 
            return null;
        
    

//可乐工厂

public class ColaFactory implements MacDonaldFactory
    @Override
    public Produce getProduct(String productName) 
       if("SmallCola".equals(productName))
           return new SmallCola();
       else if("BigCola".equals(productName))
           return new BigCola();
       else
           return null;
       
    

缺点:每一个产品应一个工厂子类,在创建具体产品对象时,实例化不同的工厂子类。但是,如果业务涉及的子类越来越多,难道每一个子类都要对应一个工厂类吗?这样会使得系统中类的个数成倍增加,增加了代码的复杂度。
为了缩减工厂实现子类的数量,不必给每一个产品分配一个工厂类,可以将产品进行分组,每组中的不同产品由同一个工厂类的不同方法来创建。于是引入了抽象工厂模式

三. 抽象工厂模式

//抽象产品Cola

public interface Cola 
    void doProduce();

//具体产品SmallCola

public class SmallCola implements Cola
    @Override
    public void doProduce() 
        System.out.println("do SmallCola ");
    

//具体产品BigCola

public class BigCola implements Cola
    @Override
    public void doProduce() 
        System.out.println("do BigCola ");
    

//抽象产品Hamburg

public interface Hamburg 
    void doProduce();

//具体产品ChickenDrumsticksHamburg

public class ChickenDrumsticksHamburg implements Hamburg
    @Override
    public void doProduce() 
        System.out.println("do ChickenDrumsticksHamburg ");
    

//具体产品SpicyChickenHamburg

public class SpicyChickenHamburg implements Hamburg
    @Override
    public void doProduce() 
        System.out.println("offer SpicyChickenHamburg ");
    

//抽象工厂AbtractFactory

public interface AbtractFactory 
    Cola doCola();
    Hamburg doHamburg();

//大汉堡工厂BigColaHamburgFactory

public class BigColaHamburgFactory implements AbtractFactory
    @Override
    public Cola doCola() 
        return new BigCola();
    

    @Override
    public Hamburg doHamburg() 
        return new SpicyChickenHamburg();
    

//小汉堡工厂SmallColaHamburgFactory

public class SmallColaHamburgFactory implements AbtractFactory
    @Override
    public Cola doCola() 
        return new SmallCola();
    

    @Override
    public Hamburg doHamburg() 
        return new ChickenDrumsticksHamburg();
    


测试

public class Test 
    public static void main(String[] args) 
        AbtractFactory abtractFactory=new BigColaHamburgFactory();
        abtractFactory.doCola().doProduce();
        abtractFactory.doHamburg().doProduce();
        AbtractFactory abtractFactory1=new SmallColaHamburgFactory();
        abtractFactory1.doCola().doProduce();
        abtractFactory1.doHamburg().doProduce();
    

创建型模式之工厂模式

GitHub地址:https://github.com/zhangboqing/design-mode/tree/master/src/main/java/com/zbq

一、工厂模式分类

1)简单工厂

2)工厂方法

3)抽象工厂

 

二、简单工厂

1.定义

  简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

2.代码实示例

技术分享图片
 1 /**
 2  * @author zhangboqing
 3  * @date 2017/12/12
 4  * 简单工厂
 5  */
 6 public class SimpleFactory {
 7 
 8     /**
 9      * 第一种形式
10      * 调用指定方法,直接返回对象
11      * @return
12      */
13     public static Object createObject() {
14 
15         return new Object();
16     }
17 
18     /**
19      * 第二种形式
20      * 根据指定的type,获取对应的对象
21      * @param type
22      * @return
23      */
24     public static Object createObject(Integer type) {
25 
26         if (type.equals(1)) {
27             return new Object1();
28         } else if (type.equals(2)) {
29             return new Object2();
30         } else if (type.equals(3)) {
31             return new Object3();
32         }
33         return null;
34     }
35 
36 
37     /** 方便阅读,具体产品,放入同一个类 */
38     public static class Object1 {
39 
40         private static String name = "对象1";
41     }
42 
43     public static class Object2 {
44         private static String name = "对象2";
45     }
46 
47     public static class Object3 {
48         private static String name = "对象3";
49 
50     }
51 
52 }
View Code

 

3.优点和缺点分析

优点:

>工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任

>客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量

>通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性

缺点:

>系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护

>简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构

 

4.应用场景

在以下情况下可以使用简单工厂模式:

>工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。

>客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。

 

三、工厂方法

1.定义

  工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

 

2.代码实示例

技术分享图片
 1 /**
 2  * @author zhangboqing
 3  * @date 2017/12/12
 4  * 工厂方法
 5  */
 6 public abstract class FactoryMethod {
 7 
 8     //TODO:该方法就是工厂方法
 9     public abstract Object createObject(String type);
10 
11 
12     /** 方便阅读,具体工厂实现类,放入同一个类 */
13     public class FactoryMethod1 extends FactoryMethod {
14 
15         //子类必须实现抽象工厂方法,决定到底生产哪个对象
16         @Override
17         public Object createObject(String type) {
18             //生成
19             return new Object1();
20         }
21     }
22 
23     public class FactoryMethod2 extends FactoryMethod {
24 
25         //子类必须实现抽象工厂方法,决定到底生产哪个对象
26         @Override
27         public Object createObject(String type) {
28             //生成
29             return new Object2();
30         }
31     }
32 
33     public class FactoryMethod3 extends FactoryMethod {
34 
35         //子类必须实现抽象工厂方法,决定到底生产哪个对象
36         @Override
37         public Object createObject(String type) {
38             //生成
39             return new Object3();
40         }
41     }
42 
43 
44     /** 方便阅读,具体产品,放入同一个类 */
45     public static class Object1 {
46 
47         private static String name = "对象1";
48     }
49 
50     public static class Object2 {
51         private static String name = "对象2";
52     }
53 
54     public static class Object3 {
55         private static String name = "对象3";
56 
57     }
58 }
View Code

 

3.优点和缺点分析

优点:

>基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。

>使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。



缺点:

>在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。

 

 

4.应用场景

在以下情况下可以使用工厂方法模式:

>一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。

>一个类不知道它所需要的对象的类,将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。

 

三、抽象工厂

1.定义

  抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

 

2.代码实示例

技术分享图片
 1 /**
 2  * @author zhangboqing
 3  * @date 2017/12/12
 4  * <p>
 5  * 抽象工厂
 6  */
 7 public interface AbstractFactory {
 8 
 9     //TODO:抽象工厂,由多个工厂方法组成
10 
11     public Object createObject1();
12 
13     public Object createObject2();
14 
15     public Object createObject3();
16 
17 
18     /**
19      * 方便阅读,具体工厂实现类,放入同一个类
20      */
21     public class AbstractFactory1 implements AbstractFactory {
22 
23         @Override
24         public Object createObject1() {
25             return new Object1();
26         }
27 
28         @Override
29         public Object createObject2() {
30             return new Object2();
31         }
32 
33         @Override
34         public Object createObject3() {
35             return new Object3();
36         }
37     }
38 
39     /**
40      * 方便阅读,具体产品,放入同一个类
41      */
42     public static class Object1 {
43 
44         private static String name = "对象1";
45     }
46 
47     public static class Object2 {
48         private static String name = "对象2";
49     }
50 
51     public static class Object3 {
52         private static String name = "对象3";
53 
54     }
55 }
View Code

 

 

3.优点和缺点分析

优点:

>当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。

>增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。



缺点:

>在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。

 

 

4.应用场景

在以下情况下可以使用抽象工厂模式:

>系统中有多于一个的产品族,而每次只使用其中某一产品族。

>属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。

>系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

 









以上是关于工厂模式(创建型)的主要内容,如果未能解决你的问题,请参考以下文章

设计模式才是Java灵魂,Java创建型模式的抽象工厂模式

java设计模式--创建型模式

Java设计模式(创建型:工厂方法模式)

JAVA设计模式(01):创建型-工厂模式工厂方法模式(Factory Method)

Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)

JAVA设计模式 3创建型理解工厂模式与抽象工厂模式