您的位置:知识库 » 软件工程

生成器模式(又名建造者模式、Builder Pattern)

作者: 天津城建学院软件工程  来源: 博客园  发布时间: 2010-12-05 15:39  阅读: 2056 次  推荐: 0   原文链接   [收藏]  

  模式名称:生成器模式

  1.问题描述

  生活场景:你玩过种地、种花等类似的游戏吗?这是最近很流行的游戏哟!下面就是从种花游戏中剪切的四个花盆(盆景),很漂亮吧!你将不同的种子放入花盆,一段时间后你就可以看到各种美丽的鲜花了,不同种子所生产出来的鲜花有不同的花朵、叶子和枝茎。编码该如何实现呢?

                          

  设计目标:将种子放入花盆,一段时间后就可以收获美丽的鲜花! 

  2.不假思索的思路:将盆景看做一个类,有几个盆景我new几个对象,直接完成这一奇妙过程。

  设计类图:

                      

/**
* 荷花盆景
*/
public class WaterlilyFlowerpot {
public String name;
//
public String stem;
//
public String leaf;
//
public String flower;

public void grow(){

//说明种类
name = "荷花";

//生产茎
stem = "40厘米";

//生产叶子
leaf = "圆形";

//生产花
flower = "白里透红";

}
public void create(){
System.out.println(name
+ " : 茎"+" - "+stem+" , 叶"+" - "+leaf+" , 花"+" - "+flower);
}
}

/**
* 玫瑰盆景
*/
public class RoseFlowerpot {
public String name;
//
public String stem;
//
public String leaf;
//
public String flower;

public void grow(){

//说明种类
name = "玫瑰";

//生产茎
stem = "20厘米";

//生产叶子
leaf = "椭圆形";

//生产花
flower = "大红大白";

}
public void create(){
System.out.println(name
+ " : 茎"+" - "+stem+" , 叶"+" - "+leaf+" , 花"+" - "+flower);
}
}
/**
* 场景类
*/
public class Client {
public static void main(String[] args){
//开始种玫瑰花
RoseFlowerpot rfp = new RoseFlowerpot();
rfp.grow();
//盛开
rfp.create();
//玫瑰 : 茎 - 20厘米 , 叶 - 椭圆形 , 花 - 大红大白 半径5厘米

//开始种荷花
WaterlilyFlowerpot wf = new WaterlilyFlowerpot();
wf.grow();
//盛开
wf.create();
//荷花 : 茎 - 40厘米 , 叶 - 圆形 , 花 - 白里透红 半径10厘米
}
}

  缺点:

      耦合性强,并且有大量代码是重复的。如果想对叶子做一些修改,茎和花的代码也要跟着重写。在这个例子中你可能觉得写一写茎和花的也不费什么事,可真要是想写出像图片中那么漂亮的鲜花的话,每一部分的代码都是很多的,并且这些代码都放在在盆景类中,会让盆景这个类显得很臃肿。那么怎么改?     

  3.归纳阶段:

      耦合性强就要解耦,代码臃肿就要简化和分离。我们需要将盆景这个复杂的类分解成相对简单的类,比如将花盆和鲜花分离,使得同样的花盆可以生长出不同的鲜花,然后再将鲜花分成几个简单的类,使得某一部分的修改不影响其他部分;这也就是生成器模式。 其定义:Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)

  结构类图:

/**
* 花朵的茎

*/
public class Stem {
private String name = "";
private String length;

public Stem(){
this.length = "5厘米";
}
public Stem(String length){
this.length = length;
}
public String getName() {
return name;
}

public String getLength() {
return length;
}
}
/**
* 叶子
*/
public class Leaf {
private String name = "";
private String shape;

public Leaf(String shape){
this.shape = shape;
}
public Leaf(){
this.shape = "圆形";
}
public String getName() {
return name;
}
public String getShape() {
return shape;
}

}
/**
* 花
*/
public class Flower {
private String name = "";
private String color;
private String radius;
public Flower(){
this.color = "大红大白";
this.radius = "5厘米";
}
public Flower(String color,String radius){
this.color = color;
this.radius = radius;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getRadius() {
return radius;
}
public String getColor() {
return color;
}

}



/**
* 以下属性应该为私有,设为公有纯粹是为了方便说明问题并减少代码量
*
@author 谭鹏飞
*
*/
public abstract class Seed {
public String name;
//
public Stem stem;
//
public Leaf leaf;
//
public Flower flower;

public abstract void grow();
}


/**
* 玫瑰类
*/
public class Rose extends Seed{
public Rose(Stem stem,Leaf leaf,Flower flower){
//说明种类
name = "玫瑰";

//生产茎
this.stem = stem;

//生产叶子
this.leaf = leaf;

//生产花
this.flower = flower;
}
public Rose(Stem stem){
this(stem,new Leaf(),new Flower());
//说明种类
name = "玫瑰";
}
public Rose(){
this(new Stem(),new Leaf(),new Flower());
//说明种类
name = "玫瑰";
}
public void grow(){

System.out.println(name
+ " : "+stem.getName()+" - "+stem.getLength()+" , "+leaf.getName()+" - "+leaf.getShape()+" , "+flower.getName()+" - "+flower.getColor()+" 半径"+flower.getRadius());
}
}

/**
* 场景类
*/
public class Client {

public static void main(String[] args) {
// TODO Auto-generated method stub
Seed rose = new Rose();
Soil soil
= new Soil(rose);
soil.create();
//玫瑰 : 茎 - 5厘米 , 叶 - 圆形 , 花 - 大红大白 半径5厘米
}

}

  设计体会:

  世界上没有两片完全相同的树叶,将构建具体树叶的细节与构建树的表示分离,从而避免了为修改一片树叶而重写了一棵树的麻烦!

  4.验证阶段

  让上例中的玫瑰的茎再长高5厘米,而不改动叶子和花部分的代码。除场景类外,其他类均不变化,重复代码不再赘述。

/**
* 场景类
*/
public class Client {

public static void main(String[] args) {

//如果你想将花朵长高一点,其它部分不变,没问题,而且改动也不多
Stem stem = new Stem("10厘米");
Seed tallrose
= new Rose(stem);
soil
= new Soil(tallrose);
soil.create();
//玫瑰 : 茎 - 10厘米 , 叶 - 圆形 , 花 - 大红大白 半径5厘米
}

}

  5.抽象描述

  思路描述:

  该模式的核心就是分离细节、推迟细节的现实。上面用类来实现细节的分离只是一个小例子 ,你也可以用抽象方法,将细节推迟到子类实现等。不管你用什么方法分离出了细节,再组合回来的时候,你又可以增加许多的操作,比如各个部分的比例、顺序等。生成器模式本身需要和其他模式结合使用,最经常结合的就是模板模式(用于生成具体的子类),其他要根据实际情况而定。

  类结构图:

                                     

0
0

软件工程热门文章

    软件工程最新文章

      最新新闻

        热门新闻