Java设计模式:生成器模式

问题的提出:

有些类很容易创建对象,直接调用其构造方法,例如Student student = new Student(“1001”,”zhang”,21); 之所以容易创建,因为其类成员都是基本数据类型或者封装类,或者字符串。但是如果对象的类成员还是对象,那么创建这个对象还需要产生该对象成员的具体对象。

public class Unit1 {
}

public class QuestionProduct {
    Unit1 u1;
    Unit2 u2;
    Unit3 u3;    public void createUnit1(){
        u1 = new Unit1();
    }    public void createUnit2(){
        u2 = new Unit2();
    }    public void createUnit3(){
        u3 = new Unit3();
    }    public void composite(){

    }    public static void main(String[] args) {
        QuestionProduct p = new QuestionProduct();
        p.createUnit1();
        p.createUnit2();
        p.createUnit3();
        p.composite();
    }
}

Unit123为各java对象,在main方法可以知道,只有当运行完p.composite()方法后,Product才真正的创建起来,问题来了,如果有两类Product对象,又或许有很多类成员。又或者随着Product产品种类的增加和减少,必须修改已有的源代码。于是为了解决这类问题,生成器模式应运而生!

生成器模式的主要思路是:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。简单来说,不在同一类里面创建该类的类成员,而是把类成员的创建交给另一个类,该类就叫做生成器!

public interface IBuild {    public Product create();
}

public class BuildProduct implements IBuild {
    Product p = new Product();    public void createUnit1(){        //创建u1    }    public void createUnit2(){        //创建u2    }    public void createUnit3(){        //创建u3    }    public Product composite(){        //关联Unit1,Unit2,Unit3
        return p;
    }    public Product create(){
        createUnit1();
        createUnit2();
        createUnit3();        return composite();
    }
}

通过上面的代码可以知道,如果需求分析发生变化,只需要增加或者删除相应的生成器类BuildProduct即可,并不需要修改已有的类代码。

在这基础上,再定义一个调度类,是对生成器接口的IBuild的封装。

public class Director {    private IBuild iBuild;    public Director(IBuild iBuild){        this.iBuild = iBuild;
    }    public Product build(){        //System.out.println("test");        iBuild.createUnit1();
        iBuild.createUnit2();
        iBuild.createUnit3();        return iBuild.composite();
    }    public static void main(String[] args) {
        IBuild iBuild = new BuildProduct();
        Director director = new Director(iBuild);
        Product p = director.build();
    }
}

这样就构成生成器模式的一般模式了!一般分为以下三个步骤

1)定义产品类

2)定义n个生成器Build类

3)定义一个统一调度类Director类

对于Director的理解:与常规的接口相比,生成器接口IBuild是特殊的,它是一个流程控制接口。该接口中定义的方法必须依照某种顺序执行,一个都不能少。因此在程序中一个要体现出“流程”这一特点。而Director类的作用就是对“流程”的封装类,其中的build方法决定了具体的流程控制过程。

对于上面的生成器模式,假如要生成两种Product产品,一种需要三种过程,一种需要四种过程,那么用上面的生成器模式(Model1)就不行了,因为它要求创建产品的过程必须相同(Interface IBuild定义好了创建的过程)。于是引起下面Model2的设计。

Model2:IBuild接口仅仅定义多态create()方法

public interface IBuild {    public Product create();
}

而在具体生成器类重写多态create()方法,并调用多个个非多态方法,最终返回Product对象。

public class BuildProduct implements IBuild {
    Product p = new Product();    public void createUnit1(){        //创建u1    }    public void createUnit2(){        //创建u2    }    public void createUnit3(){        //创建u3    }    public Product composite(){        //关联Unit1,Unit2,Unit3
        return p;
    }    public Product create(){
        createUnit1();
        createUnit2();
        createUnit3();        return composite();
    }
}

Director类

public class Director {    private IBuild iBuild;    public Director(IBuild iBuild){        this.iBuild = iBuild;
    }    public Product build(){        return iBuild.create();
    }
}

对代码进行仔细分析可以发现,具体生成器多态的create()方法中包含了创建Product对象的全过程,Director类中的方法就显得重复了。在这种设计中其实是可以省略Director类的,这就说明了在生成器模式中,抽象生成器和具体生成器是必须的。

