当前位置: 首页 > news >正文

【设计模式】好菜每回味不同 --- 建造者模式

一,概述 

        Builder模式的定义是:将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 首先它意图是要构建一个复杂的对像,而这个复杂的对像往往需要由好几个子对像或分步骤来完成最终的这个对象的构建,而这个复杂对象的子对像经常需要不断的变化,但它的构建过程是相对是稳定的。

        精髓:通过一个统一的工序或者约束构造出同一的对象。


二,引例

        1)构造一个小人,需要有脚、手、身体、头

              缺点:这样构造的小人,容易忘记构造手,脚之类的。


        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);


        }

        2)构造小人二

              改进之处:为了避免每次构建小人,有可能出错,所以将构建小人的方法写入一个类,每次构造时候,调用构造方法。

              缺点:如果再构造一个高个子类,忘记画腿或者胳膊怎么办?

                         解决办法:构建一个人的基本类,把要实现的方法都写成纯虚函数。这样避免缺少某一部分了

private class PersonThinBuilder //瘦子类 
{
    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 //胖子类 
{
    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);
    }
}
       

            3)建造者模式

            说明:如果有的小人需要画的更细,则只需要在特定小人里面添加相应的函数即可。只有在每个类都需要创建的时候才需要写到抽象类中。


namespace 建造者模式
{
abstract class PersonBuilder//抽象类 
{
    protected Graphics g;
    protected Pen p;

    public PersonBuilder(Graphics g, Pen p)
    {
        this.g = g;
        this.p = p;
    }
       //如果是C++的话就要写成纯虚函数的形式 
    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();
    }
}
}

 private void button1_Click(object sender, EventArgs e)
        {
            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();

        }


三,建造者模式解析

        

using System;
using System.Collections.Generic;
using System.Text;

namespace 建造者模式
{
	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);
            }
        }
    }
    
    abstract class Builder//抽象类,规定必须实现的三个部分 
    {
        public abstract void BuildPartA();
        public abstract void BuildPartB();
        public abstract Product GetResult();
    }
    

    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;
        }
    }

    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;
        }
    }

    
    class Director //整体实现各个子模块 
    {
        public void Construct(Builder builder)//传入的是抽象类,可以真正传入具体实现类的对象。 
        {
            builder.BuildPartA();
            builder.BuildPartB();
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Director director = new Director();
            Builder b1 = new ConcreteBuilder1();
            Builder b2 = new ConcreteBuilder2();

            director.Construct(b1);//指挥者用Builder1 构建产品 
            Product p1 = b1.GetResult();//获取构建的产品 
            p1.Show();

            director.Construct(b2);
            Product p2 = b2.GetResult();
            p2.Show();

            Console.Read();
        }
    }

}







        

转载于:https://www.cnblogs.com/secbook/archive/2012/06/28/2654980.html

相关文章:

  • tmux命令使用总结
  • 排序05-快速排序
  • 大数据变现之琅琊榜是怎样炼成的
  • 网站安全检测:推荐8款免费的 Web 安全测试工具
  • 世界最大的两个BT网站被迫下线 ExtraTorrent遭遇DDoS攻击
  • 2012年7月2日
  • Radware荣获ICSA实验室“卓越信息安全测试奖”
  • struts2之ModelDriven
  • asp.net开发注意事项
  • 金融创新推动资产管理公司发展
  • 安全策略的制定企业经营的基础
  • 钱盾反诈公益平台造反诈骗“防弹衣”
  • Salesforce:到2021年人工智能将创造80万工作岗位和1.1亿美元收入
  • vsftp日志内容详解
  • 带你认识DaoCloud这家做Docker的创业公司!
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Angular2开发踩坑系列-生产环境编译
  • Fundebug计费标准解释:事件数是如何定义的?
  • go append函数以及写入
  • Javascript 原型链
  • JS实现简单的MVC模式开发小游戏
  • Node + FFmpeg 实现Canvas动画导出视频
  • React的组件模式
  • Tornado学习笔记(1)
  • V4L2视频输入框架概述
  • 大型网站性能监测、分析与优化常见问题QA
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 使用SAX解析XML
  • 硬币翻转问题,区间操作
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​Python 3 新特性:类型注解
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • (2)(2.10) LTM telemetry
  • (33)STM32——485实验笔记
  • (done) 两个矩阵 “相似” 是什么意思?
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (南京观海微电子)——COF介绍
  • (实战篇)如何缓存数据
  • (四)c52学习之旅-流水LED灯
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • ***监测系统的构建(chkrootkit )
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .gitignore文件—git忽略文件
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .NET Core 项目指定SDK版本
  • .NET 读取 JSON格式的数据
  • .net 发送邮件