针对实体user,希望写一系列的功能,能够实现数据库的增删改查等功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void main (String[] args) { User u = new User(); u.setName("methol" ); add(u); edit(u); } public static void add (User user) { System.out.println("save user【" + user.getName() + "】 to db" ); } public static void edit (User user) { System.out.println("edit user【" + user.getName() + "】, and save to db" ); }
上面的方法虽然基本上实现了功能,但是不利于程序以后的扩展和复用,代码也不容易维护。 通过封装、继承、多态把程序的耦合度降低,使用设计模式可以使得程序更加灵活,后期容易修改,也更加易于复用。 有了如下的代码:
1 2 3 4 5 6 7 8 9 package mode.factory.simple; import mode.factory.bean.User; public interface Operation { void operate(User user); }
1 2 3 4 5 6 7 8 9 10 11 12 package mode.factory.simple; import mode.factory.bean.User; public class AddOperate implements Operation { @Override public void operate(User user) { System.out.println("save user【" + user.getName() + "】 to db"); } }
1 2 3 4 5 6 7 8 9 10 11 package mode.factory.simple; import mode.factory.bean.User; public class EditOperate implements Operation { @Override public void operate(User user) { System.out.println("edit user【" + user.getName() + "】, and save to db"); } }
1 2 3 4 5 6 7 8 9 10 public static void main(String[] args) { User u = new User(); u.setName("methol"); // 不同的操作需要new不同的类操作 Operation addOperate = new AddOperate(); addOperate.operate(u); Operation editOperate = new EditOperate(); editOperate.operate(u); }
上述代码已经经过封装,并且也适合之后的代码扩展,但是还是有一个问题,如果后期想通过不同的参数(事先不知道是要执行edit还是add),那么就要通过条件判断要做的操作,这时简单工厂模式可能就是一个比较好的选择。
简单工厂模式与工厂模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package mode.factory.simple; public class OperateFactory { public static Operation findOperation(String operation) { switch (operation) { case "add": return new AddOperate(); case "edit": return new EditOperate(); default: return null; } } }
通过工厂类来帮我们new一个对象,而不是直接在代码中需要的地方new一个对象,在同一个地方管理,后期的代码维护和扩展性都强了很多。 或者这时想增加一个delete方法,只需要继承Operation
类,写一个方法,然后在OperateFactory
增加一个case即可。简单工厂模式 ,就是一个简单的创建产品(Operation
)的工具,可以是AddOperate
类,也可以是EditOperate
类,甚至他们之间没有任何关系也是没问题的。工厂模式 ,他也是一个简单的创建产品(Operation
)的工具,但是他有一个区别是所有的产品(AddOperate
,EditOperate
)都是继承(实现)Operation
这个父类的,父类中有抽象的方法,之后都是调用同一个方法来做操作。 使用中,很少使用简单工厂模式,大多都是工厂模式,谈到工厂模式,基本上都是指的工厂模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public static void main (String[] args) { User u = new User(); u.setName("methol" ); Operation addOperate = new AddOperate(); addOperate.operate(u); Operation editOperate = new EditOperate(); editOperate.operate(u); OperateFactory.findOperation("add" ).operate(u); OperateFactory.findOperation("edit" ).operate(u); }
工厂方法 对Operation
做了一些小的修改,增加了一个方法
1 2 3 4 5 6 public interface Operation { void operate(User user); Operation createDefault(String operationType); }
1 2 3 4 5 6 7 8 9 10 11 12 public class AddOperate implements Operation { @Override public void operate(User user) { System.out.println("save user【" + user.getName() + "】 to db"); } @Override public Operation createDefault(String operationType) { return OperateFactory.findOperation(operationType); } }
1 2 3 4 5 6 7 8 9 10 11 12 public class EditOperate implements Operation { @Override public void operate(User user) { System.out.println("edit user【" + user.getName() + "】, and save to db"); } @Override public Operation createDefault(String operationType) { return OperateFactory.findOperation(operationType); } }
工厂方法主要系是两个元素,产品(Operation
)和创建者(OperateFactory
)。 而工厂方法就是一个创建者这个类的一个方法而已,这个方法就是用来封装产品的创建。 和工厂模式的区别是,工厂模式的最大优点在于工厂类中包含了逻辑判断,根据(客户端)传入的参数动态实例化相关的类,那么对于客户端来说,他是不需要关心产品(Operation
)的,他只需要关心传入的参数。而工厂模式这时把这一动作延后,接口定义了一个用来创建对象的接口,让子类决定实例化哪个类,工厂方法使一个类的实例化过程延迟到其子类。
抽象工厂 抽象工厂,顾名思义,就是对工厂进行抽象。 工厂方法和工厂模式都是对产品抽象封装,通过一个工厂,生产多种产品。 抽象工厂就是通过不同的工厂生产不同的产品。 还是上面的例子,OperateFactory
创建了新增和修改两种操作(产品),此时有一个新的需求来了,之前用的数据库使mysql,现在想改成oracle,此时就对OperateFactory进行抽象。
1 2 3 4 5 6 7 8 9 10 11 12 13 package mode.factory.abstracs; import mode.factory.bean.User; import mode.factory.simple.Operation; public interface Factory { void add(User user); void edit(User user); Operation createDefault(String operationType); }
接口申明了,不管是申明工厂,都需要有add和edit这两种产品的生产。不同的接口只需要实现这个接口,做自己的操作即可。同时不同的工厂还可以实现自己独有的产品的生产。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mode.factory.abstracs; import mode.factory.bean.User; import mode.factory.simple.Operation; public class MysqlOperateFactory implements Factory { @Override public void add(User user) { createDefault("add").operate(user); } @Override public void edit(User user) { createDefault("edit").operate(user); } @Override public Operation createDefault(String operationType) { return new MysqlOperate().findOperation(operationType); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mode.factory.abstracs; import mode.factory.bean.User; import mode.factory.simple.Operation; public class OracleOperateFactory implements Factory { @Override public void add(User user) { createDefault("add").operate(user); } @Override public void edit(User user) { createDefault("edit").operate(user); } @Override public Operation createDefault(String operationType) { return new OracleOperate().findOperation(operationType); } }
这里也用了工厂方法的思想,抽象工厂的模式实现了工厂线的扩展。
小结 工厂模式就是一个类,它用来根据客户端(参数)具体的实例化某个对象。 工厂方法也是实例化对象,但是他把这个过程延迟到了子类,由子类决定具体实例化哪个对象。 抽象工厂是对工厂的扩展。他是在工厂方法的上面做的进一步的抽象。 工厂模式是用来生产产品的,不能增加产品;工厂方法是用来生产产品,同时也可以增加产品(实现接口,增加产品);抽象工厂用来增加工厂的,他不能增加产品。