而指挥类需要在实际问题中认真考虑,加以取舍!进一步思考,可以把IBuild定义成泛型接口,不仅仅是Product产品,也可以是其他需要生成器魔术的产品都可以从这接口派生。

除了以上两种实现方式,还有第三种生成器功能的设计模式。

Model3:利用Product派生方法,可以实现类似生成器功能

具体代码如下

1.Product类

 

2.生成器BuildProduct类

 

3.指挥者类Director

 

总而言之,对于生成器模式创建复制对象而言,主要的原则还是对象构建过程与表示相分离。这是一个总的思想,实现具体形式不是一成不变,大可以设计自己专属的生成器模式框架。重要的是思想,而不是实现形式!

最后再说说生成器模式的应用场景,其中一个比较重要的作用就是解决同流程,异界面的手段之一。

例如在登录下常常都会分不同的角色,比如教务系统登录区分教师和学生。一般的应用也分为管理员以及普通用户。不同的角色登录后或显示不同的页面。下面就教学管理系统这个例子简单说明。

        

学生的具体信息在student表中,教师的具体信息在teacher表中。一个常用的功能是:管理员为学生和教师在login表中分配了用户名和账号,同时在student和teacher表中建立关键字user的记录。但是其他具体信息如姓名年龄等是空的。

因此需要学生或者教师在登录后首先完善个人信息。下面正是利用生成器模式设计“个人信息完善”的基础代码。

Mysql 表的简单设计

 

1)界面抽象生成器UIBuilder

package BuildModel.Example;import javax.swing.*;/**
 * Created by lenovo on 2017/4/18. */public abstract class UIBuilder {    protected JPanel panel = new JPanel();    abstract public void addUI();                   //形成界面
    abstract public void registerMsg();             //注册消息
    abstract public void initialData(String user);  //初始化界面数据
    public JPanel getPanel(){                       //返回界面面板对象
        return panel;
    }
}

2)具体学生界面生成器类StudentBuilder

 

3)DbProc数据库自定义封装类(注意测试时候strPwd要加上自己本地mysql的账户密码)

 

4)具体教师界面生成器TeacherBuilder(类似,这里就不写了)

5)流程指挥类Director

package BuildModel.Example;import javax.swing.*;/**
 * Created by lenovo on 2017/4/18. */public class Director {    private UIBuilder builder;    public Director(UIBuilder builder){        this.builder = builder;
    }    public JPanel build(String user){
        builder.addUI();                //初始化界面
        builder.registerMsg();          //登记消息
        builder.initialData(user);      //填充账号为user的初始界面显示数据
        return builder.getPanel();
    }
}

6)测试类

 

当然这只是简单的测试代码,在实际应用中还要注意很多问题。

时间: 2024-10-18 02:52:11

Java设计模式:生成器模式的相关文章

Java设计模式--生成器模式

将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示. Builder Pattern Separate the construction of a complex object from its representation so that the same construction process can create different representations. 类图 模式的结构与使用 生成器模式的结构中包括四个角色. 产品(Product):具体生成器要构造的复

Java 设计模式 -- 复合模式之二

