【设计模式系列-创建型模式篇】-工厂方法模式

工厂方法模式定义

工厂方法模式的使用频率非常高,在我们日常的开发过程中总能见到它的身影。其定义为: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();
    }
}

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

原文地址:https://www.cnblogs.com/ysdrzp/p/10015216.html