星期四, 4月 13, 2023

[DP] 建造者模式 - Fluent

[DP] 建造者模式 文章內容換成 Fluent 寫法來記錄,使用 Fluent 寫法可以增加流程順序可讀性

IPersonFluentBuilder

每個 Interface 都必須回傳自己本身
namespace Blog_Builder
{
    public interface IPersonFluentBuilder
    {
        IPersonFluentBuilder BuildHead();
        IPersonFluentBuilder BuildBody();
        IPersonFluentBuilder BuildArmLeft();
        IPersonFluentBuilder BuildArmRight();
        IPersonFluentBuilder BuildLegLeft();
        IPersonFluentBuilder BuildLegRight();
        IPersonFluentBuilder Build();
    }
}
PersonThinFluentBuilder
using System.Drawing;

namespace Blog_Builder
{
    public class PersonThinFluentBuilder : IPersonFluentBuilder
    {
        private Graphics _g;
        private Pen _p;

        public PersonThinFluentBuilder(
            Graphics g,
            Pen p)
        {
            _g = g;
            _p = p;
        }

        public IPersonFluentBuilder BuildHead()
        {
            _g.DrawEllipse(_p, 50, 20, 30, 30);
            return this;
        }

        public IPersonFluentBuilder BuildBody()
        {
            _g.DrawRectangle(_p, 60, 50, 10, 50);
            return this;
        }

        public IPersonFluentBuilder BuildArmLeft()
        {
            _g.DrawLine(_p, 60, 50, 40, 100);
            return this;
        }

        public IPersonFluentBuilder BuildArmRight()
        {
            _g.DrawLine(_p, 70, 50, 90, 100);
            return this;
        }

        public IPersonFluentBuilder BuildLegLeft()
        {
            _g.DrawLine(_p, 60, 100, 45, 150);
            return this;
        }

        public IPersonFluentBuilder BuildLegRight()
        {
            _g.DrawLine(_p, 70, 100, 85, 150);
            return this;
        }

        public IPersonFluentBuilder Build()
        {
            return this;
        }
    }
}

PersonFluentDirector
namespace Blog_Builder
{
    public class PersonFluentDirector
    {
        private IPersonFluentBuilder _pb;

        public PersonFluentDirector(IPersonFluentBuilder personFluentBuilder)
        {
            _pb = personFluentBuilder;
        }

        public void CreatePerson()
        {
            _pb
                .BuildHead()
                .BuildBody()
                .BuildArmLeft()
                .BuildArmRight()
                .BuildLegLeft()
                .BuildLegRight()
                .Build();
        }
    }
}
實際使用
using System.Drawing;
using System.Windows.Forms;

namespace Blog_Builder
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            // 測試一:使用 Director 來決定順序
            Pen p_LightGreen = new Pen(Color.LightGreen);
            var tfb = new PersonThinFluentBuilder(e.Graphics, p_LightGreen);
            var pd_ThinFluent = new PersonFluentDirector(tfb);
            pd_ThinFluent.CreatePerson();

            // 測試二:使用 Builder 決定順序
            Pen p_LightPink = new Pen(Color.LightPink);
            new PersonThinFluentBuilder(e.Graphics, p_LightPink)
                .BuildHead()
                .BuildBody()
                .BuildArmLeft()
                .BuildArmRight()
                .BuildLegLeft()
                .BuildLegRight()
                .Build();
        }
    }
} 
 
之前看到 Fluent 介紹時,因為一直點擊選擇 Method 來決定建構流程,以為是類似擴充方法設計,學習後發現是透過回傳本身來做到

沒有留言:

張貼留言