工厂模式(Factory Pattern)

一、工厂模式(Factory Pattern)的介绍

  工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。使用工厂模式可能会多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

二、工厂模式的分类

  1.简单工厂模式

  2.工厂方法模式

  3.抽象工厂模式

三、简单工厂模式

  1.父类产品

 1 /**
 2  * 父类产品
 3  */
 4 public class Product {
 5     public Product(){
 6         System.out.println("------product------");
 7     }
 8     public void change(){
 9         System.out.println("-----父类方法------");
10     }
11 }

·  2. A B C 三种子类产品

 1 //子类产品A
 2 public class ProductA extends Product {
 3     public ProductA() {
 4         System.out.println("------产品A------");
 5     }
 6     @Override
 7     public void change() {
 8         System.out.println("------方法A------");
 9     }
10 }
 1 //子类产品B
 2 public class ProductB extends Product {
 3     public ProductB() {
 4         System.out.println("------产品B------");
 5     }
 6 
 7     @Override
 8     public void change() {
 9         System.out.println("------方法B------");
10     }
11 }
 1 //子类产品C
 2 public class ProductC extends Product {
 3     public ProductC() {
 4         System.out.println("------产品C------");
 5     }
 6 
 7     @Override
 8     public void change() {
 9         System.out.println("------方法C------");
10     }
11 }

  3、创建产品的工厂类

  工厂类是整个模式的关键,包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象。

 1 /**
 2  * 创建产品的工厂
 3  */
 4 public class Factory {
 5 
 6     /**
 7      * 静态方法,直接调用
 8      * 自动向上转型,转为product
 9      */
10     public static Product createProduct(String param){
11         if (param.equals("A")){
12             Product productA = new ProductA();
13             return productA;
14         }else if (param.equals("B")){
15             Product productB = new ProductB();
16             return productB;
17         }else if (param.equals("C")){
18             ProductC productC = new ProductC();
19             return productC;
20         }
21         return new Product();
22     }
23 
24     public static void change(Product product){
25         product.change();
26     }
27 }

  4、比较普通创建对象的方法和测试简单工厂方法

 1 public class TestProduct {
 2     @Test
 3     public void test1(){
 4         /**
 5          * 没有工厂模式
 6          * 每个产品都需要创建
 7          */
 8         ProductA productA = new ProductA();
 9         ProductB productB = new ProductB();
10         ProductC productC = new ProductC();
11         System.out.println("------productA------" + productA);
12         System.out.println("------productB------" + productB);
13         System.out.println("------productC------" + productC);
14     }
15 
16     @Test
17     public void test2(){
18         /**
19          * 工厂设计
20          * 参数不同,返回产品不同
21          * 向下转型,和本身的类型相关
22          */
23         ProductA productA = (ProductA) Factory.createProduct("A");
24         ProductB productB = (ProductB) Factory.createProduct("B");
25         ProductC productC = (ProductC) Factory.createProduct("C");
26         System.out.println("------productA------" + productA);
27         System.out.println("------productB------" + productB);
28         System.out.println("------productC------" + productC);
29         // 多态测试
30         Factory.change(productA);
31         Factory.change(productB);
32         Factory.change(productC);
33     }
34 }

  5.小结简单工厂

  简单工厂的所有产品都是在一个工厂生产的,通过在构造时判断传入的参数不同来生产不同的产品,这种模式会随着产品的增加而越来越庞大,每次新增产品都要添加修改判断条件,即修改工厂类,给维护和扩展带来不便。并且一但工厂类中出错,所有产品都无法创建了。

四、工厂方法模式

  1.抽象产品工厂类

  工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

1 /**
2  * 抽象产品工厂类
3  * Product为抽象产品
4  */
5 public abstract class Factory {
6     abstract Product create();
7 }

  2.具体的A、B工厂类

  2个工厂都继承抽象工厂类,它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。

 1 /**
 2  * A工厂生产A产品
 3  */
 4 public class AFactory extends Factory {
 5     @Override
 6     public Product create() {
 7         return new ProductA();
 8     }
 9 }
10 
11 
12 /**
13  * B工厂生产B产品
14  */
15 public class BFactory extends Factory {
16     @Override
17     Product create() {
18         return new ProductB();
19     }
20 }

  3.抽象产品接口

  它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

1 /**
2  * 抽象产品接口
3  */
4 public interface Product {
5     void method();
6 }

  4.具体产品类

  A、B 产品都实现抽象产品接口

 1 /**
 2  * 具体产品A
 3  */
 4 public class ProductA implements Product{
 5     @Override
 6     public void method() {
 7         System.out.println("------ProductA------");
 8     }
 9 }
