欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式(一):简单工厂

程序员文章站 2024-01-21 20:31:16
...

定义:

从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

需求:

模拟一个计算器的实现,输入一个数,再输入加减乘中的一个运算符,再输入第二个数字,运算结果返回

简单实现:

 public static void main(String args[]) {
    try {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入第一个数");
        String strA = scanner.nextLine();
        System.out.println("请输入符号");
        String operator = scanner.nextLine();
        System.out.println("请输入第二个数");
        String strB = scanner.nextLine();

        Integer numA = Integer.parseInt(strA);
        Integer numB = Integer.parseInt(strB);

        if (operator.equals("+"))
            System.out.println("结果为:" + (numA + numB));
        else if (operator.equals("-"))
            System.out.println("结果为:" + (numA - numB));
        else if (operator.equals("*"))
            System.out.println("结果为:" + numA*numB);
        else
            System.out.println("请输入正确的符号");
    } catch (Exception e) {
        System.out.println("输入有误");
    }
}

如上我们实现了一个简单的计算器功能。但是我们现在只有加减乘的功能,如果我们现在要添加一个除法功能,我们就要去修改我们的计算器,在if中添加分支,这就会导致我们的计算器经常需要修改,不符合我们的解耦思想。

改进

我们可以将其中判断的那部分抽离出来,这样以后有新的功能加进来,只需要改进我们的计算的代码,而不需要对我们的计算器进行修改。

public static void main(String args[]) {
    try {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入第一个数");
        String strA = scanner.nextLine();
        System.out.println("请输入符号");
        String operator = scanner.nextLine();
        System.out.println("请输入第二个数");
        String strB = scanner.nextLine();

        Integer numA = Integer.parseInt(strA);
        Integer numB = Integer.parseInt(strB);

        Integer result = CalculateFactory.calculate(numA, operator, numB);
        if (null != result)
            System.out.println("结果为:" + result);
        else
            System.out.println("输入有误");
    } catch (Exception e) {
        System.out.println("输入有误");
    }
}

public class Calculate {
    public static Integer calculate(Integer numA, String operator, Integer numB) {
        if (operator.equals("+"))
            return numA + numB;
        else if (operator.equals("-"))
            return numA - numB;
        else if (operator.equals("*"))
            return numA * numB;
        else
            return null;
    }
}

这样我们假如需要添加一个计算就只需要在计算类中添加,就将计算的部分和计算器界面的部分分开来,相当于是完成了解耦。

抽象与多态,紧耦合和松耦合

假如说,我们在添加一个新的计算运算符时,不小心修改了其他的运算的运算比如将numA+numB改成了numA+numA,那么就会导致问题。(不要在这里觉得不回犯这种错误,事实上到了真正的项目中,逻辑并不会像这么简单)
同时,在我们工作的过程中,我们会碰到很多相似的类,实现了类似的功能,比如缓存,根据不同的情况选择用memcache或是ehcache。
在这里,大家都是计算类,不过有的是加法计算有的是减法计算。
我们将计算类抽象成为一个抽象类:

public abstract class Calculate {
    protected Integer numA;
    protected Integer numB;

    public abstract Integer result();
}

接着定义各运算符的计算类

public class CalculateAdd extends Calculate {
    @Override
    public Integer result() {
        return numA + numB;
    }
}

public class CalculateMinus extends Calculate {
    @Override
    public Integer result() {
        return numA - numB;
    }
}

public class CalculateMulti extends Calculate {
    @Override
    public Integer result() {
        return numA * numB;
    }
}

根据运算符生产计算类的工厂类:

public class CalculateFactory {
    public static Calculate getOpr(String operator) {
        Calculate opr = null;
        switch (operator) {
            case "+":
                opr = new CalculateAdd();
                break;
            case "-":
                opr = new CalculateMinus();
                break;
            case "*":
                opr = new CalculateMulti();
                break;
        }
        return opr;
    }
}
   

最后,改进我们的计算器:

public class OperatorDemo1 {
    public static void main(String args[]) {
        try {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入第一个数");
            String strA = scanner.nextLine();
            System.out.println("请输入符号");
            String operator = scanner.nextLine();
            System.out.println("请输入第二个数");
            String strB = scanner.nextLine();

            Integer numA = Integer.parseInt(strA);
            Integer numB = Integer.parseInt(strB);

            Calculate calculate = CalculateFactory.getOpr(operator);
            calculate.numA = numA;
            calculate.numB = numB;
            Integer result = calculate.result();
            if (null != result)
                System.out.println("结果为:" + result);
            else
                System.out.println("输入有误");
        } catch (Exception e) {
            System.out.println("输入有误");
        }
    }
}

优缺点:

优点
  1. 简单工厂模式实现了对责任的分割,提供了专门的工厂类用于创建对象。
  2. 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
  3. 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点
  1. 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
  2. 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
  3. 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
  4. 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

使用场景

  1. 工厂类负责创建的对象比较少。
  2. 客户端只知道传入工厂类的参数,对于如何创建对象不关心。
相关标签: 设计模式