1. 简单工厂模式
简单工厂模式也称为静态工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。比如,我们一个车工厂,我们只要告诉他们我需要什么车(宝马、特斯拉),它就会给你生产一辆车,我们不需要关注车是怎么来的,只需要告诉它你的需求。
优点:
- 简单易于实现。
- 把类的实例化交给工厂,易于解耦。
缺点:
- 添加具体产品需要修改工厂违反 OCP 开放封闭原则(对外扩展开放,对修改关闭)。 ```java public interface Car { void name(); }
public class WuLing implements Car{ @Override public void name() { System.out.println(“五菱宏光”); } }
public class Tesla implements Car{ @Override public void name() { System.out.println(“特斯拉”); } }
public class CarFactory { public static Car getCar(String car) { if (Objects.equals(“五菱”, car)) { return new WuLing(); } else if (Objects.equals(“特斯拉”, car)) { return new Tesla(); } else if (Objects.equals(“大众”, car)) { return new DaZhong(); } else { return null; } } }
public class Consumer { public static void main(String[] args) { Car car1 = CarFactory.getCar(“五菱”); car1.name();
Car car2 = CarFactory.getCar("特斯拉");
car2.name();
}
}
---
<a name="r5lS2"></a>
# 2. 工厂方法模式
工厂方法模式,在不修改已有类的前提下,为每个产品提供一个工厂类,这些工厂类都实现了共同的接口,在客户端判断使用哪个工厂类来创建对象。如果我们要增加一个产品,需要在代码中添加对应的产品类和工厂类。<br />优点:
- 实现了开放封闭原则,每次添加子产品不需要修改原有代码,只需要创建相应的产品类和工厂类。
- 降低了代码耦合度。
缺点:
- 增加了代码量,每个具体产品都需要一个具体工厂。
- 当增加抽象产品,也就是添加一个其他产品族,需要修改工厂,违背了OCP。
```java
public interface CarFactory {
Car getCar();
}
public class WuLingFactory implements CarFactory{
@Override
public Car getCar() {
return new WuLing();
}
}
public class Consumer {
public static void main(String[] args) {
Car car1 = new WuLingFactory().getCar();
car1.name();
}
}
3. 抽象工厂模式
抽象工厂模式,可以理解为,当工厂只生产一个产品的时候,即为工厂方法模式,而工厂如果生产两个或以上的商品即变为抽象工厂模式。我们在抽象工厂接口中新增创建系统的方法,并由实例工厂类去实现。这个工厂称为超级工厂,不可以增加产品,可以增加产品族。
产品族:手机、路由就各是一个产品族。
产品等级:简单来说就是同一类产品,比如小米手机、华为手机等都是手机。
//手机产品接口
public interface IphoneProduct {
void start();
void shutdown();
void callup();
void sendMS();
}
//路由器产品接口
public interface IRouteProduct {
void start();
void shutdown();
void openWifi();
void setting();
}
//小米手机产品
public class XiaomiPhone implements IphoneProduct{
。。。
}
//小米工厂
public class XiaomiProductFactory implements IProductFactory{
@Override
public IphoneProduct iphoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouteProduct irouteProduct() {
return new XiaomiRouter();
}
}
//抽象产品工厂
public interface IProductFactory {
//生产手机
IphoneProduct iphoneProduct();
//生产路由器
IRouteProduct irouteProduct();
}
public class Client {
public static void main(String[] args) {
System.out.println("===============小米系列产品===========");
IphoneProduct xiaomiPhone = new XiaomiProductFactory().iphoneProduct();
xiaomiPhone.callup();
IRouteProduct xiaomiRouter = new XiaomiProductFactory().irouteProduct();
xiaomiRouter.openWifi();
}
}
原型图
4. 三者的区别
- 简单工厂模式:就是说你要什么产品,由对应的工厂创建(即 new 工厂对象调用方法返回对应的产品对象)。
- 优点:简单易于实现。
- 但添加产品需要修改工厂违反了 OCP 开闭原则。
- 工厂方法模式:就是说为每个产品提供一个工厂类,由客户端决定使用哪个工厂类创建产品。
- 优点:实现了开放封闭原则,每次添加子产品不需要修改原有代码,只需要创建相应的产品类和工厂类,降低了代码耦合度。
- 缺点:增加了代码量,并且当增加抽象产品,也就是添加一个其他产品族,需要修改工厂,违背了OCP。
- 抽象工厂模式:可以理解为,当工厂只生产一个产品的时候,即为工厂方法模式,而工厂如果生产两个或以上的商品即变为抽象工厂模式。我们在抽象工厂接口中新增创建系统的方法,并由实例工厂类去实现,不可以增加产品,可以增加产品族。(产品族:小米手机、小米路由器就是一个产品族)。
- 优点:具体产品在应用层的代码隔离,无需关心创建的细节,并且可以将一系列的产品统一到一起创建。
- 缺点:规定了所有可能被创建的产品集合,扩展产品族相当麻烦,而且扩展产品族会违反 OCP。
- 适用场景:客户端不依赖于产品类实例如何被创建、实现等细节;强调一系列相关的产品对象(属于同一产品族)一起适用创建对象需要大量的重复代码。
举例说明:比如说我们的超级工厂里实现了手机这个产品族,再增加个路由器产品族,我们需要定义一个路由器产品的接口,并通过某一种产品实现(比如小米路由器),并且还需要到小米工厂(实现了超级工厂)里去加上路由器的生产,即由小米工厂生产这个小米路由器。
5. 应用场景
工厂模式:
- JDBC 中的 Connection 对象的获取。
- 使用 mybatis 里面经常用到的
sqlSessionFactory.openSession(ExecutorType.BATCH);
,用的就是工厂模式,实际上用的是 Defaultsqlsession 里的 openSession 方法。 - Spring使用工厂模式可以通过 BeanFactory 或 ApplicationContext 创建 bean 对象。
单例模式:用于 Runtime,Calendar 和其他的一些类中。