工厂模式
Posted gang-bryant
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工厂模式相关的知识,希望对你有一定的参考价值。
上次实现了简单工厂模式,这次我们来学习工厂模式。
先看看工厂模式的代码实现,再来对比这两种工厂模式都有什么特点。
代码:
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 @Override 27 public void insert() { 28 System.out.println("插入学生"); 29 } 30 31 @Override 32 public void query() { 33 System.out.println("查询学生"); 34 } 35 36 @Override 37 public void delete() { 38 System.out.println("删除学生"); 39 } 40 41 @Override 42 public void update() { 43 System.out.println("更新学生"); 44 } 45 } 46 47 class TeacherService1 implements Service { 48 49 @Override 50 public void insert() { 51 System.out.println("插入老师"); 52 } 53 54 @Override 55 public void query() { 56 System.out.println("查询老师"); 57 } 58 59 @Override 60 public void delete() { 61 System.out.println("删除老师"); 62 } 63 64 @Override 65 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 @Override 78 public Service getService() { 79 //局部变量,使用倚赖 80 return new StudentService1(); 81 } 82 } 83 84 class TeacherFactory1 implements Factory1 { 85 86 @Override 87 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 @Override 32 public void insert() { 33 System.out.println("插入学生"); 34 } 35 36 @Override 37 public void query() { 38 System.out.println("查询学生"); 39 } 40 } 41 42 class TeacherService3 implements Delete3, Update3 { 43 44 @Override 45 public void delete() { 46 System.out.println("删除老师"); 47 } 48 49 @Override 50 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 @Override 74 public Insert3 getInsert() { 75 return new StudentService3(); 76 } 77 78 @Override 79 public Query3 getQuery() { 80 return new StudentService3(); 81 } 82 } 83 84 class TeacherFactory3 implements Delete3Factory, Update3Factory { 85 86 @Override 87 public Delete3 getDelete() { 88 return new TeacherService3(); 89 } 90 91 @Override 92 public Update3 getUpdate() { 93 return new TeacherService3(); 94 } 95 }
UML
哈哈哈哈哈到这里代码已经很长了,但是也算是达到了我想要的“面向对象”优雅实现(当然这样也可能不是最好的解决方案,如果你有更好的方案,欢迎留言哟)
以上是关于工厂模式的主要内容,如果未能解决你的问题,请参考以下文章
设计模式简单工厂模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )