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,如需转载请自行联系原作者
相关文章
|
10月前
|
设计模式 Java 数据库连接
【设计模式】【创建型模式】工厂方法模式(Factory Methods)
一、入门 什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪个类。工厂方法模式使类的实例化延迟
296 16
|
10月前
|
设计模式 Java 关系型数据库
【设计模式】【创建型模式】抽象工厂模式(Abstract Factory)
一、入门 什么是抽象工厂模式? 抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建相关或依赖对象的家族,而不需要指定具体的类。 简单来说,抽象工厂模式是工厂方法模式的升级版,它能够创建一组相
345 14
|
8月前
|
Java 应用服务中间件 Docker
java-web部署模式概述
本文总结了现代 Web 开发中 Spring Boot HTTP 接口服务的常见部署模式,包括 Servlet 与 Reactive 模型、内置与外置容器、物理机 / 容器 / 云环境部署及单体与微服务架构,帮助开发者根据实际场景选择合适的方案。
393 25
|
8月前
|
存储 Java 大数据
Java 大视界 -- Java 大数据在智能家居能源消耗模式分析与节能策略制定中的应用(198)
简介:本文探讨Java大数据技术在智能家居能源消耗分析与节能策略中的应用。通过数据采集、存储与智能分析,构建能耗模型,挖掘用电模式,制定设备调度策略,实现节能目标。结合实际案例,展示Java大数据在智能家居节能中的关键作用。
|
10月前
|
供应链 JavaScript 前端开发
Java基于SaaS模式多租户ERP系统源码
ERP,全称 Enterprise Resource Planning 即企业资源计划。是一种集成化的管理软件系统,它通过信息技术手段,将企业的各个业务流程和资源管理进行整合,以提高企业的运营效率和管理水平,它是一种先进的企业管理理念和信息化管理系统。 适用于小微企业的 SaaS模式多租户ERP管理系统, 采用最新的技术栈开发, 让企业简单上云。专注于小微企业的应用需求,如企业基本的进销存、询价,报价, 采购、销售、MRP生产制造、品质管理、仓库库存管理、财务应收付款, OA办公单据、CRM等。
639 23
|
设计模式 Java 关系型数据库
设计模式:工厂方法模式(Factory Method)
工厂方法模式是一种创建型设计模式,通过将对象的创建延迟到子类实现解耦。其核心是抽象工厂声明工厂方法返回抽象产品,具体工厂重写该方法返回具体产品实例。适用于动态扩展产品类型、复杂创建逻辑和框架设计等场景,如日志记录器、数据库连接池等。优点包括符合开闭原则、解耦客户端与具体产品;缺点是可能增加类数量和复杂度。典型应用如Java集合框架、Spring BeanFactory等。
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
368 4
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
227 4
|
设计模式 存储 负载均衡
【五】设计模式~~~创建型模式~~~单例模式(Java)
文章详细介绍了单例模式(Singleton Pattern),这是一种确保一个类只有一个实例,并提供全局访问点的设计模式。文中通过Windows任务管理器的例子阐述了单例模式的动机,解释了如何通过私有构造函数、静态私有成员变量和公有静态方法实现单例模式。接着,通过负载均衡器的案例展示了单例模式的应用,并讨论了单例模式的优点、缺点以及适用场景。最后,文章还探讨了饿汉式和懒汉式单例的实现方式及其比较。
【五】设计模式~~~创建型模式~~~单例模式(Java)
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
133 11