Java设计模式——抽象工厂模式

目录

四个基本要素

名称

问题

方案

效果

模式的结构

抽象工厂(Abstract Factory)

具体工厂(Concrete Factory)

抽象产品(Abstract Product)

具体产品(Concrete Product)

抽象工厂模式的类图

优点

缺点

模式具体应用


提供一个创建一系列或相互依赖对象的接口,而无须指定它们具体的类。

抽象工厂模式属于创建型设计模式

四个基本要素

名称

  • 抽象工厂模式(Abstract Factory Pattern)

问题

  • 在软件开发中,经常需要创建一组相关或依赖的对象,例如在创建用户界面时,需要同时创建按钮、文本框、复选框等组件,而这些组件之间可能存在一定的关联关系。如果直接在客户端代码中创建这些对象,会导致客户端代码与具体产品类耦合度较高,不利于后续的维护和扩展。此外,如果需要新增或修改产品类,就需要修改客户端代码,违反了开闭原则。

方案

  • 使用抽象工厂模式,定义一个抽象工厂接口或抽象类,其中包含一组用于创建产品家族的抽象方法。
  • 具体的产品家族由具体的工厂子类实现,每个具体工厂负责创建特定类型的产品。
  • 客户端通过调用工厂方法来创建产品,而不直接与具体产品类进行交互。

效果

  • 抽象工厂模式将对象的创建与使用分离,降低了客户端代码与具体产品的耦合度,提高了系统的灵活性和可扩展性。
  • 新增产品时只需添加新的具体工厂和具体产品,无需修改现有的代码。
  • 符合开闭原则,客户端代码不需要修改即可支持新的产品类型。
  • 可以在运行时动态切换具体工厂,实现了运行时的配置选择。
  • 适用于需要创建一组相关或依赖的对象家族,并且客户端不需要知道具体对象的创建细节的场景。

模式的结构

抽象工厂(Abstract Factory)

  • 定义了一个创建一组相关或依赖对象的接口。通常是一个接口或者抽象类,其中包含一组用于创建产品家族的抽象方法。
  • 抽象工厂可以看作是一种工厂的工厂,它包含多个工厂方法,每个工厂方法用于创建一个特定类型的产品,具体的产品创建由具体工厂类来实现。

具体工厂(Concrete Factory)

  • 实现了抽象工厂接口,负责创建特定类型的产品家族。
  • 每个具体工厂负责创建一组相关的产品,具体工厂类通常通过实现抽象工厂中定义的抽象方法来创建产品。
  • 实现了抽象工厂接口或抽象工厂类中定义的抽象方法,从而隐藏了对象的创建细节,提供了一种统一的接口来创建产品族。

抽象产品(Abstract Product)

  • 定义了产品对象的接口或抽象类,描述了产品对象应该具有的通用行为和属性。
  • 通常作为工厂模式中的一个基类,用于统一表示一组相关的产品对象。
  • 抽象产品的存在使得客户端代码可以通过与抽象产品进行交互,而不需要关心具体产品的实现细节,从而实现了客户端与具体产品类的解耦。

具体产品(Concrete Product)

  • 实现了抽象产品接口,属于产品族中的具体对象。
  • 每个具体产品类负责实现抽象产品中定义的抽象方法,以提供具体的功能实现。

抽象工厂模式的类图

优点

  • 产品族一致性: 抽象工厂模式能够确保创建的所有产品都属于同一产品族,这有助于确保这些产品之间的兼容性和一致性。
  • 易于替换产品族: 由于客户端只依赖于抽象工厂和抽象产品接口,因此可以比较容易地替换整个产品族,而不需要修改客户端代码。
  • 降低耦合度: 客户端代码与具体产品的实现解耦,客户端只需要与抽象工厂和抽象产品进行交互,而不需要关心具体产品的实现细节。

  • 增加灵活性: 抽象工厂模式支持在运行时动态切换具体工厂,从而实现了运行时的配置选择,可以根据需要选择不同的产品族。

缺点

  • 扩展性受限: 新增产品族时,除了需要添加新的具体工厂类外,还需要修改抽象工厂接口或抽象工厂类,这可能导致抽象工厂的修改,违反了开闭原则。
  • 复杂性增加: 抽象工厂模式引入了多个抽象类和接口,以及多个具体工厂类,这增加了系统的复杂性和理解难度。
  • 不易于单独定制产品: 由于抽象工厂模式一般是为了创建一组相关的产品对象,因此不太适合单独定制某个产品的场景,如果只需要定制某个产品,可能会显得过于笨重。

模式具体应用

在一个跨平台的软件项目中,需要创建 UI 元素,例如按钮、文本框等,同时确保所创建的元素与指定的操作系统匹配,以提供良好的用户体验。客户端代码不应该直接与具体的 UI 类耦合,而是希望能够通过统一的接口来创建 UI 元素,使得能够灵活地替换整个 UI 元素的产品族。


抽象产品 : Button.java

public abstract class Button {
    public abstract void paint();
}

 抽象产品 : Checkbox.java  

public abstract class Checkbox {
    public abstract void paint();
}

 具体产品 MacButton.java

public class MacButton extends Button{
    @Override
    public void paint() {
        System.out.println("渲染了mac系统的Button");
    }
}

 具体产品 MacCheckbox.java

public class MacCheckbox extends Checkbox {
    @Override
    public void paint() {
        System.out.println("渲染了mac系统的Checkbox");
    }
}

 具体产品  WinButton.java

public class WinButton extends Button {
    @Override
    public void paint() {
        System.out.println("渲染了Win系统的Button");
    }
}

具体产品  WinCheckbox.java

public class WinCheckbox extends Checkbox {
    @Override
    public void paint() {
        System.out.println("渲染了win系统的Checkbox");
    }
}

 抽象工厂:  GuiFactory .java

public abstract class GuiFactory {

    public abstract Button createButton();
    public abstract Checkbox createCheckbox();
}

具体构造者(ConcreteCreator): MacFactory .java

public class MacFactory extends GuiFactory {

    @Override
    public Button createButton() {
        return new MacButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new MacCheckbox();
    }
}

具体构造者(ConcreteCreator): WinFactory .java

public class WinFactory extends GuiFactory{
    
    @Override
    public WinButton createButton() {
        return new WinButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new WinCheckbox();
    }
}

应用包装:Application.java

public class Application {
    private GuiFactory factory;

    public Application(GuiFactory factory) {
        this.factory = factory;

    }
   public void createUI() {
        factory.createButton().paint();
        factory.createCheckbox().paint();
    }
}

测试:ApiTest.java

public class ApiTest {

    @Test
    public void abstractFactoryPattern(){

            String os = "Mac";

            GuiFactory factory;
            if (os.equals("Windows")) {
                factory = new WinFactory();
            } else if (os.equals("Mac")) {
                factory = new MacFactory();
            } else {
                throw new RuntimeException("错误!未知的操作系统。");
            }
            Application app = new Application(factory);
            app.createUI();
    }
}

  • 32
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值