返回

9.建造者模式

将一个复杂对象的构造流程与它的对象表现分离出来,让相同的构建流程可以产生不同的对象行为表现。

建造者模式

将一个复杂对象的构造流程与它的对象表现分离出来,让相同的构建流程可以产生不同的对象行为表现。

建造者模式的定义

建造者模式可以分成两个步骤来实施:

  1. 将复杂的构建流程独立出来,并将 整个流程分成几个步骤,其中的每一个步骤可以时一个功能组件的设置,也可以是参数的指定,并且在一个构建方法中,将这些步骤串接起来。
  2. 定义一个专门实现这些步骤的实现者,这些实现者知道每一个部分该如何完成,并且能接受参数来决定要产出的功能,但不知道整个组装流程是什么。

将“流程分析安排”和“功能分开实现”以不同的类来实现的话,类结构图如图

  • Director(建造指示者)
    • 负责对象构建时的“流程分析安排”
    • 在Construct方法中,会明确定义对象组装的流程,即调用Builder接口方法的顺序。
  • Builder(功能实现接口)
    • 定义不同的操作方法将“功能分开来实现”。
    • 其中的每一方法都是用来提供给某复杂对象的一部分功能,或是提供设置规则。
  • ConcreteBuilder(功能实现者)
    • Builder的具体实现,实现产出功能的类。
    • 不同的ConcreteBuilder(功能实现者)可以产出不同的功能,用来实现不同对象的行为表现和功能。
  • Product(产品)
    • 代表最终完成的复杂对象,必须提供方法让Builder类可以将各部位功能设置给它。

具体实现如下

	// 欲產生的複雜物件 
	public class Product
	{
		private List<string> m_Part = new List<string>();
		public Product(){}
		public void AddPart(string Part)
		{
			m_Part.Add(Part);
		}
		public void ShowProduct()
		{
			Debug.Log("ShowProduct Functions:");
			foreach(string Part in m_Part)
				Debug.Log(Part);
		}
	}

	// 介面用來生成Product的各零件
	public abstract class Builder
	{
		public abstract void BuildPart1(Product theProduct);
		public abstract void BuildPart2(Product theProduct);
	}

	// Builder介面的具體實作A
	public class ConcreteBuilderA : Builder
	{
		public override void BuildPart1(Product theProduct)
		{
			theProduct.AddPart( "ConcreteBuilderA_Part1");
		}
		public override void BuildPart2(Product theProduct)
		{
			theProduct.AddPart( "ConcreteBuilderA_Part2");
		}
	}

	// Builder介面的具體實作B
	public class ConcreteBuilderB : Builder
	{
		public override void BuildPart1(Product theProduct)
		{
			theProduct.AddPart( "ConcreteBuilderB_Part1");
		}
		public override void BuildPart2(Product theProduct)
		{
			theProduct.AddPart( "ConcreteBuilderB_Part2");
		}
	}

	// 利用Builder介面來建構物件
	public class Director
	{
		private Product m_Product;

		public Director(){}

		// 建立 
		public void Construct(Builder theBuilder)
		{
			// 利用Builder產生各部份加入Product中
			m_Product = new Product();
			theBuilder.BuildPart1( m_Product );
			theBuilder.BuildPart2( m_Product );
		}

		// 取得成品
		public Product GetResult()
		{
			return m_Product;
		}
	}

	public class BuilderTest
    {
        void UnitTest() 
        {
            // 建立
            Director theDirectoir = new Director();
            Product theProduct = null;

            // 使用BuilderA建立
            theDirectoir.Construct( new ConcreteBuilderA());
            theProduct = theDirectoir.GetResult();
            theProduct.ShowProduct();

            // 使用BuilderB建立
            theDirectoir.Construct( new ConcreteBuilderB());
            theProduct = theDirectoir.GetResult();
            theProduct.ShowProduct();
        }
    }

使用建造者模式组装角色功能

参与者说明如下:

  • CharacterBuilderSystem:角色建造者系统负责双方橘色构建时的装配流程。它是一个“IGameSystem 游戏系统”,因为角色构建完成后,还需要通知其他的游戏系统,所以将其加入已经具有中介者模式的PBanseDefenseGame类中,方便与其他游戏功能沟通。
  • ICharacterBuilder:定义游戏角色功能的组装方法,包含3D模型、武器、属性、AI等功能
  • SoldierBuilder:负责玩家角色功能的产生并设置给玩家角色。
  • EnemyBuilder:负责敌方阵营角色功能的产生并设置给敌方角色。

使用建造者模式的优点

在重构后的角色工厂中,只简单负责橘色的“产生”,而复杂的功能组装工作则交由新增加的角色建造者系统来完成。运用建造者模式的角色建造者系统,将角色功能的“组装流程”给独立出来,并以明确的方法调用来试下,这有助于程序代码的阅读和维护。而各个角色的功能装备任务,也交由不同的类来实现,并使用接口方法操作,将系统之间的耦合度降低。所以当实现系统由任何变化时,也可以使用替换实现类的方式来应对。

建造者模式的应用

  • 在角色扮演游戏中,设计者为了增加法术系统的声光效果,在施展法术时,大多会分成不同的段落来呈现法术特效。里如果发射钱的法术吟唱特效、发射时的特效、法术在进行时的特效等。优势为了执行性能的考虑,会在施展法术时,就将所有特效全部准备完成。这个时候就可以利用建造者模式将特效组装完成。
  • 游戏的用户界面就如同一般的网页或App,有时也会有复杂的版面配置和信息显示,利用建造者模式可以将界面的呈现,分成不同的区域或内容来是下面,让界面也可以有“功能组装”的应用方式。