zoukankan      html  css  js  c++  java
  • 设计模式——简单工厂模式

    定义:

      简单工厂模式是一个由工厂来确定创建某种产品的实例。

      先看一个简单的例子 

    package com.zr.pattern.simpleFactory;
    
    import java.util.Scanner;
    
    /**
     * 实现计算机控制台程序,要求输入两个数和运算符得到运算结果
     * @author zr
     */
    public class Calculator {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入第一个数");
            String firstNumber = scanner.nextLine();
            System.out.println("请输入第二个数");
            String secondNumber = scanner.nextLine();
            System.out.println("请输入运算符");
            String operator = scanner.nextLine();
            String result = "";
            try {
                switch (operator) {
                case "+":
                    result = Double.valueOf(firstNumber) + Double.valueOf(secondNumber) + "";
                    break;
                case "-":
                    result = Double.valueOf(firstNumber) - Double.valueOf(secondNumber)+ "";
                    break;
                case "*":
                    result = Double.valueOf(firstNumber) * Double.valueOf(secondNumber)+ "";
                    break;
                case "/":
                    if(Double.valueOf(secondNumber) != 0){
                        result = Double.valueOf(firstNumber) / Double.valueOf(secondNumber)+ "";    
                    }else {
                        System.out.println("除数不能为零");
                    }
                    break;
                }
                System.out.println("运算结果是:" + result);
            } catch (NumberFormatException e) {
                System.out.println("输入的不是数字");
            }
        }
    }

       这个程序满足功能是没有问题,只是用计算机的思路来表述和解决问题。比如这个程序先输入一个数,在输入一个数,然后根据输入的运算符号获得结构,确实是满足了计算机的需求,但是这种程序。不容易扩展,不容易维护,不容易复用。

      可维护:指的是如果要改,只需更改要改的的地方。比如说上面的程序我改加法 ,很可能不小心把减法的逻辑改了。

      可扩展:指的是如果要加东西,直接加就行了,原来的代码不用动。如果上面的程序我要加个开根的功能。在switch下加分支,那么这个程序会越来越臃肿。有可能会加出毛病来。

      可复用:代码重用。如果别的地方地方需要加减乘除的功能,上述代码完全不能用。耦合度太高了。有的人可能认为把计算的代码复制过去就行了。这不叫复用,这叫复制。如果程序里面相同的代码有很多万一,某个逻辑错了,改起来是不是很痛苦,也有可能改出问题。

    面向对象的设计:继承、封装、多态

      可以通过继承、封装、多态来把程序的耦合度降到最低。上面的计算机程序就是 输入、输出、计算全部都在一个方法里面耦合度太高

        封装:将业务方法抽出来。定义一个接口只有一个方法,获得运算结果

    package com.zr.pattern.simpleFactory;
    
    public interface Operator {
    	public void getResult();
    }
    

      继承:实现这个接口,这样就容易维护和扩展,修改加法 不会影响到减法, 增加一个开根的功能,只需要实现上述的接口,而不需要修改原来的代码。

     1 /**
     2  * 加法类
     3  * @author zr
     4  */
     5 public class OperatorAdd implements Operator{
     6     public double firstNumber = 0;
     7     public double secondNumber = 0;
     8     
     9     public OperatorAdd(double firstNumber, double secondNumber) {
    10         this.firstNumber = firstNumber;
    11         this.secondNumber = secondNumber;
    12     }
    13     
    14     @Override
    15     public void getResult() {
    16         double result = Double.valueOf(firstNumber) + Double.valueOf(secondNumber);
    17         System.out.println("运算结果是:" + result);
    18     }
    19 }
    20 
    21 
    22 /**
    23  * 减法类
    24  * @author zr
    25  */
    26 public class OperatorSub implements Operator{
    27     public double firstNumber = 0;
    28     public double secondNumber = 0;
    29     
    30     public OperatorSub(double firstNumber, double secondNumber) {
    31         this.firstNumber = firstNumber;
    32         this.secondNumber = secondNumber;
    33     }
    34     
    35     @Override
    36     public void getResult() {
    37         double result = Double.valueOf(firstNumber) - Double.valueOf(secondNumber);
    38         System.out.println("运算结果是:" + result);
    39     }
    40 }
    41 
    42 /**
    43  * 乘法类
    44  * @author zr
    45  */
    46 public class OperatorMul implements Operator{
    47     public double firstNumber = 0;
    48     public double secondNumber = 0;
    49     
    50     public OperatorMul(double firstNumber, double secondNumber) {
    51         this.firstNumber = firstNumber;
    52         this.secondNumber = secondNumber;
    53     }
    54     
    55     @Override
    56     public void getResult() {
    57         double result = Double.valueOf(firstNumber) * Double.valueOf(secondNumber);
    58         System.out.println("运算结果是:" + result);
    59     }
    60 }
    61 
    62 
    63 
    64 /**
    65  * 除法类
    66  * @author zr
    67  */
    68 public class OperatorDiv implements Operator{
    69     public double firstNumber = 0;
    70     public double secondNumber = 0;
    71     
    72     public OperatorDiv(double firstNumber, double secondNumber) {
    73         this.firstNumber = firstNumber;
    74         this.secondNumber = secondNumber;
    75     }
    76     
    77     @Override
    78     public void getResult() {
    79         if(Double.valueOf(secondNumber) != 0){
    80             double result = Double.valueOf(firstNumber) / Double.valueOf(secondNumber);
    81             System.out.println("运算结果是:" + result);
    82         }else {
    83             System.out.println("除数不能为零");
    84         }
    85     }
    86 }

      多态:工厂类来实例化对象,通过返回父类的方式实现了计算结果。

    package com.zr.pattern.simpleFactory;
    
    public class OperatorFactory {
        public static Operator createrOperator(String operator, double first, double second){
            Operator o = null;
            switch (operator) {
            case "+":
                o = new OperatorAdd(first, second);
                break;
            case "-":
                o = new OperatorSub(first, second);
                break;
            case "*":
                o = new OperatorMul(first, second);
                break;
            case "/":
                o = new OperatorDiv(first, second);
                break;
            }
            return o;
        }
    }

        客户端类:

    public class Client {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入第一个数");
            String firstNumber = scanner.nextLine();
            System.out.println("请输入第二个数");
            String secondNumber = scanner.nextLine();
            System.out.println("请输入运算符");
            String operator = scanner.nextLine();
            //加法
            Operator o = OperatorFactory.createrOperator("+", Double.valueOf(firstNumber), Double.valueOf(secondNumber));
            o.getResult();
        }
    }

    这样设计计算器:

    1、如果要修改加法,只需要修改OperatorAdd类,不会影响其他算法。

    2、如果要增加其他的复杂运算,如平方根、立方根,只需要增加相应的子类,并修改工厂类增加switch分支。

    这样就实现了 可维护、可扩展、易重用(加减乘除的算法完全可以单独调用)。

     

    uml类图如下

  • 相关阅读:
    mysql重启.....
    tomcat双向认证
    tomcat单向认证
    tomcat ssi使用
    各种排序
    字符转换
    threeSum问题
    求出0~999之间的所有“水仙花数”并输出
    动态规划
    迷惑一天的代码
  • 原文地址:https://www.cnblogs.com/lnzr/p/5785506.html
Copyright © 2011-2022 走看看