设计模式 | 工厂方法模式(factory method)

定义:

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

结构:(书中图,侵删)

一个工厂的抽象接口
若干个具体的工厂类
一个需要创建对象的抽象接口
若干个所需创建的对象的类
 
较之简单工厂方法,多了一层抽象——将工厂也抽象了;由原来的一个万能工厂变为现在的若干个各司其职的工厂。
 
导致的结果就是:原本新增一个要创建的对象需要直接修改万能工厂类,增加判断,违反了开放-封闭原则;
现在工厂相关代码不用改,只需要新增工厂类即可,同时将判断转移给了客户端。

实例:

既然是和简单工厂相对比,就还是延用之前计算器的例子:(同样,为了代码简洁不考虑输入不合法等代码健壮性)
抽象工厂接口:
package designpattern.factorymethod;

import designpattern.staticfactorymethod.Calculate;

public interface CalculateFactory {
    Calculate create();
}
若干工厂接口:
package designpattern.factorymethod;

import designpattern.staticfactorymethod.Calculate;
import designpattern.staticfactorymethod.Plus;

public class PlusFactory implements CalculateFactory{

    @Override
    public Calculate create() {
        return new Plus();
    }

}
package designpattern.factorymethod;

import designpattern.staticfactorymethod.Calculate;
import designpattern.staticfactorymethod.Minus;

public class MinusFactory implements CalculateFactory {

    @Override
    public Calculate create() {
        return new Minus();
    }

}

package designpattern.factorymethod;

import designpattern.staticfactorymethod.Calculate;
import designpattern.staticfactorymethod.Multiply;

public class MultiplyFactory implements CalculateFactory {

    @Override
    public Calculate create() {
        return new Multiply();
    }

}

package designpattern.factorymethod;

import designpattern.staticfactorymethod.Calculate;
import designpattern.staticfactorymethod.Divide;

public class DivideFactory implements CalculateFactory {

    @Override
    public Calculate create() {
        return new Divide();
    }

}

抽象计算类及若干具体计算类:(延用之前简单工厂方法的代码)
抽象类:
package designpattern.staticfactorymethod;

public abstract class Calculate {
    public double num1;
    public double num2;

    Calculate() {
    }

    Calculate(double num1, double num2) {
        this.num1 = num1;
        this.num2 = num2;
    }

    public abstract double calculate();
}

加:

package designpattern.staticfactorymethod;

public class Plus extends Calculate {
    public Plus() {
    }

    Plus(double num1, double num2) {
        super(num1, num2);
    }

    @Override
    public double calculate() {
        return num1 + num2;
    }

}
package designpattern.staticfactorymethod;

public class Minus extends Calculate {
    public Minus() {
    }

    Minus(double num1, double num2) {
        super(num1, num2);
    }

    @Override
    public double calculate() {
        return num1 - num2;
    }

}

package designpattern.staticfactorymethod;

public class Multiply extends Calculate {
    public Multiply() {
    }

    Multiply(double num1, double num2) {
        super(num1, num2);
    }

    @Override
    public double calculate() {
        return num1 * num2;
    }

}

package designpattern.staticfactorymethod;

public class Divide extends Calculate {
    public Divide() {
    }

    Divide(double num1, double num2) {
        super(num1, num2);
    }

    @Override
    public double calculate() {
        return num1 / num2;
    }

}

客户端:
package designpattern.factorymethod;

import java.util.Scanner;

import designpattern.staticfactorymethod.Calculate;

public class Client {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个数字");
        double num1 = scanner.nextDouble();
        System.out.println("请输入一个运算符:+、-、*、/");
        String operator = scanner.next();// 不能用nextLine(),会把上一个回车给吸收
        System.out.println("请输入一个数字");
        double num2 = scanner.nextDouble();
        CalculateFactory calculateFactory = null;

        switch (operator) {
        case "+":
            calculateFactory = new PlusFactory();
            break;
        case "-":
            calculateFactory = new MinusFactory();
            break;
        case "*":
            calculateFactory = new MultiplyFactory();
            break;
        case "/":
            calculateFactory = new DivideFactory();
            break;
        default:
            break;
        }
        Calculate calculate = calculateFactory.create();
        calculate.num1 = num1;
        calculate.num2 = num2;
        System.out.println(calculate.calculate());
        scanner.close();
    }
}

总结:

工厂方法模式就是在简单工厂方法模式的基础上进一步抽象,使其符合开放-封闭原则。
个人理解,在轻量级系统,或者工厂所能创建的东西较少可能修改的情况下,可以考虑使用简单工厂模式;
否则,需要使用工厂方法模式。
(0)

相关推荐

  • 方法重载

    方法名必须相同,参数列表不同(类型或个数或排列顺序不同) public static int max(int num1, int num2) { //方法体 } public static doubl ...

  • 数据结构-栈

    栈 定义 限制插入和删除只能在表的末端进行操作,也就是栈顶进行操作.符合先进后出的特点.Java中栈的实现是 通过数组. 例如:把1,2,3,4插入栈中,则存储结构如下: 栈的简单应用-计算器 代码如 ...

  • 大话设计模式笔记(二)の策略模式

    举个栗子 问题描述 商场收银软件,营业员根据客户所购买的商品单价和数量,向客户收费. 简单实现 /** * 普通实现 * Created by callmeDevil on 2019/6/1. */ ...

  • 设计模式-工厂方法模式学习笔记

    工厂方法模式 定义 工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负 ...

  • 【设计模式】工厂方法模式(Factory Method)

    工厂方法模式(Factory Method) 工厂方法模式分为三种: 1.普通工厂模式 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.首先看下关系图:举例如下:(我们举一个发送邮件和短信 ...

  • 【7/25】使用工厂方法模式(Factory Method Pattern)创建Page页面对象

    这是<小游戏从0到1设计模式重构>系列内容第7篇,所有源码及资料在"程序员LIYI"公号回复"小游戏从0到1"获取. 看完三姐妹中的简单工厂模式,再 ...

  • 大白话工厂方法模式(Factory Method)

    目录 简单工厂模式缺陷 简单工厂模式改造 工厂方法模式定义 工厂方法模式结构 工厂方法模式分析 优点分析 缺点分析 参考文献 简单工厂模式缺陷 大白话简单工厂模式(Simple Factory Pat ...

  • PHP设计模式之工厂方法模式

    PHP设计模式之工厂方法模式 上回说到,简单工厂不属于GoF的二十三种设计模式,这回可就来真家伙了,大名顶顶的工厂方法模式前来报道! GoF类图解释 工厂方法模式对比简单工厂来说,最核心的一点,其实就 ...

  • [PHP小课堂]PHP设计模式之工厂方法模式

    [PHP小课堂]PHP设计模式之工厂方法模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 设计模式(1) 工厂方法模式

    创建型模式 简单工厂模式 工厂方法模式 IOC与工厂方法模式的结合 泛型工厂 委托工厂 创建型模式 创建型模式可以隔离客户程序对需要实例化类型的依赖关系,这类模式一般通过将实例化具体对象的职责委托给第 ...

  • 【设计模式】工厂方法模式

    定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类 优缺点 优点 针对简单工厂不容易扩展,工厂方法将实例化延迟到子类工厂,从而提供扩展 缺点 每次新增产品 ...

  • 大话设计模式笔记(六)の工厂方法模式

    栗子回顾 简单工厂模式: https://www.cnblogs.com/call-me-devil/p/10926633.html 运算类使用工厂方法模式实现 UML图 代码实现 工厂接口 /** ...