上次实现了简单工厂模式,这次我们来学习工厂模式。
先看看工厂模式的代码实现,再来对比这两种工厂模式都有什么特点。
代码:
1 public class MyFactory2 { 2 public static void main(String[] args) { 3 Factory1 studentFactory1 = new StudentFactory1(); 4 Service studentFactory1Service = studentFactory1.getService(); 5 studentFactory1Service.insert(); 6 7 8 Factory1 teacherFactory1 = new TeacherFactory1(); 9 Service teacherFactory1Service = teacherFactory1.getService();10 teacherFactory1Service.delete();11 }12 }13 14 interface Service {15 void insert();16 17 void query();18 19 void delete();20 21 void update();22 }23 //实现接口24 class StudentService1 implements Service {25 26 @Override27 public void insert() {28 System.out.println("插入学生");29 }30 31 @Override32 public void query() {33 System.out.println("查询学生");34 }35 36 @Override37 public void delete() {38 System.out.println("删除学生");39 }40 41 @Override42 public void update() {43 System.out.println("更新学生");44 }45 }46 47 class TeacherService1 implements Service {48 49 @Override50 public void insert() {51 System.out.println("插入老师");52 }53 54 @Override55 public void query() {56 System.out.println("查询老师");57 }58 59 @Override60 public void delete() {61 System.out.println("删除老师");62 }63 64 @Override65 public void update() {66 System.out.println("更新老师");67 }68 }69 70 interface Factory1 {71 //方法属性,使用倚赖72 Service getService();73 }74 //实现接口75 class StudentFactory1 implements Factory1 {76 77 @Override78 public Service getService() {79 //局部变量,使用倚赖80 return new StudentService1();81 }82 }83 84 class TeacherFactory1 implements Factory1 {85 86 @Override87 public Service getService() {88 //局部变量,使用倚赖89 return new TeacherService1();90 }91 }
代码更长了
UML图:
(接口实现应该是虚线,更正下...)
简单工厂模式的UML图
我们可以看到两种模式最大的区别就是将工厂的实现:
新增工厂接口,再让具体的工厂实现工厂的接口
符合倚赖倒置原则(正置指的是倚赖实现类,倒置倚赖接口编程)
同时回一下简单工厂的客户端代码:
1 public static void main(String[] args) {2 //目标增加学生,删除员工,查询老师,更新老师3 MySimpleFactory mySimpleFactory = new MySimpleFactory();4 System.out.println(mySimpleFactory.getMyService(0).myAdd());5 System.out.println(mySimpleFactory.getMyService(1).myDelete());6 System.out.println(mySimpleFactory.getMyService(2).myQuery());7 System.out.println(mySimpleFactory.getMyService(3).myUpdate());8 }
工厂模式客户端代码
public static void main(String[] args) { Factory1 studentFactory1 = new StudentFactory1(); Service studentFactory1Service = studentFactory1.getService(); studentFactory1Service.insert(); Factory1 teacherFactory1 = new TeacherFactory1(); Service teacherFactory1Service = teacherFactory1.getService(); teacherFactory1Service.delete(); }
简单工厂模式:
1.实例化工厂
2.通过通用的工厂实例化操作对象
3.操作对象进行相应的操作
这个过程中是通过工厂的内部逻辑实现对操作对象的直接初始化。
工厂模式:
1.实例化工厂
2.通过具体的工厂实例化操作对象
3.操作对象进行相应的操作
通过对指定工厂的具体实例化,实现具体的操作对象(也约等于实例化对象)。
上一次说过了,我们写更多的代码。是为了修改和维护起来更加方便。我们来看看在什么后面的维护和修改中两个工厂模式有什么特点
第一个需求:现在我们加入一个员工的增删改查
简单工厂:
1员工service实现service
2工厂中在判断返回对象中新增一个返回员工service对象的 逻辑语句
到这里就可以看到弊端了,简单工厂模式需要修改代码,违反了开放封闭原则(对于新增是开放,对于修改是闭合的)
那么工厂模式需要怎么做呢,
1工厂模式实现员工的service
2增加员工操作对应的工厂模式
对于现有的代码不需要修改,遵守了开放封闭原则。
第二个需求把客户端的代码都改成员工的增删改查
public static void main(String[] args) { //目标增加学生,删除员工,查询老师,更新老师 MySimpleFactory mySimpleFactory = new MySimpleFactory(); System.out.println(mySimpleFactory.getMyService(4).myAdd()); System.out.println(mySimpleFactory.getMyService(4).myDelete()); System.out.println(mySimpleFactory.getMyService(4).myQuery()); System.out.println(mySimpleFactory.getMyService(4).myUpdate());}
刚刚所有的工厂传入的参数都需要修改,修改的代码相对较多
如果是工厂模式:
public static void main(String[] args) { Factory1 empolyeetFactory1 = new EmpolyeeFactory1(); Service empolyeetFactory1Service = empolyeetFactory1 .getService(); empolyeetFactory1Service .insert(); empolyeetFactory1Service .delete(); }
可以看到只需要修改具体的工厂实现修改即可,相比简单工厂模式需要修改的代码更少。
到这里就可以看到简单工厂和工厂模式的特点:
简单工厂模式把返回操作对象的逻辑封装在工厂中
而工厂模式将实例化具体操作对象(实例化那个操作对象的工厂)逻辑放在客户端
区别:
新增功能
简单工厂:需要修改工厂
工厂模式:无修改代码,新增代码即可
修改客户端操作对象
简单工厂:修改工厂传入参数
工厂模式:修改具体工厂的实例化对象
当然优缺点也就很明显了
简单工厂模式:代码简洁,工厂中含有必要的逻辑判断,客户只需要传入条件即可 适合于修改较小的项目
工厂模式:遵守倚赖倒置,职责单一,开放闭合,代码较多,但是需要在客户端对实例化对象进行判断 适合较多数情况
当然后面我们可以通过反射来避免分子判断的问题(动态的加载类对象)
没有最好的技术,只有最适合业务的解决方案。如果场景业务可以使用简单工厂模式,那就没有必要使用工厂模式。
补充:
当然最后我还想试试能让代码优雅点哈哈,当然觉得麻烦可以不用往下看了哈哈。
首先第一点,我想增删改查的确是大部分dao层操作必须的,但是也不是所有的类都需要这几种操作。
所以我想接口应该是4个接口,你有神马操作实现什么操作
public class MyFactory { public static void main(String[] args) { Factory studentFactory = new StudentFactory(); Insert studentFactoryInsertClass = studentFactory.getInsertClass(); studentFactoryInsertClass.insert(); Factory teacherFactory = new TeacherFactory(); Delete teacherFactoryDeleteClass = teacherFactory.getDeleteClass(); teacherFactoryDeleteClass.delete(); }}interface Insert { void insert();}interface Query { void query();}interface Delete { void delete();}interface Update { void update();}class StudentService implements Insert, Query, Delete, Update { @Override public void insert() { System.out.println("插入学生"); } @Override public void query() { System.out.println("查询学生"); } @Override public void delete() { System.out.println("删除学生"); } @Override public void update() { System.out.println("更新学生"); }}class TeacherService implements Insert, Query, Delete, Update { @Override public void insert() { System.out.println("插入老师"); } @Override public void query() { System.out.println("查询老师"); } @Override public void delete() { System.out.println("删除老师"); } @Override public void update() { System.out.println("更新老师"); }}interface Factory { Insert getInsertClass(); Query getQueryClass(); Delete getDeleteClass(); Update getUpdateClass();}class StudentFactory implements Factory { @Override public Insert getInsertClass() { return new StudentService(); } @Override public Query getQueryClass() { return new StudentService(); } @Override public Delete getDeleteClass() { return new StudentService(); } @Override public Update getUpdateClass() { return new StudentService(); }}class TeacherFactory implements Factory { @Override public Insert getInsertClass() { return new TeacherService(); } @Override public Query getQueryClass() { return new TeacherService(); } @Override public Delete getDeleteClass() { return new TeacherService(); } @Override public Update getUpdateClass() { return new TeacherService(); }}
UML
这样看起来就好一点了,还是有个大大的问题。就是我们每个工厂还是实现了4个方法,工厂应该和service的实现方式相同
再想想办法改进下
1 public class MyFactory3 { 2 public static void main(String[] args) { 3 Insert3Factory studentFactory3 = new StudentFactory3(); 4 Insert3 studentFactory3Insert = studentFactory3.getInsert(); 5 studentFactory3Insert.insert(); 6 7 Delete3Factory delete3Factory = new TeacherFactory3(); 8 Delete3 delete3FactoryDelete = delete3Factory.getDelete(); 9 delete3FactoryDelete.delete();10 }11 }12 13 interface Insert3 {14 void insert();15 }16 17 interface Query3 {18 void query();19 }20 21 interface Delete3 {22 void delete();23 }24 25 interface Update3 {26 void update();27 }28 29 class StudentService3 implements Insert3, Query3 {30 31 @Override32 public void insert() {33 System.out.println("插入学生");34 }35 36 @Override37 public void query() {38 System.out.println("查询学生");39 }40 }41 42 class TeacherService3 implements Delete3, Update3 {43 44 @Override45 public void delete() {46 System.out.println("删除老师");47 }48 49 @Override50 public void update() {51 System.out.println("更新老师");52 }53 }54 55 interface Insert3Factory {56 Insert3 getInsert();57 }58 59 interface Query3Factory {60 Query3 getQuery();61 }62 63 interface Delete3Factory {64 Delete3 getDelete();65 }66 67 interface Update3Factory {68 Update3 getUpdate();69 }70 71 class StudentFactory3 implements Insert3Factory, Query3Factory {72 73 @Override74 public Insert3 getInsert() {75 return new StudentService3();76 }77 78 @Override79 public Query3 getQuery() {80 return new StudentService3();81 }82 }83 84 class TeacherFactory3 implements Delete3Factory, Update3Factory {85 86 @Override87 public Delete3 getDelete() {88 return new TeacherService3();89 }90 91 @Override92 public Update3 getUpdate() {93 return new TeacherService3();94 }95 }
UML
哈哈哈哈哈到这里代码已经很长了,但是也算是达到了我想要的“面向对象”优雅实现(当然这样也可能不是最好的解决方案,如果你有更好的方案,欢迎留言哟)