[Architecture] Factory Builder

摘要:[Architecture] Factory Builder

[Architecture] Factory Builder

目的

同時提供延遲注入物件、掛載注入項目這兩個功能

情景

在開發系統時,如果需要在執行階段才生成並注入物件,可以套用Factory模式來提供延遲注入物件功能。例如:一個監控系統在火警發生時,建立功能物件來啟動相關設備(灑水設備、警報設備、警消通報)。

  • 物件圖

    情景01

但在實作過程中,延遲注入物件這個功能,常常需要伴隨掛載注入項目功能,用以增加系統的延展性,這時可以接著套用Builder模式,來提供掛載注入項目功能。例如:一個監控系統在火警發生時,依照購買版本建立功能物件來啟動相關設備(V1:灑水設備、警報設備;V2:灑水設備、警報設備、警消通報;V3:....)。

  • 物件圖

    情景02

本篇文章介紹上述這個Factory模式、Builder模式組合而成的Factory Builder模式。這個模式定義物件之間的職責跟互動,用來為系統同時提供延遲注入物件、掛載注入項目這兩個功能,用以增加系統的延展性。主要為自己做個紀錄,也希望能幫助到有需要的開發人員。(使用DI Framework也能提供相關功能)

  • 示意圖

    情景03

結構

  • 物件圖

    結構01

參與者

System

  • 擁有一個Factory

  • 使用Factory來生成Product。

  • 使用Product來提供系統功能。

Factory

  • 擁有多個Builder

  • 使用Builder來生成Product。

  • 在條件生成Product情景中,Factory封裝條件邏輯。

Builder

  • 生成Product,生成參數由Builder提供。

  • 在條件生成Product情景中,Builder封裝條件參數。

Productm

  • 封裝系統功能。

  • 透過Builder生成並注入到系統。

合作方式

  • 順序圖

    合作方式01

實作

  • 類別圖

    實作01

  • ActionFactory

    public class ActionFactory
    {
        // Fields
        private readonly IEnumerable<ActionBuilder> _actionBuilderCollection = null;
    
    
        // Constructors
        public ActionFactory(IEnumerable<ActionBuilder> actionBuilderCollection)
        {
            // Default
            _actionBuilderCollection = actionBuilderCollection;
        }
    
    
        // Methods
        public IEnumerable<IAction> Create()
        {
            // Result
            List<IAction> actionList = new List<IAction>();
    
            // Create
            foreach (var actionBuilder in _actionBuilderCollection)
            {
                var action = actionBuilder.Create();
                if (action == null) throw new InvalidOperationException();
                actionList.Add(action);
            }
    
            // Return
            return actionList;
        }
    }
    
  • ActionBuilder

    public abstract class ActionBuilder
    {
        // Methods
        public abstract IAction Create();
    }
    
  • Action

    public interface IAction
    {
        // Methods
        void Execute();
    }
    
  • SecuritySystem

    public class SecuritySystem
    {
         // Fields
        private readonly ActionFactory _actionFactory = null;
    
    
        // Constructors
        public SecuritySystem(ActionFactory actionFactory)
        {
            // Default
            _actionFactory = actionFactory;
        }
    
    
        // Methods
        public void Execute()
        {
            // Create
            var actionCollection = _actionFactory.Create();
            if (actionCollection == null) throw new InvalidOperationException();
    
            // Execute
            foreach(var action in actionCollection)
            {
                action.Execute();
            }
        }
    }
    
  • 系統掛載:灑水設備、警報設備

    class Program
    {
        static void Main(string[] args)
        {
            // Initialize
            var actionBuilderList = new List<ActionBuilder>();
            actionBuilderList.Add(new WateringActionBuilder());
            actionBuilderList.Add(new AlarmActionBuilder());
            var securitySystem = new SecuritySystem(new ActionFactory(actionBuilderList));
    
            // Execute
            securitySystem.Execute();
    
            // End
            Console.ReadLine();
        }
    }
    

    實作02

  • 系統掛載:灑水設備、警報設備、警消通報

    class Program
    {
        static void Main(string[] args)
        {
            // Initialize
            var actionBuilderList = new List<ActionBuilder>();
            actionBuilderList.Add(new WateringActionBuilder());
            actionBuilderList.Add(new AlarmActionBuilder());
            actionBuilderList.Add(new NotifyActionBuilder());
            var securitySystem = new SecuritySystem(new ActionFactory(actionBuilderList));
    
            // Execute
            securitySystem.Execute();
    
            // End
            Console.ReadLine();
        }
    }
    

    實作03

下載

範例程式碼:點此下載

期許自己
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。