工厂方法模式(Factory Method)
一、问题
在软件设计中,我们经常遇到需要创建不同类型对象的情况。但是,如果直接在代码中实例化对象,会使代码紧密耦合在一起,难以维护和扩展。此外,如果对象的创建方式需要变化,那么就需要在整个代码中进行大量的修改。工厂方法模式旨在解决这个问题。
二、解决方案
工厂方法模式提供了一个创建对象的接口,但是将具体的对象创建延迟到子类中。这样,客户端代码不需要知道要创建的具体对象的类,只需要通过工厂方法来创建对象。这使得客户端代码与具体对象的创建解耦,提高了代码的灵活性和可维护性。 在工厂方法模式中,通常会定义一个抽象工厂类,其中包含一个创建对象的抽象方法,而具体的对象创建则由具体的子类实现。这样,每个具体的子类都可以根据需要创建不同类型的对象,而客户端代码只需要通过抽象工厂类来调用工厂方法,而不需要关心具体的对象创建细节。
三、效果
工厂方法模式的优点包括:
- 松耦合:客户端代码与具体对象的创建解耦,使得系统更具弹性和可维护性。
- 扩展性:通过添加新的具体工厂和产品子类,可以很容易地扩展系统以支持新的对象类型。
- 封装性:将对象的创建集中在工厂类中,封装了对象的创建细节,使得客户端代码更简洁。
然而,工厂方法模式也可能引入一些额外的复杂性,因为需要定义多个工厂类和产品类的层次结构。这可能会导致系统中类的数量增加。在选择使用工厂方法模式时,需要根据具体情况进行权衡。 工厂方法模式在实际应用中非常常见,例如,图形库可以使用工厂方法模式来创建不同类型的图形对象,数据库访问框架可以使用工厂方法模式来创建不同类型的数据库连接等。
四、代码
1.Animal.java
/**
* Animal
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 13:57
* @description 动物抽象类
*/
public interface Animal {
// 叫
public void sound();
}
java
2.Cat.java
/**
* Cat
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 13:57
* @description 猫咪类
*/
public class Cat implements Animal {
@Override
public void sound() {
System.out.println("喵喵喵");
}
}
java
3.Dog.java
/**
* Dog
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 13:58
* @description 小狗类
*/
public class Dog implements Animal {
@Override
public void sound() {
System.out.println("汪汪汪");
}
}
java
4.AnimalFactory.java
/**
* AnimalFactory
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 13:58
* @description 动物工厂抽象类
*/
public abstract class AnimalFactory {
// 创建动物类对象
public abstract Animal createAnimal();
}
java
5.CatFactory.java
/**
* CatFactory
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 16:22
* @description 猫咪工厂
*/
public class CatFactory extends AnimalFactory {
@Override
public Animal createAnimal() {
return new Cat();
}
}
java
6.DogFactory.java
/**
* DogFactory
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 16:23
* @description 小狗工厂
*/
public class DogFactory extends AnimalFactory{
@Override
public Animal createAnimal() {
return new Dog();
}
}
java
7.Main.java
/**
* Main
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:52
* @description 工厂方法模式客户端
*/
public class Main {
public static void main(String[] args) {
// 初始化猫咪工厂
AnimalFactory catFactory = new CatFactory();
Animal cat = catFactory.createAnimal();
cat.sound();
// 初始化小狗工厂
AnimalFactory dogFactory = new DogFactory();
Animal dog = dogFactory.createAnimal();
dog.sound();
}
}
java
8.打印结果
抽象工厂模式(Abstract Factory)
一、问题
在某些情况下,需要创建一系列相关或相互依赖的对象,这些对象属于一组相关的产品族。同时,系统需要保证这些产品族之间的一致性。如果直接在代码中创建这些对象,会使得代码与具体产品的细节紧密耦合,不利于后续的扩展和维护。
二、解决方案
抽象工厂模式提供了一个接口,用于创建一系列相关或相互依赖的对象。通过使用抽象工厂接口及其具体实现,可以将对象的创建与客户端代码分离,从而实现系统的松耦合。抽象工厂模式涉及多个角色:
- 抽象工厂(Abstract Factory):声明了一组用于创建不同产品的抽象方法。具体的工厂类必须实现这些方法来创建具体的产品对象。
- 具体工厂(Concrete Factory):实现抽象工厂接口,负责创建特定种类的产品对象。
- 抽象产品(Abstract Product):定义了产品的通用接口,具体产品必须实现这个接口。
- 具体产品(Concrete Product):实现抽象产品接口,是抽象工厂创建的实际对象。
三、效果
抽象工厂模式的使用可以带来以下效果:
- 产品族一致性:抽象工厂确保创建的产品是一组相关的产品族,保证了这些产品之间的一致性。
- 松耦合:客户端代码不需要直接依赖于具体产品,只需要通过抽象工厂接口创建产品,从而降低了代码的耦合度。
- 可扩展性:增加新的产品族或产品变得相对容易,只需要添加新的具体工厂和产品类即可,不需要修改现有代码。
- 限制:抽象工厂模式要求系统中的每个产品族都必须有一个对应的具体工厂,这可能增加了系统的复杂性。
抽象工厂模式适用于需要创建一系列相关产品并保证它们之间一致性的情况,例如图形界面库中的UI元素,不同操作系统下的界面组件等。通过使用抽象工厂模式,可以更好地管理和组织这些产品的创建过程。
四、代码
1.OperatingSystem.java
/**
* OperatingSystem
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:39
* @description 抽象产品接口:操作系统
*/
public interface OperatingSystem {
/**
* 启动
*/
void run();
}
java
2.WindowsOS.java
/**
* WindowsOS
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:39
* @description 具体产品:Window操作系统
*/
public class WindowsOS implements OperatingSystem {
@Override
public void run() {
System.out.println("Windows系统启动~");
}
}
java
3.Linux.java
/**
* LinuxOS
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:40
* @description 具体产品:Linux操作系统
*/
public class LinuxOS implements OperatingSystem {
@Override
public void run() {
System.out.println("Linux系统启动~");
}
}
java
4.Application.java
/**
* Application
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:41
* @description 抽象产品接口:应用程序
*/
public interface Application {
/**
* 打开
*/
void open();
}
java
5.WeChat.java
/**
* WeChat
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:44
* @description 具体产品:微信
*/
public class WeChat implements Application {
@Override
public void open() {
System.out.println("打开微信~");
}
}
java
6.Vim.java
/**
* Vim
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:45
* @description 具体产品:Vim
*/
public class Vim implements Application {
@Override
public void open() {
System.out.println("打开Vim~");
}
}
java
7.SoftwareFactory.java
/**
* SoftwareFactory
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:47
* @description 抽象工厂接口
*/
public interface SoftwareFactory {
/**
* 创建操作系统
* @return 操作系统
*/
OperatingSystem createOperatingSystem();
/**
* 打开程序
* @return 程序
*/
Application openApplication();
}
java
8.WindowsFactory.java
/**
* WindowsFactory
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:49
* @description 具体工厂:Windows工厂
*/
public class WindowsFactory implements SoftwareFactory {
@Override
public OperatingSystem createOperatingSystem() {
return new WindowsOS();
}
@Override
public Application openApplication() {
return new WeChat();
}
}
java
9.LinuxFactory.java
/**
* LinuxFactory
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:50
* @description 具体工厂:Linux工厂
*/
public class LinuxFactory implements SoftwareFactory {
@Override
public OperatingSystem createOperatingSystem() {
return new LinuxOS();
}
@Override
public Application openApplication() {
return new Vim();
}
}
java
10.Main.java
/**
* Main
*
* @author 裴浩宇
* @version 1.0
* @date 2023/10/17 17:52
* @description 抽象工厂模式客户端
*/
public class Main {
public static void main(String[] args) {
// 初始化Windows工厂
SoftwareFactory windowsFactory = new WindowsFactory();
// 初始化操作系统
OperatingSystem windowsOS = windowsFactory.createOperatingSystem();
// 启动
windowsOS.run();
// 初始化应用程序
Application wechat = windowsFactory.openApplication();
// 打开
wechat.open();
// 初始化Linux操作系统
SoftwareFactory linuxFactory = new LinuxFactory();
// 初始化操作系统
OperatingSystem linuxOS = linuxFactory.createOperatingSystem();
// 启动
linuxOS.run();
// 初始化应用程序
Application vim = linuxFactory.openApplication();
// 打开
vim.open();
}
}
java