1.定义

定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。

2.类图

设计模式学习-工厂模式

 

3.代码示例

 1 package com.zhaoyangwoo.factorymethod;
 2 
 3 /**
 4  * Created by john on 16/5/1.
 5  * @author wuzhaoyango
 6  * <p>
 7  *     This is a demo for factoryMethod
 8  * </p>
 9  * <p>
10  *     工厂方法:一抽象产品类派生出多个具体产品类;一抽象工厂类派生出多个具体工厂类;每个具体工厂类只能创建一个具体产品类的实例。
11  *     即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)。“一对一”的关系。
12  * </p>
13  */
14 public class FactoryMethod {
15 
16     private static Factory factoryA,factoryB;
17     private static Product productA,productB;
18     public static void main(String[] args) {
19         factoryA = new FactoryA();
20         factoryB = new FactoryB();
21         productA = factoryA.create();
22         productB = factoryB.create();
23         productA.getName();
24         productB.getName();
25     }
26 }
27 
28 
29 interface Product{
30     void getName();
31 }
32 
33 interface Factory{
34     Product create();
35 }
36 
37 class ProductA implements Product{
38 
39     @Override
40     public void getName() {
41         System.out.println("I'm productA");
42     }
43 }
44 
45 class ProductB implements Product{
46 
47     @Override
48     public void getName() {
49         System.out.println("I'm productB");
50     }
51 }
52 
53 class FactoryA implements Factory {
54 
55     @Override
56     public Product create() {
57         return new ProductA();
58     }
59 }
60 
61 class FactoryB implements Factory {
62 
63     @Override
64     public Product create() {
65         return new ProductB();
66     }
67 }

 

 

4.扩展:简单工厂模式

  4.1 类图

  设计模式学习-工厂模式

  4.2 代码示例

  

 1 package com.zhaoyangwoo.simplefactory;
 2 
 3 /**
 4  * Created by john on 16/5/1.
 5  * 简单工厂实现类,ConcreteFactory是"上帝类",这个设计模式是工厂方法的一种扩展,实际使用也比较多,但是
 6  * 它并不满足开闭原则,如果拓展类一种新的产品,例如ProductC,那么必须修改create方法的判断条件,别无他法.
 7  * 这并无影响它的广泛使用,所以原则是死的,编码是活的. 
 8  */
 9 public class SimpleFactory {
10     public static void main(String[] args){
11         Product product = ConcreteFactory.create(ProductA.class);
12         product.getName();
13     }
14 }
15 
16 class ConcreteFactory {
17     public static Product create(Class t) {
18         if(t.equals(ProductA.class)){
19             return new ProductA();
20         }else if(t.equals(ProductB.class)){
21             return new ProductB();
22         }else {
23             throw new IllegalArgumentException("参数错误");
24         }
25     }
26 }
27 interface Product{
28     void getName();
29 }
30 
31 class ProductA implements Product {
32 
33     @Override
34     public void getName() {
35         System.out.println("I'm productA");
36     }
37 }
38 
39 class ProductB implements Product {
40 
41     @Override
42     public void getName() {
43         System.out.println("I'm productB");
44     }
45 }

 

5.应用场景举例

  • 创建复杂对象,隔离对象创建的具体过程
  • 一个类不知道它所需要的对象的类:客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。 

6.JDK源码中的模式实现

还记得我们在单例模式中提到的Calendar.getInstance() 吗?它实际上就是工厂方法的一个典型实现。我们再来看看源码

 1  public static Calendar getInstance(TimeZone zone,
 2                                        Locale aLocale)
 3     {
 4         return createCalendar(zone, aLocale);
 5     }
 6 
 7     private static Calendar createCalendar(TimeZone zone,
 8                                            Locale aLocale)
 9     {
10         CalendarProvider provider =
11                 LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
12                         .getCalendarProvider();
13         if (provider != null) {
14             try {
15                 return provider.getInstance(zone, aLocale);
16             } catch (IllegalArgumentException iae) {
17                 // fall back to the default instantiation
18             }
19         }
20 
21         Calendar cal = null;
22 
23         //通过判断条件来决定用怎样的子类来实例化父类
24         if (aLocale.hasExtensions()) {
25             String caltype = aLocale.getUnicodeLocaleType("ca");
26             if (caltype != null) {
27                 switch (caltype) {
28                     case "buddhist":
29                         cal = new BuddhistCalendar(zone, aLocale);
30                         break;
31                     case "japanese":
32                         cal = new JapaneseImperialCalendar(zone, aLocale);
33                         break;
34                     case "gregory":
35                         cal = new GregorianCalendar(zone, aLocale);
36                         break;
37                 }
38             }
39         }
40 
41         //通过判断条件来决定用怎样的子类来实例化父类
42         if (cal == null) {
43             if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
44                 cal = new BuddhistCalendar(zone, aLocale);
45             } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
46                     && aLocale.getCountry() == "JP") {
47                 cal = new JapaneseImperialCalendar(zone, aLocale);
48             } else {
49                 cal = new GregorianCalendar(zone, aLocale);
50             }
51         }
52         return cal;
53     }
View Code

相关文章:

  • 2021-07-10
  • 2021-08-27
  • 2021-10-02
  • 2021-11-04
  • 2021-04-07
  • 2021-10-25
  • 2021-05-24
  • 2021-08-14
猜你喜欢
  • 2021-06-04
  • 2021-05-15
  • 2022-12-23
  • 2021-08-20
  • 2021-11-13
  • 2022-12-23
  • 2022-03-06
相关资源
相似解决方案