接着上文的鸭鸣例子:Java 设计模式 -- 复合模式之一 上文中,我们的鸭鸣实现了 装饰者模式  适配器模式  工厂模式的结合 现在,又需要进行改动了,上文,是可以统计一群鸭子的叫声,现在需要能够观察个别鸭子的行为 引入观察者模式: 任何想被观察的Quackable都必须实现下面的接口 public interface QuackObservable { public void registerObserver(Observer observer); public void notifyobs

一起学java设计模式--代理模式(结构型模式)

代理模式 应用软件所提供的桌面快捷方式是快速启动应用程序的代理,桌面快捷方式一般使用一张小图片来表示(Picture),通过调用快捷方式的run()方法将调用应用软件(Application)的run()方法.使用代理模式模拟该过程,绘制类图并编程实现. package ProxyPattern; interface Software { void run(); } class Application implements Software { public void run() { Syste

Java设计模式-代理模式之动态代理(附源码分析)

Java设计模式-代理模式之动态代理(附源码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的区别就是:动态代理是在运行时刻动态的创建出代理类及其对象.上篇中的静态代理是在编译的时候就确定了代理类具体类型,如果有多个类需要代理,那么就得创建多个.还有一点,如果Subject中新增了一个方法,那么对应的实现接口的类中也要相应的实习该方法,不符合设计模式原则. 动态代理的做法:在运行时刻,可以动态创建出一个实现了多个接口的代理类.每个代理类的对象都会关联一个表示内部处理

Java设计模式-代理模式之动态代理(附源代码分析)

Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代理是在编译的时候就确定了代理类详细类型.假设有多个类须要代理.那么就得创建多个. 另一点,假设Subject中新增了一个方法,那么相应的实现接口的类中也要相应的实现这些方法. 动态代理的做法:在执行时刻.能够动态创建出一个实现了多个接口的代理类.每一个代理类的对象都会关联一个表示内部处理逻辑的Inv

Java设计模式-代理模式之静态代理

Java设计模式-代理模式之静态代理 概念 为另一个对象提供一个替身或占位符以提供对这个对象的访问,使用代理模式创建代表对象,让代表对象控制某对象的访问,被代理对象可以是远程的对象.创建开销大的对象或需要安全控制的对象 远程代理控制访问远程对象 虚拟代理控制访问创建开销大的资源 保护代理基于权限控制对资源的访问 看如下的类图: 仔细看上面的类图,首先是Subject它为RealSubject和Proxy提供了接口,通过实现同一个接口,Proxy在RealSubject出现的地方取代它,这点和适配

设计模式-生成器模式

前言 点击查看:设计模式系列 生成器模式(建造者模式/builder) 定义:将一个复杂的对象,分成多分,使同样的构建过程,能有不同的表示,这样的设计模式被称为建造者模式. 举例说明: 李嘉诚的遗嘱执行: 财产(产品角色):李嘉诚拥有众多复杂的财产框架,这里以现金与物品入例. 遗嘱(建造者):相当于建造者,分配现金与物品. 具体遗嘱(具体建造者):1.给大儿子的财产分配,2,给小儿子的财产分配. 律师(指导者角色):按照具体的遗嘱指令分配财产. 例子类图: 庞大的财产结构代码: // 财产(复杂

iOS设计模式——生成器模式

选择建造自己的房子的人会把工程外包给承包商.单一承包商不能建造整个房子,他将其分解为几个部分,然后转包给几个实际的建筑商,他们懂得如何将零部件组装起来.房子由由风格.颜色和尺寸各不相同的部件组成.客户告诉承包商房子里都要有什么,然后承包商协调各房屋建筑商,决定需要做什么.应该如何建造,建筑商就如何施工.建房子是个复杂过程,单凭一双手就想建房子,即便可能也非常困难.如果承包商(指导者)与懂得如何建造的建筑商相互协调,这一过程简单得多且更易管理. 有时,构建某些对象有多种不同方式.如果这些逻辑包含在

跟着实例学习设计模式-生成器模式(builder)

生成器模式是创建型设计模式. 设计意图:将一个复杂的类表示与其构造相分离,使得相同的构建过程能够得出不同的表示. 实例类图: IVehicleBuilder:抽象建造者,为创建一个Vehicle对象并创建它的相关部件指定的抽象接口,把产品的生产过程分解为不同的步骤,从而使具体的建造者在具体的建造步骤上具有更多弹性,从而创造出不同表示的产品.(这里就是小车和卡车) CarBuilder.TrunkBuilder:具体建造者,实现IVehicleBuilder接口,构造和装配产品的各个部件定义并明确

Java设计模式——迭代器模式

概述 网上大部分人说迭代模式的时候,总是以某一种可遍历的对象为例进行介绍.这是可行的,这也是迭代模式的基本原型.当我看到<Head Frist设计模式>中迭代模式的时候,感觉要是能从另一个角度来说明,可能更能够体现迭代模式的威力所在. 本文介绍的这种迭代模式,倒是更像是适配器-迭代器模式.希望于你有益~ 版权说明 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:Coding-Naga发表日期: 2016年3月4日链接:http://blog.csdn.net/lemo