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); } }
如此一来,那么我们需要增加各种复杂运算,比如平方根,立方根,自然对数,正弦余弦等,只需增加相应的运算子类就可以了。