Java设计模式之工厂模式

前言

      工厂模式在项目中被广泛的使用。使用设计模式,可以让很复杂的业务用简单的代码表达出来。

工厂模式的概述

      首先我们举个栗子来说明,在相传的神话中,最早的一批人类是通过女娲造人来产生的,女娲就是一个客户端的调用方,也是场景的执行者。黄色人种,白色人种,黑色人种就是要产生的产品。即工厂中的产品。

我们再来定义一个抽象工厂用来生成产品。示意代码如下所示:

1 public abstract class AbstractHumanFactory {
2 
3     public abstract <T extends Human> T createHuman(Class<T> c);
4 }

其中入参是人类的类型,出参是对应的人类。接下来我们来定义一下具体的人类。首先新增一个人类的抽象接口以及具体的三种肤色的人类,如下代码示意:

1 public interface Human {
2 
3     public void getColor();
4 
5     public void talk();
6 }
 1 public class BlackHuman implements Human {
 2     @Override
 3     public void getColor() {
 4 
 5         System.out.println("我是黑人");
 6 
 7     }
 8 
 9     @Override
10     public void talk() {
11         System.out.println("黑人会说话");
12     }
13 }
 1 public class WhiteHuman implements Human {
 2     @Override
 3     public void getColor() {
 4         System.out.println("我是白人");
 5 
 6     }
 7 
 8     @Override
 9     public void talk() {
10         System.out.println("白人会说话");
11 
12     }
13
public class YellowHuman implements Human {
    @Override
    public void getColor() {
        System.out.println("我是黄人");

    }

    @Override
    public void talk() {
        System.out.println("黄人会说话");

    }
}

 最后我们新增一个抽象工程的具体工厂方法。如下代码所示:

 1 public class HumanFactory extends AbstractHumanFactory {
 2     @Override
 3     public <T extends Human> T createHuman(Class<T> c) {
 4         Human human = null;
 5         try {
 6            human =  (T)Class.forName(c.getName()).newInstance();
 7         } catch (Exception e) {
 8 
 9         }
10         return (T)human;
11     }
12 }

 最后我们新增一个场景类Client:

public class Client {


    public static void main(String[] args) {

        AbstractHumanFactory humanFactory = new HumanFactory();

        BlackHuman blackHuman = humanFactory.createHuman(BlackHuman.class);
        blackHuman.getColor();
        blackHuman.talk();

        WhiteHuman whiteHuman = humanFactory.createHuman(WhiteHuman.class);
        blackHuman.getColor();
        blackHuman.talk();

        YellowHuman yellowHuman = humanFactory.createHuman(YellowHuman.class);
        yellowHuman.getColor();
        yellowHuman.talk();


    }
}

 运行结果如下所示:

我是黑人
黑人会说话
我是黑人
黑人会说话
我是黄人
黄人会说话

 工厂模式的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到子类。

 

总结一下,在工程模式中,我们拥有客户端,也就是调用方。同时拥有工厂接口和具体的工厂实现。另外还包含产品接口和具体产品。

1.采用工厂模式,只要客户端知道要产生什么产品整套链路就确认下来了,无须知晓产品产生的细节。这降低了模块之间的耦合。

2.当增加一个产品,只需要实现产品接口即可,工厂类不需要任何的变动。这符合设计原则中的开闭的原则。对修改关闭,对扩展开放。

 

 

最后我们再来总结一下工厂模式的通用实现方式:

①首先我们需要有抽象产品类,同时拥有公共的方法prepare();以及抽象的处理方法handle();

 1 package com.example.pattern.factory.summary;
 2 
 3 public abstract class AbstractProduct {
 4 
 5     public void prepare() {
 6 
 7     }
 8 
 9 
10     public abstract void handle();
11 }

②需要有具体的产品类,这些产品类继承了抽象产品类,重写的handle抽象方法。

 1 package com.example.pattern.factory.summary;
 2 
 3 public class ConcreteProductFirst extends AbstractProduct {
 4 
 5 
 6     @Override
 7     public void handle() {
 8 
 9     }
10 }

这样的产品类可以有多个,主要用来负责产品的产生,但是要保证这个产品是一个具体的产品。

③抽象工厂类

1 package com.example.pattern.factory.summary;
2 
3 public interface IFactory {
4     
5     public <T extends AbstractProduct> T createProduct(Class<T> clazz) ;
6     
7 }

抽象工厂类可以定义为接口,也可以定义为抽象类。在实际中可以采用定义一个接口,一个抽象类实现这个接口,把公共的实现方法抽取到抽象类中实现,具体的工厂类再去继承这个抽象工厂。

④具体工厂类

 1 package com.example.pattern.factory.summary;
 2 
 3 public class ConcreteFactory implements IFactory {
 4     @Override
 5     public <T extends AbstractProduct> T createProduct(Class<T> clazz) {
 6 
 7         AbstractProduct product = null;
 8 
 9         try {
10             product = (AbstractProduct)Class.forName(clazz.getName()).newInstance();
11         } catch (Exception e) {
12 
13         }
14 
15         return (T)product;
16     }
17 }

⑤业务场景类

 1 package com.example.pattern.factory.summary;
 2 
 3 public class Client {
 4 
 5     public static void main(String[] args) {
 6         IFactory factory = new ConcreteFactory();
 7 
 8         ConcreteProductFirst product = factory.createProduct(ConcreteProductFirst.class);
 9         product.handle();
10 
11     }
12 }

 

以上代码是工厂模式的通用写法,在实际应用中可以适当调整,或者和其他的设计模式混合使用。

posted @ 2018-11-19 19:55  冰糖小城  阅读(306)  评论(0编辑  收藏  举报