Java 之工厂方法和抽象工厂模式(转)

1. 概念

    工厂方法:一抽象产品类派生出多个具体产品类;一抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。

    即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)。“一对一”的关系。

    抽象工厂:多个抽象产品类,派生出多个具体产品类;一个抽象工厂类,派生出多个具体工厂类;每个具体工厂类可创建多个具体产品类的实例。

    即提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体的类。“一对多”的关系。

2. UML

 工厂方法:

抽象工厂:

3. 代码

工厂方法:

 1 public interface Product
 2 {       
 3 }
 4 
 5 public interface Creator
 6 {
 7        public Product factory();
 8 }
 9 
10 public class ConcreteProduct1 implements Product
11 {
12        public ConcreteProduct1()
13        {
14               System.out.println("ConcreteProduct1被创建");
15        }
16 }
17 
18 public class ConcreteProduct2 implements Product
19 {
20        public ConcreteProduct2()
21        {
22               System.out.println("ConcreteProduct2被创建");
23        }
24  
25 }
26 
27 public class ConcreteCreator1 implements Creator
28 {
29        public Product factory()
30        {
31               return new ConcreteProduct1();
32        }
33 }
34 
35 public class ConcreteCreator2 implements Creator
36 {
37        public Product factory()
38        {
39               return new ConcreteProduct2();
40        }
41 }
42  
43 public class Client
44 {
45        private static Creator creator1, creator2;
46        private static Product prod1, prod2;
47 
48        public static void main(String[] args)
49        {
50               creator1 = new ConcreteCreator1();
51               prod1 = creator1.factory();
52               System.out.println("----------------------------");
53               creator2 = new ConcreteCreator2();
54               prod2 = creator2.factory();
55        }
56 }

抽象工厂:

 1 //定义不同的产品之间的一定具备的标准,用interface实现 
 2 //其中的method()方法可看作提取出不同产品的共性,如手机都有类似的功能 
 3 interface IProductA{ 
 4   public void method(); 
 5 } 
 6 
 7 interface IProductB{ 
 8   public void method(); 
 9 } 
10 
11 //实现了产品标准实现的一系列具体产品 
12 //由于已经设计好A1由厂商1生产,故以下输出代码有“厂商x” 
13 class ProductA1 implements IProductA{ 
14   public void method() { 
15     System.out.println("厂商1    生产ProductA1 ..."); 
16   } 
17 } 
18 
19 class ProductA2 implements IProductA{ 
20   public void method() { 
21     System.out.println("厂商2    生产ProductA2 ..."); 
22   } 
23 } 
24 
25 class ProductB1 implements IProductB{ 
26   public void method() { 
27     System.out.println("厂商1    生产ProductB1 ..."); 
28   } 
29 } 
30 
31 class ProductB2 implements IProductB{ 
32   public void method() { 
33     System.out.println("厂商2    生产ProductB2 ..."); 
34   } 
35 } 
36 
37 //每一种牌子的产品生产工厂,即不同的厂商负责自己牌子产品的生产 
38 abstract class Factory1{ 
39   abstract IProductA getProductA1(); 
40   abstract IProductB getProductB1(); 
41 } 
42 
43 abstract class Factory2{ 
44   abstract IProductA getProductA2(); 
45   abstract IProductB getProductB2(); 
46 } 
47 
48 //具体的工厂用来生产相关的产品 
49 class ConcreteFactory1 extends Factory1{ 
50   public IProductA getProductA1() { 
51     return new ProductA1(); 
52   } 
53   public IProductB getProductB1() { 
54     return new ProductB1(); 
55   } 
56 } 
57 
58 class ConcreteFactoryB extends Factory2{ 
59   public IProductA getProductA2() { 
60     return new ProductA2(); 
61   } 
62   public IProductB getProductB2() { 
63     return new ProductB2(); 
64   } 
65 } 
66 
67 //测试类 
68 public class Client { 
69   public static void main(String[] args) { 
70     //厂商1负责生产产品A1、B1 
71     Factory1 factory1 = new ConcreteFactory1(); 
72     IProductA productA1 = factory1.getProductA1(); 
73     IProductB productB1 = factory1.getProductB1(); 
74      
75     productA1.method(); 
76     productB1.method(); 
77      
78     //厂商2负责生产产品A2、B2 
79     Factory2 factory2 = new ConcreteFactoryB(); 
80     IProductA productA2 = factory2.getProductA2(); 
81     IProductB productB2 = factory2.getProductB2(); 
82      
83     productA2.method(); 
84     productB2.method(); 
85   } 
86 }

4. 应用场景

工厂方法:

在以下情况下,适用于工厂方法模式:

(1) 当一个类不知道它所必须创建的对象的类的时候。

(2) 当一个类希望由它的子类来指定它所创建的对象的时候。

(3) 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

抽象工厂:

(1) 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

(2) 这个系统有多于一个的产品族,而系统只消费其中某一产品族。

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

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

(转自:http://www.cnblogs.com/devinzhang/archive/2011/12/19/2293160.html)

原文地址:https://www.cnblogs.com/WayneZeng/p/2964526.html