java三种工厂模式:简单工厂、工厂方法、抽象工厂
2017-07-11 10:34
633 查看
简单工厂
简单工厂模式又 叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。我们从一个实例展开
现在有一道面试题:使用java实现一个计算机控制台程序,要求输入数的运算,得到结果。
这道题目最原始的写法:
public class Computer { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("请输入第一个数字:"); float firstNum = in.nextFloat(); System.out.println("请输入第二个数字:"); float secondNum = in.nextFloat(); System.out.println("请输入运算符号:"); String countQuato = in.next(); if("+".equals(countQuato)){ System.out.println("result : "+(firstNum+secondNum)); }else if("-".equals(countQuato)){ System.out.println("result : "+(firstNum-secondNum)); }else if("*".equals(countQuato)){ System.out.println("result : "+(firstNum*secondNum)); }else if("/".equals(countQuato)){ System.out.println("result : "+(firstNum/secondNum)); } }
上面的写法实现虽然简单,但是却没有面向对象的特性,代码拓展性差,显然不是出题者想要考察的意图。
那么面向对象编程要如何在题中体现呢?
在面向对象编程语言中,一切都是对象,所以上面运算符号也应当作对象来处理。
我们首先建立一个接口
public abstract class Operation { public abstract float getResult(float firstNumber, float secondNumber); } //把符号都当做对象处理,实现此接口 public class AddOperation extends Operation { @Override public float getResult(float firstNumber, float secondNumber) { return firstNumber+secondNumber; } } public class SubOperation extends Operation { @Override public float getResult(float firstNumber, float secondNumber) { return firstNumber-secondNumber; } } public class MulOperation extends Operation { @Override public float getResult(float firstNumber, float secondNumber) { return firstNumber*secondNumber; } } public class DivOperation extends Operation { @Override public float getResult(float firstNumber, float secondNumber) { return firstNumber/secondNumber; } } //接下来需要解决的就是对象的创建问题了,既如何根据不同的情况创建不同的对象:我们正好可以通过简单工厂模式实现 public class OperationFactory { public static Operation getOperation(String quotaFlag){ Operation o = null; switch (quotaFlag){ case "+" : o = new AddOperation(); case "-" : o = new SubOperation(); case "*" : o = new MulOperation(); case "/" : o = new DivOperation(); default:break; } return o; } } //调用: public class Computer { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("请输入第一个数字:"); float firstNum = in.nextFloat(); System.out.println("请输入第二个数字:"); float secondNum = in.nextFloat(); System.out.println("请输入运算符号:"); String countQuato = in.next(); System.out.println(count(firstNum,secondNum,countQuato)); } private static float count(float firstNum,float secondNum , String countQuota){ //通过工厂类获取对象 Operation operation = OperationFactory.getOperation(countQuota); return operation.getResult(firstNum,secondNum); } }
简单工厂将对象的创建过程进行了封装,用户不需要知道具体的创建过程,只需要调用工厂类获取对象即可。
这种简单工厂的写法是通过switch-case来判断对象创建过程的。在实际使用过程中,违背了 开放-关闭原则,当然有些情况下可以通过反射调用来弥补这种不足。
工厂方法
工厂方法 定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到了子类工厂方法在简单工厂的基础上再包了一层工厂,所有的工厂都是此工厂的子类。而产生对象的类型由子类工厂决定。使用工厂方法来实现上面的加减乘除对象的创建
//定义上级工厂的接口 public interface IFractory { public Operation generateOper(); } //为每一个类创建工厂 /** * 工厂方法 为每个对象生成一个工厂类 */ public class AddOperationFactory implements IFractory{ @Override public Operation generateOper() { return new AddOperation(); } } public class SubOperationFactory implements IFractory { @Override public Operation generateOper() { return new SubOperation(); } } public class MulOperationFactory implements IFractory { @Override public Operation generateOper() { return new MulOperation(); } } public class DivOperationFactory implements IFractory { @Override public Operation generateOper() { return new DivOperation(); } } //客户端代码 IFractory fractory = new AddOperationFactory(); Operation operation = fractory.generateOper(); operation.getResult(firstNum,secondNum);
工厂方法将类的实例化推迟到了其子类。所以使用工厂方法模式时,需要客户端决定实例化哪一个工厂类。选择判断问题还是存在的。也就是说,工厂方法把简单的工厂内部逻辑判断转移到了客户端来运行。你想要加的功能,本来是要改工厂类的,而现在是修改客户端。不过,我们在某些情况下通过工厂方法,只需要修改一行实例化的代码就可以实现系统元素的切换(比如切换数据源)。这也是很方便的。
抽象工厂
提供一个创建一系列相关相互依赖对象的接口,而无需指定他们具体的类。抽象工厂为不同产品族的对象创建提供接口。使用场景:系统需要在不同产品族进行切换
代码实现:
public interface IFacfory { public IUser createUser(); public IDepartment createDepartment(); } public interface IUser { public void insert(); public void getById(); } public interface IDepartment { public void insert(); public void getDepartmentById(); } public class SqlServerUser implements IUser { @Override public void insert() { System.out.println("insert into sqlserver."); } @Override public void getById() { System.out.println("get user by id from sqlserver."); } } public class SqlServerDepartment implements IDepartment { @Override public void insert() { System.out.println("insert department into sqlserver."); } @Override public void getDepartmentById() { System.out.println("get department in sqlserver by id."); } } public class AccessUser implements IUser { @Override public void insert() { System.out.println("insert into access"); } @Override public void getById() { System.out.println("get by id from access"); } } public class AccessDepartment implements IDepartment { @Override public void insert() { System.out.println("insert department into sqlserver."); } @Override public void getDepartmentById() { System.out.println("get department in sqlserver by id."); } } //不同产品组使用一个工厂 public class SqlServerFactory implements IFacfory { @Override public IUser createUser() { return new SqlServerUser(); } @Override public IDepartment createDepartment() { return new SqlServerDepartment(); } } public class AccessFactory implements IFacfory { @Override public IUser createUser() { return new AccessUser(); } @Override public IDepartment createDepartment() { return new AccessDepartment(); } } 客户端: IFacfory facfory = new AccessFactory(); IUser user = facfory.createUser(); IDepartment department = facfory.createDepartment(); user.insert(); user.getById(); department.insert(); department.getDepartmentById();
抽象工厂最大的好处就是便于交换产品系列,具体工厂在代码中一般只出现一次。这就使得改变应用的具体工厂很容易。
第二个好处是他能让具体的创建对象实例和客户端分离,客户端是通过他们的抽象接口操作实例
抽象工厂不太易于拓展,如果需要自增功能,或者自增产品,则需要至少修改三个类,而且实例化的代码是写死在程序中的 , 这样无法避免违背开放-关闭原则。
对于上述问题,可以通过配置文件,结合反射的方式来解决。在这里就不再啰嗦
相关文章推荐
- Java设计模式之简单工厂、工厂方法和抽象工厂
- java设计模式之工厂模式(简单工厂,工厂方法,抽象工厂)
- 三种工厂设计模式 分别是:简单工厂设计模式、抽象工厂方法设计模式、工厂方法设计模式
- 设计模式:浅析 抽象工厂、工厂方法、简单(静态)工厂 java实现
- Java设计模式之工厂模式分析【简单工厂、工厂方法、抽象工厂】
- 设计模式之三种工厂模式总结(简单工厂、工厂方法、抽象工厂)
- 设计模式:浅析 抽象工厂、工厂方法、简单(静态)工厂 java实现
- Java设计模式之简单工厂、工厂方法和抽象工厂
- Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)
- Java设计模式之工厂模式(简单工厂、工厂方法、抽象工厂)
- 简单工厂,工厂方法,抽象工厂 三种设计模式的区别和实例
- java中简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别
- 设计模式-简单工厂、工厂方法与抽象工厂
- 简单工厂,Factory Method(工厂方法)和Abstract Factory(抽象工厂)模式
- 简单工厂,Factory Method(工厂方法)和Abstract Factory(抽象工厂)模式
- 重头开始学23种设计模式:三大工厂(简单工厂,工厂方法,抽象工厂)
- 简单工厂、工厂方法和抽象工厂设计模式
- java设计模式——工厂方法与抽象工厂方法
- Java设计模式----------简单工厂类+工厂方法(FactoryMethod)
- 简单工厂-工厂方法-抽象工厂对比,给出理解思路和Java参考案例源码