白话设计模式——Builder

 

生成器模式,用于创建复杂对象。当我们的软件系统中出现了这样的情况时——我们需要一个比较复杂的对象,它的外观(接口)我们是知道的,但是他的组成(各种各样的组成)我们并不关心,而且他的构造过程(比如先后顺序)我们也不关心——这时,我们就需要用到Builder模式了。

还是拿广本来打比方。广本的四个车间,最开头的是冲压科,而在冲压科的门口有一间小房子,里面放了一台激光焊接机,它用它的机械手臂抓起旁边放着的各种各样的钢板,不停的焊接。可能有人要问,这是什么例子?这就是生成器!一般来说,汽车各处外壳的厚度以及硬度是不同的,比如车头部分就要够硬(用来撞的^_^),其他一些地方比如车顶就没有必要用超厚的钢板。这样,一来可以降低整车的质量,可以省油;二来可以降低成本(所以广本暴利啊~~其实其他汽车厂家也这么干)先前所讲的焊接机就是干这个事情的,它将各种不同厚度不同硬度的钢板焊接在一起,供那些巨型的冲压机来冲压成型,以生产汽车的各个不同的部分。各种汽车所使用的合成钢板的组成是不一样的,但冲压机不管那么多,它只管压钢板。这样一来就明白了吧?焊接机将各种钢板按照规定焊接成不同组成的合成钢板,至于它是如何焊接的以及合成钢板的组成,冲压机对这些信息是不关心的。

我们来看一个类图。

白话设计模式——Builder_第1张图片

 

 

这张简单的类图跟《设计模式》书中有显著的不同。因为我主要是用来说明上面的例子的,跟书中提及的例子不同。这个图中,焊接机由焊接程序控制,以生产不同规格的钢板,冲压机仅仅是调用焊接机的GetSteel方法来获得焊好的钢板。其实,这样的情况在我们平时的程序中用得更多一些,即某一个类仅仅是要得到一个产品,而产品的一切信息它均不知晓。当我们需要另外一种规格的钢板时,更换相应的程序就可以了。

MS给我们的类库中,有一个叫做StringBuilder的类,这就是一个例子。我们给它不同的字符串或是其他对象(这些就可以看作是原材料),根据我们输入的顺序(组装过程),我们可以得到我们想要的一个字符串。

把这个类图串换成代码(这个代码实在不怎么样,还好,这只是一个说明,如果我在工作中写出这样的东西来,我就可以体验一下从17楼飞下的感觉了,^_^

Builder
    public class Steel
    
{
        
public object Part00;
        
public object Part01;
        
public object Part10;
        
public object Part11;
    }


    
public class WeldingProgramme
    
{
        
object[] _materials;
        
public WeldingProgramme()
        
{
            
this._materials = new object[4];

            
// TODO: Add some materials
        }

        
public Steel Go()
        
{
            SteelWelder sw 
= new SteelWelder();
            
foreach(object m in this._materials)
            
{
                sw.WeldSteel(m);
            }


            
//    you can weld the steel like this
            
//    sw.WeldSteel(this._materials[3]);
            
//    sw.WeldSteel(this._materials[2]);
            
//    sw.WeldSteel(this._materials[1]);
            
//    sw.WeldSteel(this._materials[0]);


            
//    also, you can do it like this
            
//    sw.WeldSteel(this._materials[2]);
            
//    sw.WeldSteel(this._materials[1]);
            
//    sw.WeldSteel(this._materials[0]);
            
//    sw.WeldSteel(this._materials[3]);

            
return sw.GetSteel();
        }

    }


    
public class SteelWelder
    
{
        Steel _steel;
        
public void WeldSteel(object materials)
        
{
            
if(this._steel == null)
                
this._steel = new Steel();
            
if(this._steel.Part00 == null)
            
{
                
this._steel.Part00 = materials;
            }

            
else if(this._steel.Part01 == null)
            
{
                
this._steel.Part01 = materials;
            }

            
else if(this._steel.Part10 == null)
            
{
                
this._steel.Part10 = materials;
            }

            
else if(this._steel.Part11 == null)
            
{
                
this._steel.Part11 = materials;
            }

            
else
            
{
                
throw new Exception("what do you want?");
            }

        }

        
public Steel GetSteel()
        
{
            
return this._steel;
        }

    }


    
public class Punch
    
{
        
private Steel _steel;

        
public void Work()
        
{
            WeldingProgramme wp 
= new WeldingProgramme();
            
this._steel = wp.Go();

            
// TODO: Punch the Steel
        }

    }

 

从类图以及代码实例中,我们看到Builder的一些优势了。在我们需要不同的原料以生产不同的产品时,不用更改一大片的代码,仅仅更改指导Builder工作的向导就可以了。在本例中,也就是更改焊接程序,根本不会有什么产品的抽象类。我们当然也可以实现一个Builder的父类,以实现更多的产品的制造。

生成器模式主要用的地方就是组合一些比较复杂的产品,而且这个产品的组合方式是多种多样的。


回到目录
上一篇:Abstract Factory
下一篇:Factory Method

你可能感兴趣的:(白话设计模式——Builder)