大话设计模式,让你的代码更完美8---建造者模式

来源:互联网 发布:数据库镜像原理 编辑:程序博客网 时间:2024/06/04 19:06

需求:用程序画一个小人,要求有双手,有双脚,有身体,有头。

当让某个人一次又一次的做同一样事情时,比如说画多个小人,有小胖人、小瘦人等等(它们都具有双手,有双脚,有身体,有头)。。。。

随着次数的增多,编码者就会因为枯燥而懈怠,偶然中必然会发生代码缺少的问题(比如说少了一只手或腿等等。。。。)举例说明:

菜鸟代码:

        private void button1_Click(object sender, EventArgs e)        {            Pen p = new Pen(Color.Yellow);            Graphics gThin = pictureBox1.CreateGraphics();            gThin.DrawEllipse(p, 50, 20, 30, 30);            gThin.DrawRectangle(p, 60, 50, 10, 50);            gThin.DrawLine(p, 60, 50, 40, 100);            gThin.DrawLine(p, 70, 50, 90, 100);            gThin.DrawLine(p, 60, 100, 45, 150);            gThin.DrawLine(p, 70, 100, 85, 150);            Graphics gFat = pictureBox2.CreateGraphics();            gFat.DrawEllipse(p, 50, 20, 30, 30);            gFat.DrawEllipse(p, 45, 50, 40, 50);            gFat.DrawLine(p, 50, 50, 30, 100);            gFat.DrawLine(p, 80, 50, 100, 100);            gFat.DrawLine(p, 60, 100, 45, 150);            gFat.DrawLine(p, 70, 100, 85, 150);        }
对菜鸟的代码进行分离(分离只能降低和客户端的耦合性,不能降低代码的缺失问题):

    ///瘦人    class PersonThinBuilder    {        private Graphics g;        private Pen p;        public PersonThinBuilder(Graphics g, Pen p)        {            this.g = g;            this.p = p;        }        public void Build()        {            g.DrawEllipse(p, 50, 20, 30, 30);            g.DrawRectangle(p, 60, 50, 10, 50);            g.DrawLine(p, 60, 50, 40, 100);            g.DrawLine(p, 70, 50, 90, 100);            g.DrawLine(p, 60, 100, 45, 150);            g.DrawLine(p, 70, 100, 85, 150);        }    }    ///胖人    class PersonFatBuilder    {        private Graphics g;        private Pen p;        public PersonFatBuilder(Graphics g, Pen p)        {            this.g = g;            this.p = p;        }        public void Build()        {            g.DrawEllipse(p, 50, 20, 30, 30);            g.DrawEllipse(p, 45, 50, 40, 50);            g.DrawLine(p, 50, 50, 30, 100);            g.DrawLine(p, 80, 50, 100, 100);            g.DrawLine(p, 60, 100, 45, 150);            g.DrawLine(p, 70, 100, 85, 150);        }    }
画画事件:

        private void button1_Click(object sender, EventArgs e)        {            Pen p = new Pen(Color.Yellow);            Graphics gThin = pictureBox1.CreateGraphics();            PersonThinBuilder ptb = new PersonThinBuilder(gThin, p);            ptb.Build();            Graphics gFat = pictureBox2.CreateGraphics();            PersonFatBuilder pfb = new PersonFatBuilder(gFat, p);            pfb.Build();        }
建造者模式,将一个复杂对象的构建和他的表示进行分离,使得同样的构造过程可以创建不同的表示,使代码绝对稳定,不会出现缺胳膊少腿现象。


老鸟代码:

///人类建造模式abstract class PersonBuilder{    protected Graphics g;    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();}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 PersonFatBuilder : PersonBuilder{    public PersonFatBuilder(Graphics g, Pen p)        : base(g, p)    { }    public override void BuildHead()    {        g.DrawEllipse(p, 50, 20, 30, 30);    }    public override void BuildBody()    {        g.DrawEllipse(p, 45, 50,40, 50);    }    public override void BuildArmLeft()    {        g.DrawLine(p, 50, 50, 30, 100);    }    public override void BuildArmRight()    {        g.DrawLine(p, 80, 50, 100, 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();        }    }
为什么这里要创建外观模式类,这样做有什么好处:

一是用来控制建造过程,

二是隔离用户与建造过程的关联(具体见上一章)

三是让用户可以随时根据自己的选择如何一步一步来建造小人(比如说小人的头、脚先后建造顺序,完全可以在这里进行设置)

四是让用户可以随时根据自己的选择建造什么样的小人(比如说,缺了一只脚,多了一只手的等等)

触发事件代码:

            Pen p = new Pen(Color.Yellow);            PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1.CreateGraphics(), p);            PersonDirector pdThin = new PersonDirector(ptb);            pdThin.CreatePerson();            PersonFatBuilder pfb = new PersonFatBuilder(pictureBox2.CreateGraphics(), p);            PersonDirector pdFat = new PersonDirector(pfb);            pdFat.CreatePerson();

结构图:


建造者模式结构图(Product是具体的小人,即click事件代码里面的小人对象):

建造者模型基本代码:

    class Program    {        static void Main(string[] args)        {            Director director = new Director();            Builder b1 = new ConcreteBuilder1();            Builder b2 = new ConcreteBuilder2();            director.Construct(b1);            Product p1 = b1.GetResult();            p1.Show();            director.Construct(b2);            Product p2 = b2.GetResult();            p2.Show();            Console.Read();        }    }    ///抽象产品类,确定产品由A和B组成,并声明了一个产品获取的方法    abstract class Builder    {        public abstract void BuildPartA();        public abstract void BuildPartB();        public abstract Product GetResult();    }    ///指挥者类,用来指挥建造过程    class Director    {        public void Construct(Builder builder)        {            builder.BuildPartA();            builder.BuildPartB();        }    }    ///产品,由组件组成    class Product    {        IList<string> parts = new List<string>();        public void Add(string part)        {            parts.Add(part);        }        public void Show()        {            Console.WriteLine("\n产品 创建 ----");            foreach (string part in parts)            {                Console.WriteLine(part);            }        }    }    ///具体构造者类1    class ConcreteBuilder1 : Builder    {        private Product product = new Product();        public override void BuildPartA()        {            product.Add("部件A");        }        public override void BuildPartB()        {            product.Add("部件B");        }        public override Product GetResult()        {            return product;        }    }    ///具体构造者类2    class ConcreteBuilder2 : Builder    {        private Product product = new Product();        public override void BuildPartA()        {            product.Add("部件X");        }        public override void BuildPartB()        {            product.Add("部件Y");        }        public override Product GetResult()        {            return product;        }    }

不行了,脑子不转了,先不写代码运行流程了,改日再写!


0 0
原创粉丝点击