工厂设计模式

什么是工厂模式

  • 工厂模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们定义一个公共的接口。即工厂,让其生产继承某个抽象类或者接口的不同子类对象,这样只需要通过名称告诉工厂我们需要一个什么样的子类对象即可,而不需要关心其如何进行创建,从而对外隐藏对象创建的逻辑。
  • 缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂或者时修改工厂类的代码。

例子:实现两个数的加减乘除运算,后续可能会添加别的运算法则,如何设计实现代码的可复用,可扩展性。

简单工厂模式

实现过程:
在这里插入图片描述

  • 抽象接口:
package com.zzu;

/**
 * 抽象运算类
 */
public interface Operation {

    //运算方法,用于执行各种运算操作
    public void operation(String firstNum,String secondNum);

}
  • 四种运算操作,继承于Operation接口
    加法:
package com.zzu;

public class AddOperation implements Operation{

    @Override
    public void operation(String firstNum, String secondNum) {
        System.out.println("执行加法操作...");
        System.out.println(firstNum + "+" + secondNum + "=" + (Integer.parseInt(firstNum)+Integer.parseInt(secondNum)));
    }
}

减法:

package com.zzu;

public class SubtractionOperation implements Operation{

    @Override
    public void operation(String firstNum, String secondNum) {
        System.out.println("执行减法操作...");
        System.out.println(firstNum + "-" + secondNum + "=" + (Integer.parseInt(firstNum)-Integer.parseInt(secondNum)));
    }
}

乘法:

package com.zzu;

public class multipOperation implements Operation{
    @Override
    public void operation(String firstNum, String secondNum) {
        System.out.println("执行乘法操作...");
        System.out.println(firstNum + "*" + secondNum + "=" + (Integer.parseInt(firstNum)*Integer.parseInt(secondNum)));
    }
}

除法:

package com.zzu;

public class divOperation implements Operation{
    @Override
    public void operation(String firstNum, String secondNum) {
        System.out.println("执行除法操作...");
        System.out.println(firstNum + "/" + secondNum + "=" + (Integer.parseInt(firstNum)/Integer.parseInt(secondNum)));
    }
}

  • 工厂可以根据传入的参数生产不同的操作对象
import com.zzu.*;

public class Factory {
    public static Operation getInstance(String op) {
        if("+".equals(op)) {
            return new AddOperation();
        } else if("-".equals(op)) {
            return new SubtractionOperation();
        }else  if("*".equals(op)) {
            return new multipOperation();
        } else if ("/".equals(op)) {
            return new divOperation();
        }
        return null;
     }
}

  • 测试类
import com.zzu.AddOperation;
import com.zzu.Operation;

public class Test {
/*
实现11和2的四种运算操作
 */
    public static void main(String[] args) {
        //加法操作
        Operation o1 = Factory.getInstance("+");
        o1.operation("11","2");
        //减法操作
        Operation o2 = Factory.getInstance("-");
        o2.operation("11","2");
        //乘法操作
        Operation o3 = Factory.getInstance("-");
        o3.operation("11","2");
        //除法操作
        Operation o4 = Factory.getInstance("-");
        o4.operation("11","2");
    }
}

执行结果:
在这里插入图片描述
可以看出可以实现既定的目标,但是如果有需求变更,比如下载要增加一个求平方的运算,那么我们就需要改动工厂类,需要再增加一个恶else if,因此如果需求变更很大的情况下,对工厂类的变更就非常大,下面对其进行改进。

抽象工厂模式

实现过程:
在这里插入图片描述

改进的地方:
1、定义一个抽象工厂的接口,并在其中定义一个创建对象的抽象方法
2、定义一个类实现工厂接口,用于生产不同的实例对象

  • 抽象工厂接口:
package com.zzu;

public interface AbstractFactory {
    public Operation create();
}

  • 生产加法操作对象的工厂:
package com.zzu.factory;

import com.zzu.AbstractFactory;
import com.zzu.AddOperation;
import com.zzu.Operation;

public class AddFactory implements AbstractFactory {

    @Override
    public Operation create() {
        return new AddOperation();
    }
}
  • 生产j减法操作对象的工厂:
package com.zzu.factory;

import com.zzu.AbstractFactory;
import com.zzu.AddOperation;
import com.zzu.Operation;
import com.zzu.SubtractionOperation;

public class SubFactory implements AbstractFactory {

    @Override
    public Operation create() {
        return new SubtractionOperation();
    }
}
  • 生产乘法操作对象的工厂:
package com.zzu.factory;

import com.zzu.AbstractFactory;
import com.zzu.AddOperation;
import com.zzu.Operation;
import com.zzu.multipOperation;

public class MutilFactory implements AbstractFactory {

    @Override
    public Operation create() {
        return new multipOperation();
    }
}
  • 生产除法操作对象的工厂:

package com.zzu.factory;

import com.zzu.AbstractFactory;
import com.zzu.AddOperation;
import com.zzu.Operation;
import com.zzu.divOperation;

public class DivFactory implements AbstractFactory {

    @Override
    public Operation create() {
        return new divOperation();
    }
}

  • 测试

import com.zzu.AbstractFactory;
import com.zzu.AddOperation;
import com.zzu.Operation;
import com.zzu.factory.AddFactory;
import com.zzu.factory.DivFactory;
import com.zzu.factory.MutilFactory;

public class Test {
/*
实现11和2的四种运算操作
 */
    public static void main(String[] args) {
        //加法操作
        AbstractFactory addFactory = new AddFactory();
        Operation o1 = addFactory.create();
        o1.operation("11","2");
        //减法操作
        AbstractFactory subFactory = new AddFactory();
        Operation o2 = subFactory.create();
        o2.operation("11","2");
        //乘法操作
        AbstractFactory mutilFactory = new MutilFactory();
        Operation o3 = mutilFactory.create();
        o3.operation("11","2");
        //除法操作
        AbstractFactory divFactory = new DivFactory();
        Operation o4 = divFactory.create();
        o4.operation("11","2");
    }
}
  • 执行结果
    在这里插入图片描述
    也可以实现既定功能,但是其也存在一个问题,那就是每当我们要生产一个实例对象是,我们就需要创建 一个具体的实例工厂的对象,这样就造成类可能变的非常的多,其次,我们实例化一个具体的工厂时,都是使用new的方式进行,这样就写死在代码里,不利于维护,有没有可能可以通过配置文件来控制不同实例工厂的初始化?

抽象工厂+反射机制

import com.zzu.AbstractFactory;
import com.zzu.AddOperation;
import com.zzu.Operation;
import com.zzu.factory.AddFactory;
import com.zzu.factory.DivFactory;
import com.zzu.factory.MutilFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

public class Test {
/*
实现11和2的四种运算操作
 */
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException {
       
        //String name = "com.zzu.factory.AddFactory";
        Properties properties = new Properties();
        InputStream in = Object.class.getResourceAsStream("/configure.properties");
        //包装字节流,设置编码格式防止乱码
        InputStreamReader read  = new InputStreamReader(in,"UTF-8");
        //加载配置文件
        properties.load(read);
        //获取属性值
        String name = (String)properties.get("className");
        //通过反射机制拿到对应的类
        Class<?> c = Class.forName(name);
        //获取构造器
        Constructor<?> constructor = c.getConstructor();
        //获取实例化对象
        AbstractFactory factory  = (AbstractFactory) constructor.newInstance();
        //创建实例化工厂
        Operation o = factory.create();
        //调用工厂生产对象的方法
        o.operation("11","2");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值