设计模式之Builder模式学习笔记(四)

动机:  在我们开发软件或游戏中,有时候面临着"一个复杂对象"的创建工作,这个对象通常由其它一些子对象组成,而且这些子对象经常面临着剧烈的变化.

定义:  将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

结构: 

 

四个要素:

1.产品:  包含了一些子对象,如:游戏人物这个产品,它包含了脸容,发型,性别,发型等等的部件,它可以是抽象类,根据需求而定

2.抽象建造者:  可以说它规定了一系列产品部件的创建方法和一个返回产品的方法,当然,只是抽象上

3.具体建造者:  继承了抽象建造者,就是具体对部件创建的实现

4.导演者:  我更钟意理解成控制器,它控制了整个产品的实现过程,而且这个实现过程基本上是不变的,这样才适合Builder模式

例子:  创建一个游戏角色

 1.产品:在以下代码中,我没有使用子对象来组合成产品,而是使用简单的字符串表示

    /// <summary>
    /// 角色父类:规定角色具有的特征
    /// </summary>
    public class Actor
    {
        public string Type { get; set; }//角色类型:如天使,恶魔
        public string Sex { get; set; }//性别
        public string Face { get; set; }//面容
        public string Costume { get; set; }//服装
        public string Hairstyle { get; set; }//发型
    }
2.抽象建造者:  规定了构造游戏角色类型,性别,面容,服装,发型和返回一个产品对象的方法

    /// <summary>
    /// 抽象建造者:规定了对象的创建方式
    /// </summary>
    public abstract class ActorBuilder
    {
        //角色父类
        protected Actor actor = new Actor();
        //建造方法
        public abstract void BuildType();
        public abstract void BuildSex();
        public abstract void BuildFace();
        public abstract void BuildCostume();
        public abstract void BuildHairstyle();
        //工厂方法,返回一个完整的游戏角色对象
        public Actor CreateActor()
        {
            return this.actor;
        }
    }
3.具体建造者: 继承了上面的ActorBuilder类,意味着要具体的构造这些部件,这里我使用了两个具体建造者:天使与恶魔

    /// <summary>
    /// 天使构造器
    /// </summary>
    public class AngelBuilder:ActorBuilder
    {
        public override void BuildType()
        {
            actor.Type = "天使";
        }

        public override void BuildSex()
        {
            actor.Sex = "女";
        }

        public override void BuildFace()
        {
            actor.Face = "漂亮";
        }

        public override void BuildCostume()
        {
            actor.Costume = "白裙";
        }

        public override void BuildHairstyle()
        {
            actor.Hairstyle = "披肩长发";
        }
    }


    /// <summary>
    /// 恶魔构造器
    /// </summary>
    public class DevilBuilder:ActorBuilder
    {
        public override void BuildType()
        {
            actor.Type = "恶魔";
        }

        public override void BuildSex()
        {
            actor.Sex = "妖";
        }

        public override void BuildFace()
        {
            actor.Face = "猥琐";
        }

        public override void BuildCostume()
        {
            actor.Costume = "黑衣";
        }

        public override void BuildHairstyle()
        {
            actor.Hairstyle = "光头";
        }
    }
4.导演者(控制器):  控制产品的创建过程,记住(因为这是一个主干线,Builder模式发生变化的应该是在产品的子对象变化,所以它基本是不变的)

    /// <summary>
    /// 控制复杂产品对象的构建:这个过程一般不变
    /// </summary>
    public  class ActorController
    {
        /// <summary>
        /// 创建复杂产品对象
        /// </summary>
        /// <param name="ab">builder子对象</param>
        public Actor Construct(ActorBuilder ab)
        {
            Actor actor;
            //角色的创建过程假设都是这样不变
            //都是具有类型,性别,头发,面部,服装
            ab.BuildType();
            ab.BuildSex();
            ab.BuildHairstyle();
            ab.BuildFace();
            ab.BuildCostume();
            actor = ab.CreateActor();
            return actor;
        }
    }
最后:主文件和配置文件: 后面可以直接通过

<span style="white-space:pre">	</span>static void Main(string[] args)
        {
            //读取配置文件,恶魔
            string devil = ConfigurationManager.AppSettings["DevilBuilder"];
            //反射生成对象
            ActorBuilder ab = Assembly.Load("Builder").CreateInstance(devil) as ActorBuilder;
            //通过指挥者创建完整的产品对象
            ActorController ac = new ActorController();
            Actor actor = ac.Construct(ab);
            Console.WriteLine("角色类型:{0}", actor.Type);
            Console.WriteLine("性别:{0}", actor.Sex);
            Console.WriteLine("面容:{0}", actor.Face);
            Console.WriteLine("服装:{0}", actor.Costume);
            Console.WriteLine("发型:{0}", actor.Hairstyle);
            Console.WriteLine("------------------------------------------------");
            //天使
            string angel = ConfigurationManager.AppSettings["AngelBuilder"];
            ab = Assembly.Load("Builder").CreateInstance(angel) as ActorBuilder;
            actor = ac.Construct(ab);
            Console.WriteLine("角色类型:{0}", actor.Type);
            Console.WriteLine("性别:{0}", actor.Sex);
            Console.WriteLine("面容:{0}", actor.Face);
            Console.WriteLine("服装:{0}", actor.Costume);
            Console.WriteLine("发型:{0}", actor.Hairstyle);
            Console.Read();
        }
        <?xml version="1.0" encoding="utf-8" ?>
        <configuration>
          <appSettings>
            <add key="DevilBuilder" value="Builder.DevilBuilder"/>
<span style="white-space:pre">	</span>    <add key="AngelBuilder" value="Builder.AngelBuilder"/>
          </appSettings>
        </configuration>

总结,Builder模式的几个要点:

1.Builder模式主要用于"分步骤构建一个发杂的对象",这个的"分步骤"是一个稳定的算法,(如上面控制器创建产品对象的过程),而产品对象的各个部分则经常变化

2.封装变化点,这是面向对象的一个基本原则之一,Builder模式的缺点在于难以应对"分步骤构建"这个需求的变动

3.抽象工厂模式解决的是"系列对象"的需求变化,Builder模式解决"对象部分"的需求变化,再者,Builder模式通常和Composite模式组合使用

这是第四个模式,之前的有三个模式,后面会补上来.








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值