Java设计模式-简单工厂模式

一、简单工厂模式的概述

1. 定义:定义一个工厂类,它可以根据不同的参数返回不同的实例,被创建的实例通常具有相同的父类

以活字印刷术为例,不同活字的排列组合得到不同的文章,这些文章的活字都来源于同一套活字模板

2. 在简单工厂中被创建的实例方法通常是静态方法(Static Method),因此简单工厂模式又被成为静态工厂方法(Statis Factory Method) 

 

二、简单工厂模式的结构和实现

1. 结构

 

上述UML简单来说就是创建一个抽象类(父类)->其他的类(子类)继承抽象类,实现父类的方法->创建一个类写逻辑判断,调用子类方法

注意:父类中statis修饰的普通方法,不能被子类继承

1)Factory(工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象

2)Product(抽象类产品):工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象

3)ConcreteProduct(具体产品):简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象产品中声明的抽象方法(有关抽象类)

 

2. 实现

/**
 * @author ***
 * @title: Test2
 * @projectName design-pattern
 * @description TODO
 * @date 2021/7/510:27
 */
abstract class Product {
    public static void MethName() {
        //公共方法的实现
    }

    public abstract void MethodDiff();
    //声明抽象业务方法
}

class ConcreteProductA extends Product {
    @Override
    public void MethodDiff() {
        //业务方法的实现
    }
}

class ConcreteProductB extends Product {
    @Override
    public void MethodDiff() {
        //业务方法的实现
    }
}

class Factory {
    public static Product GetProduct(String arg) {
        Product product = null;
        if (arg.equals("A")){
            product = new ConcreteProductA();
            //init
        }else if (arg.equals("B")) {
            product = new ConcreteProductB();
            //init
        } else {
            //其他情况
        }
        return product;
    }
}

class Program {
    public static void main(String[] args) {
        Product product;
        product = Factory.GetProduct("A");//工厂类创建对象
        Product.MethName();
        product.MethodDiff(); 
    }
       
}

 

三、简单工厂模式的优缺点和适用环境  

1. 优点

1)工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责
2)客户端无需知道所创建具体产品的类名,只需知道参数即可
3)也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。(这也是我在开始的披萨店里遇到没有的披萨的解决情况)

2. 缺点

1)工厂类集中了所有产品的创建逻辑,职责过重,一旦异常,整个系统将受影响
2)使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
3)系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
4)简单工厂模式使用了static工厂方法,造成工厂角色无法形成基于继承的等级结构。

3. 适用环境

1)工厂类负责创建对的对象比较少,因为不会造成工厂方法中的业务逻辑过于复杂

2)客户端只知道传入工厂类的参数,对如何创建对象不关心

 

四、实际案例

利用简单工厂模式编写一款简单的计算器软件程序

我们在设计的时候最重要是将界面逻辑(main方法)和业务逻辑(普通方法)分开,降低代码之间的耦合度

业务逻辑:

/**
 * @author ***
 * @title: Operation
 * @projectName design-pattern
 * @description 运算抽象类
 * @date 2021/7/510:49
 */
public abstract class Operation {
    private double _numberA = 0;
    private double _numberB = 0;

    public double get_numberA() {
        return _numberA;
    }
    public void set_numberA(double _numberA) {
        this._numberA = _numberA;
    }
    public double get_numberB() {
        return _numberB;
    }
    public void set_numberB(double _numberB) {
        this._numberB = _numberB;
    }

    public abstract double getResult();
}
/**
 * @author ***
 * @title: OperationAdd
 * @projectName design-pattern
 * @description 加法类,继承运算类
 * @date 2021/7/5 10:50
 */
public class OperationAdd extends Operation{
    @Override
    public double getResult() {
        double result = 0;
        return get_numberA() + get_numberB();
    }
}
/**
 * @author ***
 * @title: OperationSub
 * @projectName design-pattern
 * @description 加减乘除类 -- 减法类,继承运算类
 * @date 2021/7/5 10:51
 */
public class OperationSub extends Operation{
    @Override
    public double getResult() {
        double result = 0;
        return get_numberA() - get_numberB();
    }
}
/**
 * @author ***
 * @title: OperationMul
 * @projectName design-pattern
 * @description 加减乘除类 -- 乘法类,继承运算类
 * @date 2021/7/5 10:53
 */
public class OperationMul extends Operation{
    @Override
    public double getResult() {
        double result = 0;
        return get_numberA() * get_numberB();
    }
}
/**
 * @author ***
 * @title: OperationDiv
 * @projectName design-pattern
 * @description 加减乘除类 -- 除法类,继承运算类
 * @date 2021/7/5 10:54
 */
public class OperationDiv extends Operation{
    @Override
    public double getResult() {
        double result = 0;
        return get_numberA() / get_numberB();
    }
}
/**
 * @author ***
 * @title: OperationFacotry
 * @projectName design-pattern
 * @description 简单运算工厂类
 * @date 2021/7/5 10:57
 */
public class OperationFactory {
    public static Operation createOperate(String operate){
        Operation oper = null;
        switch (operate)
        {
            case "+":
                oper = new OperationAdd();
                break;
            case "-":
                oper = new OperationSub();
                break;
            case "*":
                oper = new OperationMul();
                break;
            case "/":
                oper = new OperationDiv();
                break;
        }
        return oper;
    }
}

界面逻辑:

/**
 * @author ***
 * @title: ClassC
 * @projectName design-pattern
 * @description 客户端代码
 * @date 2021/7/5 10:58
 */
public class ClassC {
    public static void main(String[] args) {
        Operation oper;
        oper = OperationFactory.createOperate("-");
        oper.set_numberA(1);
        oper.set_numberB(2);
        double result = oper.getResult();
        System.out.println("结果是:" + result);
    }
}

如此一来,那么我们需要增加各种复杂运算,比如平方根,立方根,自然对数,正弦余弦等,只需增加相应的运算子类就可以了。 

 

posted @ 2021-07-05 11:23  八块腹肌的青书  阅读(111)  评论(0编辑  收藏  举报
Live2D