Java设计模式圣经连载(02)-工厂方法(Factory Method)模式

简介:
1.2 工厂方法(Factory Method)模式
 
    工厂方法模式是类的创建模式,又叫虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。
    工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际工作推迟到子类中。
 
1.2.1 工厂方法模式的引进
    
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。下面是工厂方法模式的缩略类图:
点击在新窗口查看全图

 
  
  在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做。这个核心工厂则变为抽象工厂角色,仅负责给出具工厂子类必须实现的接口,而不接触哪一产品创建的细节。
    这种抽象的结果,使这种工厂方法模式可以用来允许系统不修改具体工厂角色的情况下引进新产品,这一特点无疑使得工厂模式具有超过简单工厂模式的优越性。
 
1.2.2 工厂方法模式的结构
    
在工厂方法模式中,一般都有一个平行的等级结构,也就是说工厂和产品是对应的的。抽象工厂对应抽象产品,具体工厂对应具体产品。简单的示意图如下:
点击在新窗口查看全图
 
    
从上图可以看出,工厂方法模式的系统涉及到了以下角色:
    抽象工厂角色:与应用程序无关,任何在模式中创建对象的工厂必须实现这个接口。
    具体工厂角色:实现了抽象工厂接口的具体Java类,含有与引用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。
    抽象产品角色:工厂方法所创建产品对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
    具体产品角色:这个角色实现了抽象产品角色所声名的接口。工厂方法所创建的每个具体产品对象都是某个具体产品角色的实例。
 
1.2.3 工厂方法模式在农场系统中的实现
 
1.2.3.1 背景
    在简单工厂模式中,有个全能的园丁,控制所有作物的种植、生长和收获。现在农场规模变大了,管理更加专业化了。过去全能的园丁没有了,每一种作物都有专门的园丁管理,形成了规模化和专业化生产。
 
1.2.3.2 系统设计机构图
点击在新窗口查看全图
 
1.2.3.3 实现源码
 
1.2.3.3.1 水果产品接口Fruit.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
 * Created by IntelliJ IDEA.
 * FileName:Fruit.java
 * User:    LavaSoft
 * Date:    2006-12-3
 * Time:    17:25:48
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  水果接口
 */
public interface Fruit {
    /**
     * 种植
     */
    void plant();
    /**
     * 生长
     */
    void grow();
    /**
     * 收获
     */
    void harvest();
}
 
1.2.3.3.2 具体产品苹果Apple.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
 * Created by IntelliJ IDEA.
 * FileName:Apple.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Time:    0:47:25
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  水果工厂的产品:苹果
 */
public class Apple implements Fruit {
    private int treeAge;
    /**
     * 种植
     */
    public void plant() {
        System.out.println("Apple has been planted.");
    }
    /**
     * 生长
     */
    public void grow() {
        System.out.println("Apple is growing...");
    }
    /**
     * 收获
     */
    public void harvest() {
        System.out.println("Apple has been harvested.");
    }
    /**
     * @return 返回树龄
     */
    public int getTreeAge() {
        return treeAge;
    }
    /**
     * 设置树龄
     */
    public void setTreeAge(int treeAge) {
        this.treeAge = treeAge;
    }
}

1.2.3.3.3 具体产品葡萄:Grape.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
 * Created by IntelliJ IDEA.
 * FileName:Grape.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Time:    0:36:56
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  水果工厂的产品:葡萄
 */
public class Grape implements Fruit {
    private boolean seedless;   //是否有籽
    /**
     * 种植
     */
    public void plant() {
        System.out.println("Grape has been planted.");
    }
    /**
     * 生长
     */
    public void grow() {
        System.out.println("Grape is growing...");
    }
    /**
     * 收获
     */
    public void harvest() {
        System.out.println("Grape has been harvested.");
    }
    /**
     * @return 是否有籽
     */
    public boolean getSeedless() {
        return seedless;
    }
    /**
     * 有无籽的赋值方法
     */
    public void setSeedless(boolean seedless) {
        this.seedless = seedless;
    }
    /**
     * 辅助方法
     */
    public static void log(String msg) {
        System.out.println(msg);
    }
}

1.2.3.3.4 具体产品草莓:Strawberry.java
package com.lavasoft.patterns.factorymethod.ybms;

/**
 * Created by IntelliJ IDEA.
 * FileName:Strawberry.java
 * User:    LavaSoft
 * Date:    2006-12-1
 * Time:    0:45:09
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  水果工厂的产品:草莓
 */
public class Strawberry implements Fruit {
    /**
     * 生长
     */
    public void grow() {
        System.out.println("Strawberry is growing...");
    }
    /**
     * 收获
     */
    public void harvest() {
        System.out.println("Strawberry has been harvested.");
    }
    /**
     * 种植
     */
    public void plant() {
        System.out.println("Strawberry has been planted.");
    }
    /**
     * 辅助方法
     */
    public static void log(String msg) {
        System.out.println(msg);
    }
}
 
1.2.3.3.5 水果工厂接口:FruitGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
 * Created by IntelliJ IDEA.
 * FileName:FruitGardener.java
 * User:    LavaSoft
 * Date:    2006-12-3
 * Time:    17:22:52
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  水果工厂接口
 */
public interface FruitGardener {
    /**
     * 工厂方法
     *
     * @return 水果
     */
    public Fruit factory();
}
 
