工厂模式详解
1. 工厂模式的分类
工厂模式可以分为三类:
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
2. 什么是工厂模式
工厂模式是一种创建型设计模式,它提供了一种封装对象创建过程的方式,使得代码更加灵活、可维护和可扩展。在工厂模式中,对象的创建由一个专门的工厂类负责,这样调用者无需关心对象的创建细节,只需向工厂类请求所需的对象即可。
3. 工厂模式的角色
产品(Product): 定义产品的接口或抽象类,描述产品的主要功能和特性。
具体产品(Concrete Product): 实现产品接口或继承产品抽象类的具体类,是工厂类创建的目标。
工厂(Factory): 创建产品的接口或抽象类,其中包含了创建产品的方法。
具体工厂(Concrete Factory): 实现工厂接口或继承工厂抽象类,负责具体创建产品实例。
4. 工厂模式的优点
解耦: 将对象的创建与使用分离,降低代码之间的耦合度。
灵活性: 可以轻松创建不同的产品实例,只需修改工厂类的实现即可。
可扩展性: 当需要添加新产品时,只需添加新的具体工厂和具体产品类,无需修改原有代码。
易于维护: 将对象的创建封装在工厂类中,使得代码更清晰和易于维护。
一、简单工厂模式
1. 简单工厂模式的角色
角色 描述
抽象产品 定义了产品接口或抽象类,是所有具体产品的基类。
具体产品 实现了产品接口或继承了产品抽象类,是简单工厂模式创建的目标。
简单工厂 负责创建所有实例,外界通过调用其方法创建所需产品对象。
2. 简单工厂模式示例
定义一个抽象手机产品 Phone:
public interface Phone {
void showBrand();
}
定义具体手机产品 Xiaomi、Oppo、Vivo:
public class Xiaomi implements Phone {
@Override
public void showBrand() {
System.out.println("这是一个小米手机。");
}
}
public class Oppo implements Phone {
@Override
public void showBrand() {
System.out.println("这是一个OPPO手机。");
}
}
public class Vivo implements Phone {
@Override
public void showBrand() {
System.out.println("这是一个Vivo手机。");
}
}
定义手机工厂 PhoneFactory:
public class PhoneFactory {
public static Phone showPhone(String brandName){
if ("Xiaomi".equals(brandName)){
return new Xiaomi();
}
if ("Oppo".equals(brandName)){
return new Oppo();
}
if ("Vivo".equals(brandName)){
return new Vivo();
}
return null;
}
}
测试:
public class PhoneTest {
public static void main(String[] args) {
Phone xiaomi = PhoneFactory.showPhone("Xiaomi");
if (null != xiaomi) xiaomi.showBrand();
else System.out.println("无法生成该品牌的手机。");
}
}
3. 使用场景
- 创建对象不涉及复杂逻辑。
- 减少客户端代码对类的依赖。
- 动态选择具体类。
- 创建对象消耗较多资源。
- 创建对象需遵守约束或规则。
4. 总结
优点:
解耦客户端与具体产品,提高系统灵活性和可扩展性。
缺点:
增加新产品时需修改简单工厂类,违反开闭原则。
二、工厂方法模式
1. 工厂方法模式角色
角色描述:
- 抽象产品 产品接口,是所创建对象的超类型。
- 具体产品 实现了抽象产品接口,由专门的具体工厂创建。
- 抽象工厂 声明了返回一个产品的方法,是核心所在。
- 具体工厂 实现抽象工厂,用于返回具体产品实例。
2. 工厂方法示例
抽象工厂 PhoneFactory:
public interface PhoneFactory {
Phone CreatePhone();
}
抽象产品 Phone:
public interface Phone {
void showBrand();
}
具体产品工厂 XiaomiFactory、OppoFactory、VivoFactory:
public class XiaomiFactory implements PhoneFactory {
@Override
public Phone createPhone() {
System.out.println("这是小米手机工厂,这里只生产小米手机。");
return new Xiaomi();
}
}
public class OppoFactory implements PhoneFactory {
@Override
public Phone createPhone() {
System.out.println("这是OPPO手机工厂,这里只生产OPPO手机。");
return new Oppo();
}
}
public class VivoFactory implements PhoneFactory {
@Override
public Phone createPhone() {
System.out.println("这是Vivo手机工厂,这里只生产Vivo手机。");
return new Vivo();
}
}
测试:
public class Test {
public static void main(String[] args) {
XiaomiFactory xiaomiFactory = new XiaomiFactory();
Phone phone = xiaomiFactory.createPhone();
phone.showBrand();
}
}
3. 使用场景
- 重复代码。
- 不关心创建过程。
- 子类指定创建对象。
- 提供默认值并允许自定义值。
4. 总结
优点:
解耦用户代码与特定子类。
符合“开放-封闭”原则。
缺点:
增加系统复杂度和代码量。
三、抽象工厂模式
1. 抽象工厂模式角色
角色描述
- 抽象工厂 声明用于生产不同类型对象的方法。
- 具体工厂 实现抽象工厂接口,负责实例化具体产品。
- 抽象产品 定义了产品接口,是所创建对象的超类型。
- 具体产品 实现抽象产品接口,是某种类型的具体产品对象。
2. 抽象工厂示例
抽象工厂:
public interface AbstractFactory {
Phone CreateApplePhone();
Book CreateBookPhone();
}
抽象产品:
public interface Book {
void showDetail();
}
public interface Phone {
void showDetail();
}
具体工厂 XiaomiFactory、OppoFactory:
// XiaomiFactory
public class XiaomiFactory implements AbstractFactory{
@Override
public Phone createPhone() {
return new XiaomiPhone();
}
@Override
public Book createBook() {
return new MiNotebook();
}
}
// OppoFactory
public class OppoFactory implements AbstractFactory{
@Override
public Phone createPhone() {
return new OppoRenoPhone();
}
@Override
public Book createBook() {
return new OppoLaptop();
}
}
具体产品:
// Phone
public class XiaomiPhone implements Phone {
@Override
public void showDetail() {
System.out.println("这是小米手机。");
}
}
public class OppoRenoPhone implements Phone {
@Override
public void showDetail() {
System.out.println("这是OPPO Reno手机。");
}
}
// Book
public class MiNotebook implements Book {
@Override
public void showDetail() {
System.out.println("这是小米笔记本电脑。");
}
}
public class OppoLaptop implements Book {
@Override
public void showDetail() {
System.out.println("这是OPPO笔记本电脑。");
}
}
测试:
public class Client{
public static void main(String[] args){
XiaomiFactory xiaomiFactory = new XiaomiFactory();
xiaomiFactory.createPhone().showDetail();
xiaomiFactory.createBook().showDetail();
System.out.println("===========================");
OppoFactory oppoFactory = new OppoFactory();
oppoFactory.createPhone().showDetail();
oppoFactory.createBook().showDetail();
}
}
3. 使用场景
- 系统独立于产品创建、组合和表示。
- 多个产品系列配置。
- 强调联合使用一系列相关产品对象。
- 想显示产品接口而非实现。
4. 总结
优点:
封装性好,支持更换产品族,降低耦合度。
缺点:
难以支持新种类产品,增加系统复杂性。
通过以上三种设计模式,可以根据需求选择合适的方式来管理和优化代码结构,提高系统灵活性和可维护性。