iT邦幫忙

2022 iThome 鐵人賽

DAY 19
1

今天要介紹的是 Object Pool模式,會以工廠的機器為例。假設今天要生產晶片,需要高精密的機器才能去生產,而這台機器又非常昂貴,而且做出機器需要花的時間很長,以老闆的角度來看,資金有限,除非真的需要更多台機器才會去添加購買,並且也要設定能買的最高上限數量,畢竟機器很昂貴,如果買太多會導致資金週轉不靈。

今天如果生產完晶片A,那就會讓機器做閒置的動作,等到有下一個產品需要生產時再拿出來使用,達到重複利用的價值(畢竟機器很貴,買了就是要給他操下去),而如果今天需求大爆發,每一台機器都在被使用,這樣就會需要去等待,直到有機器空閒時才能做生產,接下來我們看例子來說明。

Object Pool - 定義

在建立物件比較昂貴,或者對於特定類型能夠建立的物件數目有限制時,管理物件的再利用。

https://ithelp.ithome.com.tw/upload/images/20220927/20136443eUBDsQcqVg.png

(圖片來源:https://oowisdom.csse.canterbury.ac.nz/images/0/06/Object_pool.PNG)

範例 UML

https://ithelp.ithome.com.tw/upload/images/20220927/201364432UVIyZyg0e.png

Code要點

  • Machine 簡單定義了機器的名稱以及目前是否閒置(這邊透過 Enum去表示機器是否閒置)。
  • Factory 可以想成是管理機器的工廠,任何人要使用機器都要到這邊去拿,而裡面有定義好機器最多能擁有的數量,以及一個蒐集Machine的物件池(_objPool),會透過這個物件池來存放機器 ( 正常的物件池概念應該是會真的從池裡拿出物件以及放回物件,這邊我用isIdle的屬性值來代表機器是否閒置,如果閒置則表示機器目前沒有被拿出,非閒置則表示機器已被拿出 )。

不囉嗦上Code!

using System;
using System.Collections.Generic;
using System.Linq;

namespace DAY19_Object_Pool
{
    public class Program
    {
        static void Main(string[] args)
        {
            Factory factory = new Factory();

            factory.GetMachine();
            factory.GetMachine();
            factory.GetMachine();
            factory.GetMachine();
            factory.GetMachine();
            Factory.ReleaseMachine();
            Factory.ReleaseMachine();
            factory.GetMachine();
            factory.GetMachine();
            factory.GetMachine();
            Factory.ReleaseMachine();
            Factory.ReleaseMachine();
            Factory.ReleaseMachine();
            factory.GetMachine();
            factory.GetMachine();
            factory.GetMachine();
            Factory.ReleaseMachine();
            factory.GetMachine();
            factory.GetMachine();
            factory.GetMachine();

            Console.Read();
        }
    }

    public class Factory
    {
        // 機器編碼
        private static int Number = 1;
        // 限制機器最大擁有數量
        private static readonly int _poolMaxSize = 3;
        // 對象池
        private static readonly List<Machine> _objPool = new List<Machine>(_poolMaxSize);
        public Machine GetMachine()
        {
            Machine Machine;
            // 判斷對象池數量是否已達上限,如果沒有,則新增機器,如果已達上限,則去取回可用的機器
            if (_objPool.Count >= _poolMaxSize && _objPool.Count > 0)
                Machine = RetrieveFromPool();
            else
                Machine = GetNewMachine();
            return Machine;
        }

        private Machine GetNewMachine()
        {
            // 新增機器
            Machine Machine = new Machine() { Name = $"機器{Number++}號", Status = MachineStatus.isNotIdle };
            _objPool.Add(Machine);
            Console.WriteLine($"新增{Machine.Name}");
            return Machine;
        }

        protected Machine RetrieveFromPool()
        {
            Machine Machine;
            Machine =_objPool.FirstOrDefault(x => x.Status == MachineStatus.isIdle);
            if (Machine == null)
            {
                Console.WriteLine("無空閒的機器,請稍後再試!");
            }
            else
            {
                Machine.Status = MachineStatus.isNotIdle;
                Console.WriteLine($"使用空閒的機器:{Machine.Name}");
            }
            return Machine;
        }

        public static void ReleaseMachine()
        {
            Random rnd = new Random();
            var machine = _objPool.Where(x => x.Status == MachineStatus.isNotIdle).FirstOrDefault();
            machine.Status = MachineStatus.isIdle;
            Console.WriteLine($"{machine.Name}已釋放,目前可使用!");
        }
    }
    public class Machine
    {
        public string Name { get; set; }
        public MachineStatus Status { get; set; }
    }

    public enum MachineStatus
    {
        isIdle,
        isNotIdle
    }
}
  • 結果

https://ithelp.ithome.com.tw/upload/images/20220927/20136443I4oGq9TWHG.png

簡單的小結

透過 Object Pool模式,當我們在建立昂貴物件的時候 (假設一個物件需要透過大量的資料庫連線以及計算,甚至要花很長的等待時間),就可以使用物件池的概念,將這些昂貴的物件放置在一個物件池,如果需要就拿出來使用,用完就放回去,減少每次都要重複花費高成本在建立昂貴物件。


上一篇
【DAY18】Observer模式 - 訂閱你喜好的Youtuber!
下一篇
【DAY20】Builder模式 - 今晚...我想來點麥當勞(下)
系列文
勇闖秘境!探索物件導向背後的設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言