设计模式(Ⅱ)简单工厂模式+计算器类(妙用反射)

468 阅读2分钟

简单工厂模式


一、类图

简单工厂模式包含的角色如下

  • Factory 工厂角色
  • Product 抽象产品角色
  • ConcreteProduct 具体产品角色

简单工厂模式类图.jpg

二、计算器实现

abstract class Operation{
    double a, b;
    abstract double getResult() throws Exception;
}
class Add extends Operation{
    double getResult(){
        return a + b;
    }
}
class Sub extends Operation{
    double getResult(){
        return a - b;
    }
}
class Mul extends Operation{
    double getResult(){
        return a * b;
    }
}
class Div extends Operation{
    if(b == 0){
        throw new Exception("除数不能为0");
    }
    return a / b;
}
class OperationFactory{   //运算类工厂
    public Operator creatOperator(char c){
        Operator op = null;
        switch(c){
            case '+': op = new Add(); break;
            case '-': op = new Sub(); break;
            case '*': op = new Mul(); break;
            case '/': op = new Div(); break;
        }
        return op;
    }
}
public static void main(String[] args) throws Exception{
    char c = (char)System.in.read();
    Operater op = OperatorFactory.creatOperstor(c);
    Scanner sc = new Scanner();
    op.a = sc.nextDouble();
    op.b = sc.nextDouble();
    double res = op.getResult();
    System.out.println("运算结果为 : " + res);
}

计算器对应类图如下

简单工厂模式计算器类图.jpg

三、java反射(Java Reflection)

  • 反射是指在程序运行时获取已知名称类或已有对象的相关信息的一种机制,包括类的方法、属性、超类等信息,还包括实例的创建和实例类型的判断等
  • 反射机制支持在状态中动态地获取类的信息,提供动态调用对象的能力
Class对象
  • Class类是一个特殊的类,它的实例可以存储Java程序运行时的类和接口的有关信息

  • 每个运行的java类都有一个相应的Class对象

  • Class类中用于提供类信息的常用方法

    • getName() 返回类名
    • newInstance() 创建该类的一个新实例
    • getField() 返回类成员变量
    • getMethod() 返回该成员的方法

    可以通过一个类名字符串得到类的实例

使用反射机制的工厂类
class OperationFactory{
    public static Operation createOperation(String operate) throws exception{
        Operation opObject = null;
        opObject = (Operation)(Class.forName(operate).newInstance());
        return opObject;
    }
}
class Client{
    public static void main(String[] args){
        Sacnner sc = new Scanner(System.in());
        String operate = sc.next();
        Operation op = OperationFactory.createOperation(operate);
        op.a = sc.nextDouble();
        op.b = sc.nextDouble();
        System.out.println(op.getResult());
        /* op.getResult(a, b) */
    }
}

四、优点

  • 实现了对象的使用创建和对象的使用分离,将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易
  • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无需知道其创建细节

五、缺点

  • 简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要更改工厂类的判断逻辑,这一点与开闭原则是相违背的
  • 在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护
  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统复杂度和理解难度

六、适用情况

  • 工厂类负责创建的产品比较少
  • 客户端只知道传入工厂的参数,对于如何创建对象并不关心