1.2.3.3.6 苹果工厂:AppleGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
 * Created by IntelliJ IDEA.
 * FileName:AppleGardener.java
 * User:    LavaSoft
 * Date:    2006-12-3
 * Time:    17:45:29
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  苹果工厂方法
 */
public class AppleGardener implements FruitGardener {
    /**
     * 工厂方法
     *
     * @return 苹果
     */
    public Fruit factory() {
        Fruit f = new Apple();
        System.out.println("水果工厂(AppletGardener)成功创建一个水果:苹果!");
        return f;
    }
}
 
1.2.3.3.7 葡萄工厂:GrapeGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
 * Created by IntelliJ IDEA.
 * FileName:GrapeGardener.java
 * User:    LavaSoft
 * Date:    2006-12-3
 * Time:    17:51:41
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  添加说明
 */
public class GrapeGardener implements FruitGardener {
    /**
     * 工厂方法
     *
     * @return 葡萄
     */
    public Fruit factory() {
        Fruit f = new Grape();
        System.out.println("水果工厂(GrapeGardener)成功创建一个水果:葡萄!");
        return f;
    }
}
 
1.2.3.3.8 草莓工厂:StrawberryGardener.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
 * Created by IntelliJ IDEA.
 * FileName:StrawberryGardener.java
 * User:    LavaSoft
 * Date:    2006-12-3
 * Time:    17:53:30
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  添加说明
 */
public class StrawberryGardener implements FruitGardener {
    /**
     * 工厂方法
     *
     * @return 草莓
     */
    public Fruit factory() {
        Fruit f = new Strawberry();
        System.out.println("水果工厂(StrawberryGardener)成功创建一个水果:草莓!");
        return f;
    }
}
 
1.2.3.3.9 测试类(客户端):TestApp.java
package com.lavasoft.patterns.factorymethod.ybms;
/**
 * Created by IntelliJ IDEA.
 * FileName:TestApp.java
 * User:    LavaSoft
 * Date:    2006-12-3
 * Time:    17:54:48
 * 《Java与模式》(--阎宏博士著)读书笔记
 * 工厂模式--工厂方法模式--一般性模式(农场应用)
 * ReadMe:  测试类(客户端)
 */
public class TestApp {
    private FruitGardener f1, f2, f3;
    private Fruit p1, p2, p3;
    private void test() {
        //实力化水果工厂
        f1 = new AppleGardener();
        f2 = new GrapeGardener();
        f3 = new StrawberryGardener();
        //从水果工厂生产水果
        p1 = f1.factory();
        p2 = f2.factory();
        p3 = f3.factory();
    }
    public static void main(String args[]) {
        TestApp test = new TestApp();
        test.test();
    }
}
 
1.2.3.3.10 测试运行结果
    水果工厂(AppletGardener)成功创建一个水果:苹果!
    水果工厂(GrapeGardener)成功创建一个水果:葡萄!
    水果工厂(StrawberryGardener)成功创建一个水果:草莓!
    Process finished with exit code 0
 
1.2.3.4 关于工厂方法模式的实现
   在下面我简单说说一些实现方式,不做详细分析了。
 1.使用java接口或者java抽象类
 2.使用多个工厂方法
 3.产品循环使用
 4.多态性的丧失和模式的退化,主要体现在工厂方法创建对象、工厂方法返回的类型、工厂等级结构三个方面。
 
1.2.3.5 女娲举绳造人
 
   女娲举绳造人是工厂方法模式的一个实例。下面仅仅给出设计图如下,具体编码请您自己实现。
点击在新窗口查看全图
 
 
   呵呵,学会了简单工厂模式再来学工厂方法,是不是很容易啊,看懂农场一个例子就够了,多实践多思考比什么都好!
   
    终于加班后“家班”完成了!完成时间2006年12月5日星期二12时16分51秒。



本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/11458,如需转载请自行联系原作者
相关文章
|
2月前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
137 11
|
23天前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
86 40
|
25天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——简单工厂模式
简单工厂模式是一种创建型设计模式,通过工厂类根据传入参数创建不同类型的对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。适用于对象种类较少且调用者无需关心创建细节的场景。
53 19
|
23天前
|
设计模式 Java
「全网最细 + 实战源码案例」设计模式——生成器模式
生成器模式(Builder Pattern)是一种创建型设计模式,用于分步骤构建复杂对象。它允许用户通过控制对象构造的过程,定制对象的组成部分,而无需直接实例化细节。该模式特别适合构建具有多种配置的复杂对象。其结构包括抽象建造者、具体建造者、指挥者和产品角色。适用于需要创建复杂对象且对象由多个部分组成、构造过程需对外隐藏或分离表示与构造的场景。优点在于更好的控制、代码复用和解耦性;缺点是增加复杂性和不适合简单对象。实现时需定义建造者接口、具体建造者类、指挥者类及产品类。链式调用是常见应用方式之一。
50 12
|
25天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——工厂方法模式
简单工厂模式是一种创建型设计模式,通过一个工厂类根据传入参数创建不同类型的产品对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。适用于创建对象种类较少且调用者无需关心创建细节的场景。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。
44 15
|
3月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
3月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
56 4
|
3月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式
|
Java
Java反射之Method对象详解
使用Java反射,可以在运行时检查一个方法的信息以及在运行期调用这个方法,通过使用java.lang.reflect.Method类就可以实现上述功能。
494 0
|
2天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
33 14

热门文章

最新文章