简单工厂模式
来源:互联网 发布:穆斯林党员 知乎 编辑:程序博客网 时间:2024/06/15 21:20
还是拿《大话设计模式》里面的例子来说,设计一个计算器,能够计算加减乘除。根据面向对象的思想(第一个demo只用到了封装,后面一个用到了封装、继承、多态),我们可以抽取一个计算类能根据输入的数字a,运算符,数字b进行运算。
public class Operation { /** * 进行加减乘除运算 */ public static double operate(int numberA,int numberB,String symbol){ double result = 0; switch (symbol) { case "+": result = numberA + numberB; break; case "-": result = numberA - numberB; break; case "*": result = numberA * numberB; break; case "/": result = numberA / numberB; break; default: break; } return result; }}
客户端代码
public class Client { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入运算:"); String line = scanner.nextLine(); String[] strs = line.split(" "); double result = Operation.operate(Integer.parseInt(strs[0]), Integer.parseInt(strs[2]), strs[1]); System.out.println("计算结果:" + result); scanner.close();// 请输入运算,空格分开:// 3 + 5// 计算结果:8.0 }}
但是如果哪一天要修改计算的加法呢,或者增加求与运算,那么不就得修改Operation类吗,而实际我们只需要修改一个运算,决不能影响其他运算,甚至应该是个个运算相互隔离不知道对方的存在,否则修改时可能不小心对其他运算造成影响。
所以我们可以分离出4个类(加减乘除运算类)都继承自同一个运算类,各司其职。
public abstract class Operation { protected int numberA; protected int numberB; public abstract double operate(); get,set方法}
/** * 加法运算类 * @author 12706 * */public class AddOperation extends Operation{ @Override public double operate() { System.out.println("正在进行加法运算..."); double result= numberA+numberB; return result; }}
/** * 减法运算类 * @author 12706 * */public class SubOperation extends Operation{ @Override public double operate() { System.out.println("正在进行减法运算..."); return numberA-numberB; }}
/** * 乘法运算类 * @author 12706 * */public class MulOperation extends Operation{ @Override public double operate() { System.out.println("正在进行乘法运算..."); return numberA*numberB; }}
/** * 除法运算类 * @author 12706 */public class DivOperation extends Operation{ //只取小数点前面 @Override public double operate() { if (numberB == 0){ throw new RuntimeException("被除数不能为0"); } //BigDecimal decimal = new BigDecimal(numberA).divide(new BigDecimal(numberB)); System.out.println("正在进行除法运算..."); return numberA/numberB; }}
客户端代码
public class Client { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); //要求不能乱输 System.out.println("请输入运算,空格分开:"); String line = scanner.nextLine(); String[] strs = line.split(" "); Operation operation = null; //判断实例化谁 switch (strs[1]) { case "+": operation = new AddOperation(); break; case "-": operation = new SubOperation(); break; case "*": operation = new MulOperation(); break; case "/": operation = new DivOperation(); break; default: break; } operation.setNumberA(Integer.parseInt(strs[0])); operation.setNumberB(Integer.parseInt(strs[2])); System.out.println("计算结果:" + operation.operate()); scanner.close(); }}
但是到这里又得考虑一点,实例化哪个运算类这里成了客户端判断,客户端应该负责给运算而不应该做判断啊,所以实例由谁创建就可以引出简单工厂模式了。
到底由谁创建对象,只需要客户端给出运算符,工厂会给我们返回要创建的对象。
public class OperationFactory { /** * 根据运算符返回对应对象 * @param symbol 运算符 * @return */ public static Operation getOperation(String symbol){ Operation operation = null; switch (symbol) { case "+": operation = new AddOperation(); break; case "-": operation = new SubOperation(); break; case "*": operation = new MulOperation(); break; case "/": operation = new DivOperation(); break; default: break; } return operation; }}
客户端代码
public class Client { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); //要求不能乱输 System.out.println("请输入运算,空格分开:"); String line = scanner.nextLine(); String[] strs = line.split(" "); //根据运算符获取需要的对象 Operation operation = OperationFactory.getOperation(strs[1]); operation.setNumberA(Integer.parseInt(strs[0])); operation.setNumberB(Integer.parseInt(strs[2])); double res = operation.operate(); System.out.println(res); scanner.close(); }}
为了理解更清晰下面给出老公爱红牛的例子。工厂生产汽车的例子
public interface Car { public void introduce();}
public class FordCar implements Car{ @Override public void introduce() { System.out.println("我是福特..."); }}
public class HondaCar implements Car{ @Override public void introduce() { System.out.println("我是东风..."); }}
public class BenzCar implements Car{ @Override public void introduce() { System.out.println("我是奔驰..."); } }
工厂类,根据品牌名生产汽车
这里用if实现(跟which一样)
public class CarFactory { public static Car getInstance(String brand){ if(brand.equals("benz")){ return new BenzCar(); }else if (brand.equals("honda")) { return new HondaCar(); }else if (brand.equals("ford")) { return new FordCar(); }else { return new HondaCar(); } }}
客户端代码
public class Client { public static void main(String[] args) { Car ford = CarFactory.getInstance("ford"); ford.introduce(); Car honda = CarFactory.getInstance("honda"); honda.introduce(); Car benz = CarFactory.getInstance("benz"); benz.introduce(); }}
输出
我是福特...我是东风...我是奔驰...
注:其实能看到简单工厂模式是有明显的不足的,因为如果增加了汽车类那我们还得继续else if判断,那就是要修改原来的代码了,虽然不影响原来的汽车类,但是根本不满足开发-封闭原则不易于维护拓展。后面会介绍使用反射来解决这个问题。下面先给出反射用的代码吧
public class CarFoctory2 { //不让别人创建对象 private CarFoctory2(){} private static Properties config = new Properties(); static{ try { config.load(CarFoctory2.class.getResourceAsStream("car.properties")); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } public static Car newCar() throws Exception{ String className = config.getProperty("Car"); Class clazz = Class.forName(className); //局限性:要求该类有无参的构造方法,所以有了抽象工厂方法 Car car = (Car)clazz.newInstance(); return car; }}
配置文件car.properties内容如下
根据需要来改变配置文件的Car类
Car=com.scu.design2.simplefactory.FordCar
阅读全文
0 0
- 工厂模式-简单工厂
- 工厂模式-简单工厂
- 工厂模式-简单工厂模式
- 工厂模式-简单工厂模式
- 简单工厂模式,工厂模式
- 工厂模式-简单工厂模式
- 简单工厂模式,工厂模式
- 简单工厂、工厂模式、抽象工厂模式
- 简单工厂、工厂模式、抽象工厂模式
- 简单工厂&工厂模式&抽象工厂模式
- 简单工厂和工厂模式
- 简单工厂和工厂模式
- 1,工厂模式--简单工厂
- 简单工厂和工厂模式
- 简单工厂,工厂模式,抽象工厂
- 简单工厂,工厂模式,抽象工厂
- 简单工厂、工厂方法、抽象工厂模式
- 简单工厂、工厂模式和抽象工厂
- js高性能编码
- 根据pandas和matplotlib制作简单的图表
- 【数据库-Oracle】日期-时间 语法
- Spring Boot Servlet
- 深入理解SELinux SEAndroid(第一部分)
- 简单工厂模式
- 微信小程序 —— web-view组件配置及使用
- 日常问题总结(12)
- JS中的基本数据类型和引用数据类型
- 通常ERP之:物料需求计划MRP与主生产计划
- Python每日小结(七)
- layer 弹层WEB
- JS window.open打开新窗口,并居中
- 【转载】Python函数参数默认值的陷阱和原理深究