zoukankan      html  css  js  c++  java
  • 【设计模式系列-创建型模式篇】-工厂方法模式

    工厂方法模式定义

    工厂方法模式的使用频率非常高,在我们日常的开发过程中总能见到它的身影。其定义为:Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses. 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

    工厂方法模式应用场景

    工厂方法模式是通过new关键字创建对象的替代品,所有需要生产对象的地方都可以使用,但是需要慎重考虑是否要增加一个工厂类进行管理,因为这势必会增加代码的复杂度。

    工厂方法模式应用

    /**
     * 抽象运算类
     */
    public abstract class Operation {
    
        // 两个数之间的运算
        public abstract double operate(double a,double b);
    
    }
    /**
     * 加法实现类
     */
    public class AddOperation extends Operation {
    
        @Override
        public double operate(double a, double b) {
            return a + b;
        }
    }
    /**
     * 减法实现类
     */
    public class SubOperation extends Operation {
    
        @Override
        public double operate(double a, double b) {
            return a - b;
        }
    }
    /**
     * 乘法实现类
     */
    public class MulOperation extends Operation {
    
        @Override
        public double operate(double a, double b) {
            return a * b;
        }
    }
    /**
     * 除法实现类
     */
    public class DivOperation extends Operation {
    
        @Override
        public double operate(double a, double b) {
            if (b != 0){
                return a/b;
            }
            return 0;
        }
    }
    /**
     * 抽象运算工厂类
     */
    public abstract class AbstractOperationFactory {
    
        public abstract <T extends Operation> T createOperation(Class <T> c);
    }
    /**
     * 具体工厂实现
     */
    public class OperationFactory extends AbstractOperationFactory {
    
        @Override
        public <T extends Operation> T createOperation(Class <T> c) {
            Operation operation = null;
            try {
                operation = (Operation) Class.forName(c.getName()).newInstance();
            } catch (Exception e) {
                System.out.println("获取运算类异常");
            }
            return (T) operation;
        }
    }
    /**
     * 测试类
     */
    public class MainTest {
    
        @Test
        public void test(){
    
            AbstractOperationFactory abstractOperationFactory = new OperationFactory();
            Operation addOperation = abstractOperationFactory.createOperation(AddOperation.class);
            System.out.println(addOperation.operate(1,2));
            Operation subOperation = abstractOperationFactory.createOperation(SubOperation.class);
            System.out.println(subOperation.operate(3,2));
            Operation mulOperation = abstractOperationFactory.createOperation(MulOperation.class);
            System.out.println(mulOperation.operate(2,4));
            Operation divOperatipon = abstractOperationFactory.createOperation(DivOperation.class);
            System.out.println(divOperatipon.operate(6,3));
        }
    }

    通过这个实例可以体验工厂方法模式的优点:

    1、良好的封装性,代码结构清晰,一个对象的创建是有条件约束的,调用着需要获取一个具体的产品对象,只要知道这个产品的类名就可以了,不用知道创建对象等等艰辛过程,降低模块间的耦合。

    2、良好的扩展性,在增加产品类的情况下,只要适当修改具体工厂类或扩展一个工厂类,就可以轻松拥抱变化。

    3、屏蔽产品类,产品类的实现如何变化,调用者都不需要关心,只需要关心产品类的接口,只要接口不变,系统中的上层模块就不要发生变化。

    4、工厂方法模式是典型的解耦框架,高层模块只需要知道产品的抽象类,其他的实现类都不用关心。

     工厂方法模式扩展

    简单工厂模式

    一个模块需要一个工厂类,没有必要把它生产出来,使用静态的方法就可以。

    /**
     * 具体工厂实现
     */
    public class OperationFactory {
    
        public static <T extends Operation> T createOperation(Class <T> c) {
            Operation operation = null;
            try {
                operation = (Operation) Class.forName(c.getName()).newInstance();
            } catch (Exception e) {
                System.out.println("获取运算类异常");
            }
            return (T) operation;
        }
    }

    简单工厂模式也叫静态工厂模式,在项目开发中运用也比较多,但是该设计模式存在一个缺点就是工厂类的扩展比较困难,不符合开闭原则。

    升级到多个工厂类

    考虑到需要结构清晰,我们为每个产品定义一个工厂类,然后调用者去选择与哪个工厂方法关联。

    /**
     * 抽象运算工厂类
     */
    public abstract class AbstractOperationFactory {
    
        public abstract Operation createOperation();
    }
    /**
     * 加法运算工厂
     */
    public class AddOperationFactory extends AbstractOperationFactory {
    
        @Override
        public Operation createOperation() {
            return new AddOperation();
        }
    }
    /**
     * 减法运算工厂
     */
    public class SubOperationFactory extends AbstractOperationFactory {
    
        @Override
        public Operation createOperation() {
            return new SubOperation();
        }
    }
    /**
     * 乘法工厂
     */
    public class MulOperationFactory extends AbstractOperationFactory {
    
        @Override
        public Operation createOperation() {
            return new MulOperation();
        }
    }
    /**
     * 除法工厂
     */
    public class DivOperationFactory extends  AbstractOperationFactory {
    
        @Override
        public Operation createOperation() {
            return new DivOperation();
        }
    }

    这样改造完之后,结构变得简单,但是给可扩展性和可维护性带来了一定的影响。如果要扩展一个产品类,就需要建立一个相应的工厂类,这样就增加了扩展的难度,工厂类和产品类数量一致,维护时需要考虑两个对象之间的关系。

  • 相关阅读:
    Java基础:基本类型
    完全干净的卸载VS2013
    git本地仓库首次push到远程仓库出现错误 ! [rejected] master -> master (fetch first)
    运行VS出现warning C4996错误的解决办法
    xbmc-android的编译
    linux执行sh,出现/bin/sh^M: bad interpreter: No such file or directory
    Ubuntu配置android-vlc编译环境(2015-11-05)
    a80修改默认4k输出,官方代码锁死了
    ubuntu12.04平台下a80编译环境搭建
    编译java代码出现 错误: 需要class, interface或enum 提示
  • 原文地址:https://www.cnblogs.com/ysdrzp/p/10015216.html
Copyright © 2011-2022 走看看