1.工厂模式的作用
工厂模式的作用主要有以下几点:
-
封装对象创建:隐藏对象创建的复杂性,客户端只需调用工厂方法,而不必了解具体实现。
-
降低耦合度:客户端与具体产品类解耦,依赖接口或抽象类,便于维护和扩展。
-
确保产品一致性:在抽象工厂模式中,保证同一工厂创建的产品属于同一产品族,保持一致性。
-
增强扩展性:便于添加新产品类型,遵循开闭原则,不需修改现有代码。
-
集中管理创建过程:统一管理和控制对象创建,便于加入日志、监控等功能。
工厂模式使代码更加灵活、易于维护,并且支持系统的扩展和模块化设计。简单来说就是用来封装对象,便于维护和扩展,这里面涉及到一些设计原则,工厂模式主要涉及到单一职责原则、开闭原则、依赖倒转原则,这些原则我在此文章中会简单介绍,如果想要深入了解,可以关注点赞加收藏,后续我会在设计模式专栏中持续更新!
2.工厂模式的分类
工厂模式主要分为三类:
1. 简单工厂模式
- 定义:通过一个静态方法,根据传入的参数决定创建哪一种产品对象。
- 特点:不属于“设计模式”的正式分类,但常用。简化对象创建过程,适合简单场景。
- 缺点:不易扩展,增加新产品需要修改工厂类代码,违反开闭原则(对扩展开放,对修改关闭)。
2. 工厂方法模式
- 定义:定义一个用于创建对象的接口,由子类决定实例化哪一个具体产品类。
- 特点:将对象的创建推迟到子类进行,符合开闭原则,便于扩展。
- 优点:添加新产品时无需修改现有代码,只需增加新的具体工厂类。
- 缺点:增加了类的数量,复杂性较高。
3. 抽象工厂模式
- 定义:提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们的具体类。
- 特点:适用于创建产品族的情况,比如同一系列的不同产品(按钮、文本框等)。
- 优点:确保相关产品的一致性,易于扩展新的产品族。
- 缺点:添加新产品族时,所有工厂类都需要修改,增加了系统复杂性。
3.简单工厂模式
简单工厂的定义是:工厂根据客户端传的参数而返回不同的实例,返回的实例具有共同的父类或接口,此举满足了开闭原则。
由于只有一个工厂类,所以在工厂中创建的对象尽可能的少,不然容易造成逻辑复杂,代码臃肿,难以维护,其次,因为工厂封装了对象的创建过程,所以客户端不需要考虑对象创建的过程。
接下来,我全部以汽车为实例进行讲解:
首先,先定一个产品的共同行为接口。
//定一个产品拥有共同行为的接口
interface Car {
//汽车都能跑,这是一个汽车的共同行为
void run();
}
有很多人会疑问,我来学工厂模式,为什么还要定义产品的接口,多费事,多麻烦!因为在实现简单工厂模式的同时,我们还要保持设计原则之一的开闭原则,这样代码才具有健壮性。
其次,再去实现具体的产品:
//XiaoMiCar产品
public class XiaoMiCar implements Car {
//这里重写方法
@Override
public void run() {
System.out.printIn("小米汽车正在行驶中.....");
}
}
//比亚迪汽车产品
public class BydCar implements Car {
//重写方法
@Override
public void run() {
System.out.printIn("比亚迪汽车正在行驶.....");
}
}
然后,我们有个具体的产品,就要要工厂代替客户端去生产产品对吧,所以我们再定义一个工厂类,根据客户端传的参数返回不同的产品。
class SimpleFactory {
public static Car createCar(String type) {
if(type.equals("小米汽车")){
return new XiaoMiCar();
} else if(type.equals("比亚迪汽车")){
return new BydCar();
} else {
throw new IllegalArgumentException("没有你想要的汽车");
}
}
}
最后,客户端代码如下:
public class SimpleFactoryPatternDemo {
public static void main(String arg[]) {
Car xiaoMiCar = SimpleFactory.createCar("小米汽车");
xiaoMiCar.run();
Car bydCar = SimpleFactory.createCar("比亚迪汽车");
bydCar.run();
}
}
这样,就可以根据客户端不同的需求来创建不同的对象。
优点:只需要一个工厂创建对象,代码量少。
缺点:系统扩展困难,新增产品要修改工厂逻辑,当产品较多的时候,对造成工厂逻辑复杂,不易于 扩展。
4.工厂方法模式
工厂方法模式是简单工厂的仅一步深化,在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。每个对象都有一个与之对应的工厂。
有了前面的基础,我直接上代码!
首先,还是和前面一样,先定义一个产品接口:
//定一个产品拥有共同行为的接口
interface Car {
//汽车都能跑,这是一个汽车的共同行为
void run();
}
其次,定义具体的产品:
//XiaoMiCar产品
public class XiaoMiCar implements Car {
//这里重写方法
@Override
public void run() {
System.out.printIn("小米汽车正在行驶中.....");
}
}
//比亚迪汽车产品
public class BydCar implements Car {
//重写方法
@Override
public void run() {
System.out.printIn("比亚迪汽车正在行驶.....");
}
}
然后,这一步就有所不同,前面的简单工厂是在这一步直接创建了一个工厂的大工厂,而这里,我前面讲过,每个具体的产品要有自己的工厂,但是这里我们先不急创建工厂,我们要先创建一个所有工厂的共同父类接口,这里的原理和所有具体产品都有一个共同的产品接口是一样,也要满足开闭原则。不写也行的,但这样就是典型的对代码不负责任,最终成为屎山代码!!!
interface CarFactory {
Car getCar();
}
紧接着,我们来实现一对一的工厂类:
先是小米汽车工厂
class XiaoMiCarFactory implements CarFactory {
@Override
public Car getCar(){
return new XiaoMiCar();
}
}
然后是比亚迪汽车工厂
class BydCarFactory implements CarFactory {
@Override
public Car getCar(){
return new BydCar();
}
}
最后客户端指定工厂来返回具体实例:
CarFactory factory = new XiaoMiCarFactory();
Car xiaoMiCar = factory.getCar();
xiaoMiCar.run();
和简单工厂相比,最根本的区别在于简单工厂是一个大工厂,工厂方法模式是一个个具体的工厂,专人专事。其中,这些工厂也实现了一个基类也就是CarFactory
优点:新增产品类不需要修改现有的代码,直接增加新产品和新工厂就好,然后继承工厂基类。
5.抽象工厂模式
抽象工厂模式它提供一个接口,用于创建一系列相关或互相依赖的对象,而无需指定它们的具体类。通过这个模式,可以确保同一系列的对象在一起使用时是兼容的,并且在需要扩展新的产品系列时,不需要修改现有代码。可以这么理解,就是工厂方法模式的复数形式,哈哈哈哈哈,我是这样理解的。看一下他的作用就明白了
作用:
- 产品族的管理:抽象工厂模式用于创建一系列相关联的产品(如按钮、文本框、复选框等),并保证这些产品在一起使用时的一致性。
- 提高系统的可扩展性:通过扩展新的具体工厂类,可以轻松添加新的产品族,而无需修改现有代码。
假设你有两个产品族:Windows
和 MacOS
,它们各自包含 Button
和 Checkbox
两种产品。
// 抽象产品接口
interface Button {
void click();
}
interface Checkbox {
void check();
}
// 具体产品类
class WindowsButton implements Button {
@Override
public void click() {
System.out.println("Windows Button clicked");
}
}
class MacOSButton implements Button {
@Override
public void click() {
System.out.println("MacOS Button clicked");
}
}
class WindowsCheckbox implements Checkbox {
@Override
public void check() {
System.out.println("Windows Checkbox checked");
}
}
class MacOSCheckbox implements Checkbox {
@Override
public void check() {
System.out.println("MacOS Checkbox checked");
}
}
// 抽象工厂接口
interface UIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 具体工厂类
class WindowsFactory implements UIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
class MacOSFactory implements UIFactory {
@Override
public Button createButton() {
return new MacOSButton();
}
@Override
public Checkbox createCheckbox() {
return new MacOSCheckbox();
}
}
// 客户端代码
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
UIFactory factory = new WindowsFactory(); // 可替换为 MacOSFactory
Button button = factory.createButton();
Checkbox checkbox = factory.createCheckbox();
button.click(); // 输出: Windows Button clicked
checkbox.check(); // 输出: Windows Checkbox checked
}
}
适用场景:
- 和工厂方法一样客户端不需要知道它所创建的对象的类。
- 需要一组对象共同完成某种功能时。并且可能存在多组对象完成不同功能的情况。
- 系统结构稳定,不会频繁的增加对象。(因为一旦增加就需要修改原有代码,不符合开闭原则)
至此,工厂模式就完结了,文章中涉及到许多设计原则,这些原则,我会明天更新在设计模式的专栏当中,其他的设计模式我也会后续一天一更,尽可能的快的总结!感谢大家支持!