10 
11 
12 /**
13  * 具体产品B
14  */
15 public class ProductB implements Product {
16     @Override
17     public void method() {
18         System.out.println("------ProductB------");
19     }
20 }

  5.测试工厂方法

 1 public class TestFactoryMethod {
 2     /**
 3      * 创建不同的工厂,生产不同的产品
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         AFactory aFactory = new AFactory();
 8         Product product = aFactory.create();
 9         product.method();
10 
11         BFactory bFactory = new BFactory();
12         Product product1 = bFactory.create();
13         product1.method();
14         /* 输出为:
15         ------ProductA------
16         ------ProductB------*/
17     }
18 }

  6.小结工厂方法

  工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。工厂方法模式实现了不同产品在不同工厂生产,维护和扩展比简单工厂模式好,即使一个产品出现问题,其他产品也可以正常生产。

五、抽象工厂模式

  1.抽象工厂类

 1 /**
 2  * 抽象工厂类
 3  * 可以创建分别生产A、B产品
 4  */
 5 public interface AbstractFactory {
 6 
 7     ProductA factoryA();
 8 
 9     ProductB factoryB();
10 }

  2.具体工厂

  A1和B1是一个产品族,由具体工厂1生产;A2和B2是一个产品族,由具体工厂2生产

 1 /**
 2  * 具体工厂1
 3  * 生产产品A1和B1
 4  */
 5 public class Factory1 implements AbstractFactory {
 6     @Override
 7     public ProductA factoryA() {
 8         return new ProductA1();
 9     }
10 
11     @Override
12     public ProductB factoryB() {
13         return new ProductB1();
14     }
15 }
 1 /**
 2  * 具体工厂2
 3  * 生产产品A2和B2
 4  */
 5 public class Factory2 implements AbstractFactory {
 6     @Override
 7     public ProductA factoryA() {
 8         return new ProductA2();
 9     }
10 
11     @Override
12     public ProductB factoryB() {
13         return new ProductB2();
14     }
15 }

  3.抽象产品接口

  抽象产品A接口

1 /**
2  * 抽象产品A接口
3  */
4 public interface ProductA {
5 }

  抽象产品B接口

1 /**
2  * 抽象产品B接口
3  */
4 public interface ProductB {
5 }

  4.具体产品

  具体产品A1,实现抽象产品A接口

1 /**
2  * 具体产品A1
3  */
4 public class ProductA1 implements ProductA {
5     public ProductA1(){
6         System.out.println("------ProductA1------");
7     }
8 }

  具体产品A2,实现抽象产品A接口

1 /**
2  * 具体产品A2
3  */
4 public class ProductA2 implements ProductA {
5     public ProductA2() {
6         System.out.println("------ProductA2------");
7     }
8 }

  具体产品B1,实现抽象产品B接口

1 /**
2  * 具体产品B1
3  */
4 public class ProductB1 implements ProductB {
5     public ProductB1() {
6         System.out.println("------ProductB1------");
7     }
8 }

  具体产品B2,实现抽象产品B接口

1 /**
2  * 具体产品B2
3  */
4 public class ProductB2 implements ProductB {
5     public ProductB2() {
6         System.out.println("------ProductB2------");
7     }
8 }

  5.测试抽象工厂

 1 /**
 2  * 测试抽象功能工厂
 3  */
 4 public class TestAbstractFactory {
 5     public static void main(String[] args) {
 6         Factory1 factory1 = new Factory1();
 7         factory1.factoryA();
 8         factory1.factoryB();
 9 
10         Factory2 factory2 = new Factory2();
11         factory2.factoryA();
12         factory2.factoryB();
13         /* 输出
14         ------ProductA1------
15         ------ProductB1------
16         ------ProductA2------
17         ------ProductB2------*/
18     }
19 }

  6.小结

  抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

六、总结

简单工厂 : 用来生产同一等级结构中的任意产品,即所有产品由一个工厂生产,当需要添加新产品时,需要修改工厂类,不易扩展。

工厂方法 :用来生产同一等级结构中的固定产品,即不同的产品由不同的工厂生产,添加新产品只需要添加新工厂,更容易扩展,不过如果同一级产品有多个,会产生很多平行的工厂。

抽象工厂 :用来生产不同产品族的全部产品,即一个工厂生产一个产品族,每个产品族都是多个产品的同一级结构。

以上三种工厂方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。

原文地址:https://www.cnblogs.com/zt19994/p/8319111.html