zoukankan      html  css  js  c++  java
  • 抽象工厂(Abstract Factory)设计模式

    首先,让我们考虑一个支持look-and-feel 标准的用户界面工具包,例如Motif 和 Presentation Manager。为了保证look and feel 的一致性,应用程序不应该为一个特定的look-and-feel 硬编码其窗口组件。因为这样将会造成以后很难改变窗口的观感。

    为了解决这一问题,我们定义了一个 WidgetFactory 类。这个类具有一些方法,用于创建不同的窗口组件。如 createScrollBar 方法将用于创建一个 ScrollBar,createWindow 方法将创建 Window 类。对WidgetFactory 的方法所能创建的每一类窗口组件,都对应一个抽象类。如这里的Window 和 ScrollBar。WidgetFactory 是一个抽象类,其子类将用于创建具体的窗口组件。如下图所示:

     

    从上面可以看出,当我们需要创建另一类 观感时,只需要继承 WidgetFactory 抽象工厂类,并覆盖其方法即可。

    这里使用的就是 Abstract Factory 抽象工厂模式。该模式的结构图如下所示:

     

    Abstract Factory 模式具有以下特点:

    1. 客户与具体实现分离。客户使用的是抽象产品。实现与使用分离。

    2. 易于扩展新的产品类。只需要实现一个新的实体工厂,并继承自抽象工厂,即可轻松获得一个新的产品类别。

    3. 产品一致性比较好。一个应用一次只能使用同一系列中的对象,如上面不能将 MotifWindow 和 PMScrollBar 混合起来使用。

    4. Abstract Factory 也有一个问题。即不容易扩展新种类的产品。针对这个问题,后面会有一个解决方法。

    下面我们看一个抽象工厂类的例子。程序是用Java 写的。

    首先是抽象工厂类

    AbstractFactory.java:

    public abstract class AbstractFactory {
    Button button;
    TextBox textbox;
    public abstract void createButton();
    public abstract void createTextbox();
    }
    

      


    可以看出,该类用于产生产品 Button 和 TextBox。Button 和 TextBox 也是抽象类。

    Button.java:

    public abstract class Button {
    protected abstract void createShape();
    }
    TextBox.java:
    
    public abstract class TextBox {
    protected abstract void createText();
    }
    

      

    LinuxFactory 和 WindowsFactory 继承自 AbstractFactory。它们的createButton 分别产生 LinuxButton、LinuxTextBox 和 WindowsButton 、WindowsTextBox。

    LinuxFactory.java:
    
    public class LinuxFactory extends AbstractFactory {
    public void createButton() {
    button = new LinuxButton();
    button.createShape();
    }
    
    public void createTextbox() {
    textbox = new LinuxTextBox();
    textbox.createText();
    }
    }
    WindowsFactory.java:
    
    public class WindowsFactory extends AbstractFactory {
    public void createButton() {
    button = new WindowsButton();
    button.createShape();
    }
    
    public void createTextbox() {
    textbox = new WindowsTextBox();
    textbox.createText();
    }
    }
    LinuxButton.java:
    
    public class LinuxButton extends Button {
    protected void createShape() {
    System.out.println("create Linux Button");
    }
    }
    LinuxTextBox.java:
    
    public class LinuxTextBox extends TextBox {
    protected void createText() {
    System.out.println("create linux textbox");
    }
    }
    WindowsButton.java:
    
    public class WindowsButton extends Button {
    protected void createShape() {
    System.out.println("create windows button");
    }
    }
    WindowsTextBox.java:
    
    public class WindowsTextBox extends TextBox {
    protected void createText() {
    System.out.println("create windows textbox");
    }
    }
    

      

    下面Client 类显示了抽象工厂模式中对象的使用:

    Client.java:

    public class Client {
    public static void main(String args[]) {
    AbstractFactory factory = new LinuxFactory();
    factory.createButton();
    factory.createTextbox();
    factory = new WindowsFactory();
    factory.createButton();
    factory.createTextbox();
    }
    }
    

      

    从Client 类可以看出,在使用抽象工厂模式时,用实体工厂创建创建工厂类,然后通过抽象工厂类创建部件。所创建的实体产品对客户透明。


    我们再来看这个设计。我们通过AbstractFactory 可以创建 Button 和 TextBox,但是现在我们需要创建另一种产品 TextField。这就比较难办了。我们需要更改Abstract Factory ,并更改所有继承了 AbstractFactory 的类。显然这样做是非常不合适的。因此 Abstract Factory 模式在扩展新产品时是有一些问题的。

    一种解决办法是给创建对象的操作提供一个参数,这个参数用于指定被创建对象的种类。尽管这是一个可用的解决方案,但是也有一定问题。

    因此,我们需要知道,扩展新产品不是Abstract Factory 模式的强项。

  • 相关阅读:
    算法笔记_182:历届试题 核桃的数量(Java)
    算法笔记_181:历届试题 回文数字(Java)
    算法笔记_180:历届试题 国王的烦恼(Java)
    算法笔记_179:历届试题 数字游戏(Java)
    算法笔记_178:历届试题 邮局(Java)
    算法笔记_177:历届试题 城市建设(Java)
    算法笔记_176:历届试题 最大子阵(Java)
    算法笔记_175:历届试题 蚂蚁感冒(Java)
    redis集群与分片(2)-Redis Cluster集群的搭建与实践
    redis集群与分片(1)-redis服务器集群、客户端分片
  • 原文地址:https://www.cnblogs.com/tonny-li/p/15540977.html
Copyright © 2011-2022 走看看