java 设计模式 工厂模式
什么是工厂模式
工厂模式(Factory Pattern)是一种创建型设计模式,它通过定义一个接口或抽象类来创建对象,但由子类决定具体实例化哪个类。简单来说,工厂模式将对象的实例化过程封装起来,客户端通过工厂方法来创建对象,而不需要直接使用 new 关键字。
工厂模式的目的是将对象的创建和使用解耦,使得客户端代码不需要关心具体对象的创建过程,尤其是对象的构造方式或者具体类型。
工厂模式的作用
- 解耦:客户端代码与具体的对象创建解耦,客户端只需要依赖工厂接口而不依赖具体的实现类。
- 代码重用:工厂方法可以提供统一的创建对象的逻辑,从而避免重复代码。
- 更好的扩展性:如果系统中需要新增不同的产品类,只需要添加新的工厂类即可,不需要修改原有的客户端代码。
- 灵活的对象管理:有些工厂模式可以实现对象的缓存或对象池,从而优化性能。
示例
不使用工厂模式获取实例
// 抽象产品:Button(按钮)
interface Button {
void render();
}
// 具体产品:WindowsButton(Windows 按钮)
class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Windows Button");
}
}
// 具体产品:MacButton(Mac 按钮)
class MacButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Mac Button");
}
}
// 客户端代码:根据操作系统类型选择不同按钮
public class Main {
public static void main(String[] args) {
Button button;
String osType = "Windows"; // 假设从配置中获取操作系统类型
if ("Windows".equalsIgnoreCase(osType)) {
button = new WindowsButton();
} else {
button = new MacButton();
}
button.render();
}
}
这里如果又新增一个liunx按钮 客户端又要重新修改代码
使用工厂模式
// 抽象产品:Button(按钮)
interface Button {
void render();
}
// 具体产品:WindowsButton(Windows 按钮)
class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Windows Button");
}
}
// 具体产品:MacButton(Mac 按钮)
class MacButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Mac Button");
}
}
// 具体产品:LinuxButton(Linux 按钮)
class LinuxButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Linux Button");
}
}
// 抽象工厂:GUIFactory
interface GUIFactory {
Button createButton();
}
// 具体工厂:WindowsFactory
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
}
// 具体工厂:MacFactory
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
}
// 具体工厂:LinuxFactory
class LinuxFactory implements GUIFactory {
@Override
public Button createButton() {
return new LinuxButton();
}
}
// 工厂创建器:根据操作系统类型选择对应的工厂
class FactoryCreator {
public static GUIFactory getFactory(String osType) {
if ("Windows".equalsIgnoreCase(osType)) {
return new WindowsFactory();
} else if ("Mac".equalsIgnoreCase(osType)) {
return new MacFactory();
} else if ("Linux".equalsIgnoreCase(osType)) {
return new LinuxFactory();
}
return null;
}
}
// 客户端代码:通过工厂创建按钮
public class Main {
public static void main(String[] args) {
// 假设从配置文件或环境变量获取操作系统类型
String osType = System.getProperty("os.name"); // 获取操作系统名称(例如:Windows、Mac、Linux)
// 使用工厂创建器自动选择工厂
GUIFactory factory = FactoryCreator.getFactory(osType);
// 通过工厂创建按钮
if (factory != null) {
Button button = factory.createButton();
button.render();
} else {
System.out.println("No suitable factory found for " + osType);
}
}
}
这里你无论新增多少按钮,客户端代码始终不变
工厂模式的种类
简单工厂模式(Simple Factory Pattern)
通过一个工厂类来根据参数的不同返回不同类型的对象。
优点:客户端代码很简单,所有的产品类都集中在一个地方。
缺点:如果产品类增多,工厂类需要做出改动,违反了开放-封闭原则。
示例
产品类
class Car {
void drive() {
System.out.println("Driving a car");
}
}
class Truck {
void drive() {
System.out.println("Driving a truck");
}
}
工厂类
class VehicleFactory {
public static Object createVehicle(String type) {
if (type.equals("car")) {
return new Car();
} else if (type.equals("truck")) {
return new Truck();
}
return null;
}
}
public class Main {
public static void main(String[] args) {
Object vehicle = VehicleFactory.createVehicle("car");
if (vehicle instanceof Car) {
((Car) vehicle).drive();
}
}
}
工厂方法模式(Factory Method Pattern)
定义一个创建对象的接口,但让子类决定实例化哪个类。这样,工厂方法模式允许子类来决定返回什么样的对象,而不需要修改客户端代码。
优点:符合开放-封闭原则,产品扩展时不需要修改客户端代码。
简单来说,就是有个产品,咱们需要定义一个接口或者抽象类定义需要实现的方法(例如开车),然后创建多个具体类实现或者继承该方法去实现不同的开车类型(开卡车,开拖拉机,开小车),有了具体的类之后,需要创建工厂帮我们创建开车类型,这里比简单工厂模式优化点是,创建一了一个抽象工厂,让下面的子类具体工厂继承抽象工厂来帮我们实现具体的产品。这样符合开闭原则了
产品类
interface Vehicle {
void drive();
}
class Car implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a car");
}
}
class Truck implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a truck");
}
}
工厂类
abstract class VehicleFactory {
abstract Vehicle createVehicle();
}
class CarFactory extends VehicleFactory {
@Override
Vehicle createVehicle() {
return new Car();
}
}
class TruckFactory extends VehicleFactory {
@Override
Vehicle createVehicle() {
return new Truck();
}
}
public class Main {
public static void main(String[] args) {
VehicleFactory factory = new CarFactory();
Vehicle vehicle = factory.createVehicle();
vehicle.drive();
}
}
抽象工厂模式
提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。
工厂方法模式创建的是单个对象,而抽象工厂模式创建的是多个相关对象。
简单来说抽象工厂就是有几个配套的抽象产品(车轮和车胎),多个具体的类实现不同的抽象产品(车轮和车胎)当成具体实现类(越野车胎,越野车轮,公路车胎,公路车轮),有了这些类之后,需要实现工厂来帮我们进行组合,所有有个抽象工厂类用来创建车胎和车轮,然后创建具体的工厂实现抽象工厂,来返回配套的车胎车轮。
示例
产品类
// 抽象产品:车轮
interface Wheel {
void create();
}
// 抽象产品:轮胎
interface Tire {
void create();
}
// 具体产品:越野车轮
class OffRoadWheel implements Wheel {
@Override
public void create() {
System.out.println("Creating Off-road Wheel");
}
}
// 具体产品:公路车轮
class RoadWheel implements Wheel {
@Override
public void create() {
System.out.println("Creating Road Wheel");
}
}
// 具体产品:越野轮胎
class OffRoadTire implements Tire {
@Override
public void create() {
System.out.println("Creating Off-road Tire");
}
}
// 具体产品:公路轮胎
class RoadTire implements Tire {
@Override
public void create() {
System.out.println("Creating Road Tire");
}
}
工厂类
// 抽象工厂:车轮和轮胎的工厂
interface VehiclePartsFactory {
Wheel createWheel();
Tire createTire();
}
// 具体工厂:越野车配件工厂
class OffRoadVehiclePartsFactory implements VehiclePartsFactory {
@Override
public Wheel createWheel() {
return new OffRoadWheel();
}
@Override
public Tire createTire() {
return new OffRoadTire();
}
}
// 具体工厂:公路车配件工厂
class RoadVehiclePartsFactory implements VehiclePartsFactory {
@Override
public Wheel createWheel() {
return new RoadWheel();
}
@Override
public Tire createTire() {
return new RoadTire();
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
// 创建越野车配件工厂
VehiclePartsFactory offRoadFactory = new OffRoadVehiclePartsFactory();
Wheel offRoadWheel = offRoadFactory.createWheel();
Tire offRoadTire = offRoadFactory.createTire();
offRoadWheel.create();
offRoadTire.create();
// 创建公路车配件工厂
VehiclePartsFactory roadFactory = new RoadVehiclePartsFactory();
Wheel roadWheel = roadFactory.createWheel();
Tire roadTire = roadFactory.createTire();
roadWheel.create();
roadTire.create();
}
}
springboot哪些地方使用了工厂模式
BeanFactory 和 ApplicationContext
Spring 提供了 BeanFactory 和 ApplicationContext 作为工厂类来管理 bean 的创建和生命周期。这两个接口实际上是工厂模式的应用,ApplicationContext 扩展了 BeanFactory,用于创建和管理应用程序中的 bean。
示例
@Configuration
public class AppConfig {
@Bean
public Car car() {
return new Car();
}
}
@SpringBootApplication
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Car car = context.getBean(Car.class);
car.drive();
}
}
FactoryBean
FactoryBean 是一个工厂类,但是它并不是直接返回一个简单的对象,而是返回一个由 FactoryBean 实现逻辑控制的复杂对象。
示例
这里可以对比之前的工厂模式,可以看出就是工厂模式(有产品类,有工厂类,有具体工厂实现)
public class Car {
public void drive() {
System.out.println("Driving the car!");
}
}
public class CarFactoryBean implements FactoryBean<Car> {
@Override
public Car getObject() throws Exception {
// 在这里可以写复杂的创建逻辑
System.out.println("Creating Car object via FactoryBean");
return new Car();
}
@Override
public Class<?> getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return true; // 返回单例
}
}
JdbcTemplate
JdbcTemplate 是 Spring 中的一个工具类,它通过工厂模式封装了数据库连接的创建过程,并提供了统一的操作接口。开发者无需关心底层数据库连接的具体实现。
何时使用工厂模式?
需要隐藏对象创建的复杂性 当对象的创建过程复杂时,直接使用 new 关键字可能会导致代码重复、易出错、难以维护。通过工厂模式,可以将对象创建的过程封装到工厂类中,客户端代码不需要关心如何创建对象,而只需要关心如何使用对象。
需要创建的对象有多个子类 当你需要创建的对象有多个具体实现类,而这些类的具体实现对客户端不重要时,可以通过工厂模式来集中管理这些不同的对象创建过程。工厂模式能够根据不同的参数或条件动态决定实例化哪个具体的类。
对象的创建过程可能会变化或扩展 当系统需要支持未来扩展(例如,新增产品类或功能)时,使用工厂模式可以避免修改已有代码,只需要扩展工厂类来支持新的对象创建。工厂模式遵循 开放-封闭原则,便于扩展而不需要修改现有的客户端代码。
需要依赖注入和对象管理 在一些框架(如 Spring)中,工厂模式用于创建和管理对象,例如 BeanFactory 和 ApplicationContext 就是通过工厂模式来管理对象的生命周期和依赖关系。
简单来说
原文地址:https://blog.csdn.net/qq_44819486/article/details/145158317
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!