【23种设计模式】工厂模式
程序员文章站
2022-06-04 23:16:13
...
- 这是一篇以代码为主的博客,没有那么多的定义和概念,希望能通过代码讲解来帮助你理解工厂模式
工厂模式对OOP的七大原则的体现
- 开闭原则:一个软件的实体应当对扩展开放,对修改关闭
- 依赖倒转原则:要针对接口变成,不要针对实现编程
- 迪米特原则:只与你直接的朋友通信,而避免和陌生人通信
工厂模式的作用
- 核心思想:实现了创建者和调用者的分离
- 核心本质:
- 实例化对象不使用new,用工厂方法代替
- 将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦
- 工厂模式分为三种:
- 简单工厂模式:用来生产统一等级结构中的任意产品(对于增加新的产品,需要修改已有代码)
- 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
- 抽象工厂模式:围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂
【 注意 】产品结构和产品族的定义:产品族内的产品是由同一个工厂生产出来的;产品结构指的是产品所处的类别。举个例子,小米生产小米手机和小米路由器,华为生产华为手机和华为路由器,那么小米路由器和华为路由器就处于同一个产品结构等级;小米手机和小米路由器就处于同一个产品族,同理,华为手机和华为路由器也是处于同一个产品族。
简单工厂模式
Car对象
public interface Car {
/**
* car name
*/
public void name();
}
-------------------------------------
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
-------------------------------------
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱宏光");
}
}
Consumer对象
package simple;
public class Consumer {
public static void main(String[] args) {
// 这是原来s获取car对象的样子
// 需要了解接口以及所有的实现类,如果你不知道这些就无法编码
// 面向对象编码就只需要你知道这是一个Car就够了,里面有什么不需要管
// 映射到现实生活中就是如果要买车,直接去买工厂已经做好的车就行了,不需要自己造一台车
// 但是这里却要自己new一个
Car car1 = new WuLing();
Car car2 = new Tesla();
car1.name();
car2.name();
}
}
CarFactory对象
- 使用简单工厂模式改造代码
package simple;
/**
* 简单工厂模式,也称静态工厂模式
* 里面的方法都是静态的,根据接收的不同的参数返回不同的对象实例
* 弊端:如果要增加一个产品,必须要修改代码
* 但是大部分情况下都是使用这个模式
* @author Hey
*/
public class CarFactory {
// 方法一:根据传入的参数判断需要的是什么然后就返回什么
public static Car getCar(String car){
if(car.equals("五菱")){
return new WuLing();
}else if(car.equals("特斯拉")){
return new Tesla();
}else{
return null;
}
}
// 方法二:根据自己的需要自己取得相应的车
public static Car getWuLing(){
return new WuLing();
}
public static Car getTesla(){
return new WuLing();
}
}
使用工厂方法之后的Consumer对象
package simple;
public class Consumer {
public static void main(String[] args) {
// 使用工厂创建的方式
// 就可以直接通过工厂获取,而不是自己创建
// 假设我们自己new一个Car需要要传入很多的参数
// 那么通过Car工厂的方式,我们就不需要再传入那么多的参数,直接在工厂里面配置即可
Car car3 = CarFactory.getCar("五菱");
//添加car3非空的断言
assert car3 != null;
car3.name();
// 但是这样做会导致使用不灵活
// 假设我们要新增一个车,那么我们就得更改车工厂里面的代码
// 这就违背了开闭原则
}
}
简单工厂模式小结
- 最开始的时候,我们在使用一个类的时候,我们需要自己去new一个类,需要去管实现的细节
- 有了简单工厂模式之后,我们只需要面对工厂,工厂里面的细节怎么实现的就不需要管了
工厂方法模式
- 简单工厂模式从设计原则上来看违背了开闭原则,如果要解决这个问题,我们可以直接建一个工厂的接口,然后通过实现工厂的接口来创建不同类型的工厂,这样我们就可以通过具体的工厂获取需要的实例对象
CarFactory接口
package method;
public interface CarFactory{
/**
* @return car
*/
Car getCar();
}
实现CarFactory接口
// WuLingFactory
public class WuLingFactory implements CarFactory{
@Override
public Car getCar() {
return new WuLing();
}
}
-----------------------------------------------------
// TeslaFactory
public class TeslaFactory implements CarFactory {
@Override
public Car getCar() {
return new Tesla();
}
}
-----------------------------------------------------
// 如果我们要增加一个车,可以直接通过创建一个新的Factory来实现
// MoBaiFactory
public class MoBaiFactory implements CarFactory {
@Override
public Car getCar() {
return new MoBai();
}
}
Consumer对象
public class Consumer {
public static void main(String[] args) {
Car car = new WuLingFactory().getCar();
Car car1 = new TeslaFactory().getCar();
// 此时当我们再需要拿到车时,就直接去到对应的工厂获取即可
car.name();
car1.name();
// 这个时候增加一个车
// 此时发现 扩展的时候并没有对原来的类进行修改,满足了开闭原则,但是也多了很多的类
// 这样每增加一个车,就会多一个工厂类,会越来越庞大
Car car2 = new MoBaiFactory().getCar();
car2.name();
}
}
简单工厂模式与工厂方法模式比较
工厂方法模式更符合设计原则,但是在实际应用的时候,会显得较为复杂,代码量也较大
- 从结构复杂度来看:两者比较,简单工厂模式更好
- 从代码复杂度来看:两者比较,简单工厂模式更好
- 从编程复杂度来看:两者比较,简单工厂模式更好
- 从管理复杂度来看:两者比较,简单工厂模式统一管理工厂的实现,会更好
- 根据设计原则,两者比较,工厂方法模式更优
- 根据实际业务,选择简单工厂模式的会更多
抽象工厂模式
小结
- 简单工厂模式(静态工厂模式):虽然某种程度上不符合设计原则,但是实际使用确实最多的!
- 工厂方法模式:不修改已有类的前提下,通过新增新的工厂类来实现扩展
- 抽象工厂模式:不可以增加产品,但是可以增加产品族!
应用场景
- JDK中
Calendar
的getInstance()
方法 - JDBC中的
Connection
对象的获取 - Spring中IOC容器创建管理
bean
对象 - 反射中Class对象的
newInstance()
方法