C#设计模式之建造者模式

前言

本来以为这个模式也很简单呢,结果和小弟两个人被它玩了好几个小时。不过最终我们还是战胜了它,太有成就感了!
下面来讲一下我的认识。
(这里先说一点,客户端代码是写在窗体的picturebox里面的)

建造者模式

英文:Builder
又名:生成器模式

what

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
它可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。
使用建造者模式,用户只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。

结构图:

建造者模式
拿这次代码的建造小人来举例子,分别解释一下组成部分:

Builder:
抽象类→建造小人的各个部分。概括来说,是为了创建一个product对象的各个部件指定的抽象接口。

ConcreteBuilder:
具体的小人建造者,具体实现如何画出小人的各个部分。是一个具体建造者,实现Builder接口,构造和装配各个部件

Product:
具体的小人,具体产品角色

Director:
指挥者,用来根据用户的需求来构建小人对象。,主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。

场景

我们去饭馆吃饭时,没准今天老板心情不好,多放了一些盐,这次的美食相遇可能就不欢而散了。那么为什么肯德基麦当劳的食品每次都是同一个味道呢?因为他们不是凭感觉去做菜,而是依据流程,到哪一步都有严格的规定。与其说是规定,还不如说是,模板。这里感觉像是在介绍之前刚学到的模板方法模式啊。但是肯定二者还是有区别的。以后会再进行剖析。将固定的每一步都设置成一个类,其他需求再去建造。就像吃肯德基一样,同样都是油炸食品,有的人要加辣椒,有的人则要番茄。但是工序的每一步都是相同的。哪一味配料丢失也会造成味蕾的嫌弃。

应用

建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。

代码展示

今天敲的这个是在form里面运行的。这里有个新知识点,就是需要引用drawing。否则

抽象建造类: 引用drawing

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing ;

namespace 建造者模式1
{
    abstract class PersonBuilder
    {
        protected Graphics g;  //引用drawing
        protected Pen p;

        public PersonBuilder(Graphics g, Pen p)
        {
            this.g = g;
            this.p = p;
        }

        //各个部位
        public abstract void BuildHead();
        public abstract void BuildBody();
        public abstract void BuildArmLeft();
        public abstract void BuildArmRight();
        public abstract void BuildLegLeft();
        public abstract void BuildLegRight();
    }

具体类—瘦子类:

using System.Drawing ;

namespace 建造者模式1
{
    class PersonThinBuilder:PersonBuilder 
    {
        public PersonThinBuilder (Graphics g,Pen p):base(g,p)
        {}

        //重写抽象方法

        public override void BuildHead()
        {
            g.DrawEllipse (p,50,20,30,30);
        }

        public override void BuildBody()
        {
            g.DrawRectangle (p,60,50,10,50);
        }

        public override void BuildArmLeft()
        {
            g.DrawLine (p,60,50,40,100);
        }

        public override void BuildArmRight()
        {
            g.DrawLine (p,70,50,90,100);
        }

        public override void BuildLegLeft()
        {
            g.DrawLine (p,60,100,45,150);
        }

        public override void BuildLegRight()
        {
            g.DrawLine (p,70,100,85,150);
        }
    }

指挥者类:

class PersonDirector
    {
        private PersonBuilder pb;
        public PersonDirector(PersonBuilder pb)
        {
            this.pb = pb;
        }

        public void CreatePerson()
        {
            pb.BuildHead();
            pb.BuildBody();
            pb.BuildArmLeft();
            pb.BuildArmRight();
            pb.BuildLegLeft();
            pb.BuildLegRight();
        }

窗体:
加载一个picturebox控件,单击完成实现。

//这里也要引用drawing
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }



        private void pictureBox1_Click(object sender, EventArgs e)
        {
            Pen p = new Pen(Color.Red);
            PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1.CreateGraphics(), p);
            PersonDirector pdThin = new PersonDirector(ptb);
            pdThin.CreatePerson();

            Console.ReadLine();
        }

    }

效果图:

建造者

一个小人儿就这样出来啦!

后记

吐槽:
看一下小弟的小人儿:
只有头。。。。
小人儿

只有半身。。。

小人儿

我们两个神人还很认真的挑代码的错,结果。。。
picturebox控件放的太小了,以至于里面只能放下半张头!哈哈~真是笑煞老夫~~
(笑得眼泪都出来啦)

看来以后再调试,不能只局限于代码啊,真的是要统观全局,面面俱到!走起~

猜你喜欢

转载自blog.csdn.net/carrie_q/article/details/80535506