`
zhangweieye
  • 浏览: 9976 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

设计模式学习笔记(十二:生成器模式)

 
阅读更多

1.1概述

    将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。这就是生产器模式的定义。

  如果一个类中有若干个成员变量是其他类声明的对象,那么该类创建的对象就可以包含若干个其他对象作为其成员。习惯上把一个对象中的成员对象称作它的组件,例如,几何(Geometry)类含有三角形(Triangle)类、矩形(Rectangle)类和圆(Circle)类声明的对象,那么几何类就可以创建一个由三角形、矩形和圆形组成的几何图形,三角形、长方形和圆形就是当前几何图形中的组件。

    但是,在编写几何类的构造方法的代码时可能会遇到如下困难:

    (1) 有些用户并不需要几何类所创建对象含有的全部组件。

    (2)有些用户对创建的几何类对象的组件有特殊要求,比如某用户要求其中的三角形是等边的,矩形是正方形等。

    显然,如果一个对象由很多组件构成,我们无法在构造方法中进行硬编码来满足各种用户对组件结构的要求。因此,按着面向抽象的原则,我们不应该在几何类构造方法中进行任何编码,而是将几何类对象的构造方法分成若干个步骤,即根据当前组件的个数,在一个接口中定义若干个方法,每个方法负责创建几何类对象的一个组件,而实现该接口的类负责创建几何类对象,也就是说,将几何类对象的创建过程封装到另一个类中。

  在设计模式中,封装一个对象的创建过程的类称作生成器,上述示例的示意图如下图一所示:(其中BuliderOneBuliderTwo就是生成器)

 

 

图一:用生成器创建几何类对象

 

    当系统准备为用户提供一个内部结构复杂的对象时,就可以使用生成器模式,使用该模式可以逐步地构造对象,使对象的创建更具弹性。生成器模式的关键是将一个含有多个组件对象的创建分成若干个步骤,并将这些步骤封装在一个称作生成器的接口中。

 

1.2模式的结构

生成器模式结构中包括四种角色:

(1)产品(Product):具体生产器要构造的复杂对象;

(2)抽象生成器(Bulider):抽象生成器是一个接口,该接口除了为创建一个Product对象的各个组件定义了若干个方法之外,还要定义返回Product对象的方法;

(3)具体生产器(ConcreteProduct):实现Builder接口的类,具体生成器将实现Builder接口所定义的方法;

(4)指挥者(Director):指挥者是一个类,该类需要含有Builder接口声明的变量。指挥者的职责是负责向用户提供具体生成器,即指挥者将请求具体生成器类来构造用户所需要的Product对象,如果所请求的具体生成器成功地构造出Product对象,指挥者就可以让该具体生产器返回所构造的Product对象。

生产器模式结构的类图如下图二所示:

 

 

图二:生成器模式结构类图

 

1.3生成器模式的优点

(1)生成器模式将对象的构造过程封装在具体生成器中,用户使用不同的具体生成器就可以得到该对象的不同表示。

(2)生成器模式将对象的构造过程从创建该对象的类中分离出来,是用户无须了解该对象的具体组件。

(3)可以更加精细有效地控制对象的构造过程。生成器将对象的构造过程分解成若干个步骤,这就使程序可以更加精细,有效地控制整个对象的构造。

(4)生成器模式将对象的构造过程与创建该对象类解耦,使对象的创建更加灵活有弹性。

(5)当增加新的具体生成器时,不必修改指挥者的代码,即该模式满足开-闭原则。

 

1.4适合使用生成器模式的情景

1)当系统准备为用户提供一个内部结构复杂的对象,而且在构造方法中编写创建该对象的代码无法满足用户需求时,就可以使用生成器模式来构造这样的对象。

2)当某些系统要求对象的构造过程必须独立于创建该对象的类时。

 

 

1.5生成器模式的使用

以下通过一个简单的问题来描述生成器模式中所涉及的各个角色。

这个简单的问题就是创建含有按钮、标签和文本框组件的容器。不同用户对容器有不同的要求,比如某些用户希望容器中只含有按钮和标签,某些用户希望容器中只含有按钮和文本框。另外,用户对组件在容器中的顺序位置也有不同的要求,比如某些用户要求组件在容器中从左至右的排列顺序是按钮、标签、文本框,而某些用户要求从左到右的排列顺序是标签、文本框、按钮等。

显然不能在容器的构造方法中编写有关创建按钮、标签和文本框的代码,也不能编写排列这些组件位置的代码。以下使用生成器为用户创建所需要的容器,具体如下:

 首先看一下本实例构建框架具体类和1.2模式的结构中类图的对应关系,如下图所示:

 

(1)产品(Product

产品角色是PanelProduct类,该类代码如下:

复制代码
package com.liuzhen.twelve_builder;

import javax.swing.*;

@SuppressWarnings("serial")
public class PanelProduct extends JPanel{
    JButton button;
    JLabel label;
    JTextField textField;
}
复制代码

 

(2)抽象生成器(Builder

抽象生成器是Builder接口,其代码如下:

复制代码
package com.liuzhen.twelve_builder;

import javax.swing.JPanel;

public interface Builder {
    public abstract void buildButton();
    public abstract void buildLabel();
    public abstract void buildTextField();
    public abstract JPanel getPanel();
}
复制代码

 

(3)具体生成器(ConcreteBuilder

有两个具体生成器类ConcreteBuilderOneConcreteBuilderTwo,具体代码如下:

ConcreteBuilderOne.java

复制代码
package com.liuzhen.twelve_builder;

import javax.swing.*;


public class ConcreteBuilderOne implements Builder {
    private PanelProduct panel;
    
    ConcreteBuilderOne(){
        panel = new PanelProduct();
    }

    public void buildButton() {
        // TODO Auto-generated method stub
        panel.button = new JButton("按钮");
    }

    public void buildLabel() {
        // TODO Auto-generated method stub
        panel.label = new JLabel("标签");
    }

    public void buildTextField() {
        // TODO Auto-generated method stub
        panel.textField = new JTextField("文本框");
    }

    public JPanel getPanel() {
        // TODO Auto-generated method stub
        panel.add(panel.button);            //与ConcreteBuilderTwo添加组件的顺序不同
        panel.add(panel.label);
        panel.add(panel.textField);
        return panel;
    }

}
复制代码

ConcreteBuilderTwo.java

复制代码
package com.liuzhen.twelve_builder;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class ConcreteBuilderTwo implements Builder {
    private PanelProduct panel;

    ConcreteBuilderTwo(){
        panel = new PanelProduct();
    }

    public void buildButton() {
        // TODO Auto-generated method stub
        panel.button = new JButton("按钮");
    }

    public void buildLabel() {
        // TODO Auto-generated method stub
        panel.label = new JLabel("标签");
    }

    public void buildTextField() {
        // TODO Auto-generated method stub
        panel.textField = new JTextField("文本框");
    }

    public JPanel getPanel() {
        // TODO Auto-generated method stub
        panel.add(panel.textField);            //与ConcreteBuilderOne添加组件的顺序不同
        panel.add(panel.label);
        panel.add(panel.button);
        return panel;
    }

}
复制代码

 

(4)指挥者(Director

指挥者是Director类,其代码如下:

复制代码
package com.liuzhen.twelve_builder;

import javax.swing.JPanel;

public class Director {
    private Builder builder;
    
    Director(Builder builder){
        this.builder = builder;
    }
    
    public JPanel constructProduct(){
        builder.buildButton();
        builder.buildLabel();
        builder.buildTextField();
        JPanel product = builder.getPanel();
        return product;
    }
}
复制代码

 

(5)具体使用

    通过TwelveApplication类来具体实现上述相关类,来实现工厂方法模式的运用,其代码如下:

复制代码
package com.liuzhen.twelve_builder;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class TwelveApplication {


    public static void main(String[] args) {
        Builder builder = new ConcreteBuilderOne();
        Director director = new Director(builder);
        JPanel panel = director.constructProduct();
        JFrame frameOne = new JFrame();
        frameOne.add(panel);
        frameOne.setBounds(12, 12, 200, 120);
        frameOne.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frameOne.setVisible(true);
        builder = new ConcreteBuilderTwo();
        director = new Director(builder);
        panel = director.constructProduct();
        JFrame frameTwo = new JFrame();
        frameTwo.add(panel);
        frameTwo.setBounds(12, 12, 200, 120);
        frameTwo.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frameTwo.setVisible(true);
    }

}
复制代码

 

运行结果:

 

分享到:
评论

相关推荐

    23种设计模式学习笔记

    这个“23种设计模式学习笔记”文档将引导你深入理解这些模式,并帮助你在实际编程中有效地应用它们。以下是对23种设计模式的详细解读: 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。它常用于控制...

    图解设计模式 ,结城浩著 学习笔记

    根据给定的信息“图解设计模式,结城浩著学习笔记”,我们可以推断出这份文档主要涉及了设计模式的学习和理解。《图解设计模式》是一本由日本著名程序员结城浩撰写的书籍,该书以图形化的方式深入浅出地讲解了软件...

    《设计模式》学习笔记

    ### 设计模式学习笔记 #### 引言 设计模式(Design Patterns)是在软件设计领域内广泛应用的一种实践指南,它提供了一系列解决常见问题的方案。设计模式可以被理解为面向对象软件设计的经验总结,是对特定面向对象...

    Android-Java的常见集中设计模式学习笔记

    本学习笔记主要聚焦于Java中的常见设计模式,并将这些概念与Android开发实践相结合。 1. **单例模式**:在Android中,单例模式常用于创建全局唯一的对象,例如应用程序的Application类就是一个典型的单例,它在整个...

    STM32F103RCT6学习笔记1:点灯.rar

    总的来说,"STM32F103RCT6学习笔记1:点灯"这个资料将引导初学者逐步掌握STM32的基本操作,包括GPIO的配置、开发环境的使用以及简单的硬件电路设计。通过实践这个实验,学习者能够为进一步深入学习STM32系列微控制器...

    设计模式笔记

    设计模式是软件开发中的一种重要概念,它是一套经过验证的、通用的解决方案,用来解决在软件设计过程中频繁出现的问题...在学习设计模式时,可以参考经典的书籍,如《Design Patterns》和《软件秘笈-设计模式那点事》。

    学习笔记:javaWeb考试系统(基于MVC模式)

    JavaWeb在线考试系统是基于MVC(Model-View-Controller)设计模式开发的一款应用程序,它主要用于帮助学生和教师进行线上测试和评估。在这个系统中,MVC模式将应用程序分为三个主要部分:模型(Model)、视图(View...

    C# 设计模式学习 源码

    本资料包“C# 设计模式学习 源码”包含了作者在学习设计模式过程中的笔记和源码示例,对于想要深入理解C#设计模式的人来说是一份宝贵的资源。 设计模式分为三大类:创建型、结构型和行为型。下面将详细介绍这些类别...

    java设计模式源码和笔记(第一部分)

    其中包含了个人的学习笔记和Eclipse环境下实现的源码,方便读者导入后直接运行,进行实践操作。 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。在Java中,单例模式通常通过私有构造器、静态工厂方法...

    自己学习的设计模式整理的笔记源码

    在本笔记源码中,你将深入理解23种经典设计模式,每一种都有详细的注释和示例。 1. **单例模式**:保证一个类只有一个实例,并提供全局访问点。在多线程环境下,单例模式的实现需要特别注意线程安全。 2. **工厂...

    C++设计模式笔记资料.zip

    C++设计模式是一种在软件开发过程中,为了应对特定问题或场景而形成的可重用解决方案的模板。这些模式是经过时间考验、广泛接受并被证明有效的编程实践,它们可以帮助开发者更高效地组织代码,提高代码的可读性、可...

    STM32学习笔记十:WS2812制作像素游戏屏(贪吃蛇大作战) 前十章所有源代码打包

    STM32学习笔记系列第十部分聚焦于利用WS2812制作像素游戏屏,并实现经典游戏"贪吃蛇大作战"。在这个项目中,开发者将深入理解如何利用STM32微控制器驱动WS2812 RGB LED灯条,构建一个自定义的游戏显示设备。这个教程...

    利用STM32F103ZET6开发板基于HAL库的STM32学习笔记五:串口通信基础例程

    在本篇STM32学习笔记中,我们将深入探讨如何利用STM32F103ZET6开发板上的串口通信功能。串口通信是一种在嵌入式系统中广泛使用的通信方式,尤其在单片机(如STM32)与PC或其他微控制器之间交换数据时。本文将基于STM...

    使用docsify搭建的个人学习主站,主要记载学习笔记,包括但不限于Java多线程、设计模式、MySQL及Git等各.zip

    在本项目中,作者使用了docsify框架来创建一个个人学习主站,旨在记录和分享其在多个IT领域的学习笔记,主要包括Java多线程、设计模式、MySQL数据库以及Git版本控制等方面的知识。以下是对这些主题的详细阐述: 1. ...

    Spring MVC 学习笔记 十二 PDF/Excel格式输出

    这个设计模式有助于实现代码的分离,提高可维护性和可测试性。 首先,让我们从配置开始。Spring MVC的配置通常在`web.xml`中初始化DispatcherServlet,这是处理所有HTTP请求的前端控制器。接着,我们会在`spring-...

    设计模式-读书笔记(水印)1

    设计模式的学习和应用对于提升软件设计的灵活性、可维护性和可扩展性至关重要。在Python等编程语言中,设计模式的实践有助于构建更加健壮和高效的系统。遵循设计模式的主要原则,如单一职责原则、里氏替换原则、依赖...

    设计模式资料

    设计模式是软件工程中的一种重要思想,它是在特定情境下为..."良葛格总结的设计模式笔记"可能包含了对这些模式的深入讲解,包括它们的概念、实现方式、适用场景及优缺点分析,对于学习和提升设计模式理解非常有帮助。

    使用docsify搭建的个人学习主站,主要记载学习笔记,包括但不限于Java多线程、设计模式、MySQL及Git等各种工具

    首先,docsify是一款轻量级的静态站点生成器,它无需预渲染,直接在客户端动态渲染页面,使得搭建过程简单快捷。要开始搭建个人学习主站,你需要先在本地创建一个目录,然后在该目录下初始化一个docsify项目,通过...

    F2812学习笔记

    ### F2812学习笔记知识点详述 #### 一、如何开始DSP的学习 - **基础知识了解**:首先,快速浏览整个书籍,了解DSP的基本概念和技术背景,掌握DSP的总体框架。 - **学习资料的选择**:选择合适的教材或参考资料非常...

Global site tag (gtag.js) - Google Analytics