工厂模式属于创建对象的模式。将对象的创建交给工厂进行,这样我们在创建对象时不会对客户端直接暴露创建逻辑,而是 通过使用一个共同的接口根据不同的条件来指向具体想要创建的对象。
最明显的就是降低了对象之间的耦合问题。spring 中的 ioc 就采用了工厂模式来创建对象。
这里通过传统开发和使用工厂模式做个对比:
创建一个接口:
public interface UserService {
public void sayHello();
}
创建实现接口的实体类:
public class UserServiceImpl implements UserService {
public void sayHello() {
System.out.println("hello wolrd");
}
}
传统开发
那么我们如何获得该实体类的对象呢,最简单的就是 new 一个 UserServiceImpl 对象:
客户端代码如下:
public class Test {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.sayHello();
}
}
这里 Test 类和 UserServiceImpl 类就存在耦合,如果需要添加新功能(如 UserServiceImpl 类中添加属性或增加新的类),那么我们的客户端类就需要修改原来的类或者 new 新类。 如果实现的功能很多,就相当于我们将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,这样是很危险的,如果将来代码量大了,非常不利于我们维护。
我们写代码的时候应该遵循 OCP原则
OCP原则:open-close 原则,对程序扩展是 open 的,对修改程序代码是 close。 尽量做到不修改程序的源码,实现对程序的扩展。
如果我们这里创建 Factory 类来创建对象,提供接口给 Test 类调用,这样耦合关系虽然变成了 Test 类和 Factory类,Factory类和 UserServiceImpl 类,但 Test类 和 UserServiceImpl 就不存在耦合了。以后我们需要扩展功能就直接在工厂类中创建好对象,再让客户端类调用就行了。
创建一个工厂,生成基于给定信息的实体类的对象。:
public class Factory() {
// 使用 getUs 方法来获得 UserServiceImpl 对象
public UserService getUs() {
return new UserServiceImpl();
}
}
使用该工厂,通过传递类型信息来获取实体类的对象:
public class Test {
public static void main(String[] args) {
Factory factory = new Factory();
//获得 UserServiceImpl 的对象,并调用它的 sayHello 方法
UserService userService = factory.getUs();
userService.sayHello();
}
}
这样,在整个就不涉及到 UserService 的具体的实现类,达到封装效果,也就减少错误修改的机会。
使用工厂模式将对象的创建交给工厂类进行,很好的降低了代码的耦合度,提供接口给实现方调用,增加了程序的可扩展性。
具体步骤: