• 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);
        }
    }

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

  • 相关阅读:
    Shell编程——基于IBM培训教程的总结
    flex上下固定中间滚动布局
    exe 转服务
    itextcsharp使用
    devices detect
    [转]Java api 全集 【API JDK1.6中文版】
    JavaScript 项目优化总结
    服务程序打包
    knockoutjs
    C#压缩《收藏》
  • 原文地址:https://www.cnblogs.com/mylqm/p/14971284.html
Copyright © 2020-2023  润新知