iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0

Introduce Null Object

簡介

程式碼到處是處理null欄位或變數的重複邏輯.

重構前範例

假設有個JobRunner類別, 用來執行特定任務的開始與結束.
而範例只有一個任務CopyJob類別.
以下的CopyJob的實作都是dummy並無真實流程:

internal class CopyJob
{
    public bool Start()
    {
        return true;
    }

    public bool AnySetting()
    {
        return true;
    }

    public bool Stop()
    {
        return true;
    }
}

public class JobRunner
{
    private CopyJob _copyJob = null;

    public bool Start()
    {
        if (_copyJob != null)
        {
            return _copyJob.Start();
        }

        return false;
    }

    public bool Stop()
    {
        if (_copyJob != null)
        {
            return _copyJob.Stop();
        }

        return false;
    }

    public bool AnySetting()
    {

        if (_copyJob != null)
        {
            return _copyJob.AnySetting();
        }

        return false;
    }

    public void Initialize()
    {
        _copyJob = new CopyJob();
    }
}

重構後範例

JobRunnerStart, StopAnySetting都得先檢查_copyJob是不是null.
既然是null與非null都有各自的流程, 因此我們建立另一個新類別NullCopyJob, 繼承自CopyJob, 如下重構:

internal class CopyJob
{
    public virtual bool Start()
    {
        return true;
    }

    public virtual bool AnySetting()
    {
        return true;
    }

    public virtual bool Stop()
    {
        return true;
    }
}

internal class NullCopyJob : CopyJob
{
    public override bool Start()
    {
        return false;
    }

    public override bool Stop()
    {
        return false;
    }

    public override bool AnySetting()
    {
        return false;
    }
}

public class JobRunner
{
    private CopyJob _copyJob = new NullCopyJob();

    public bool Start()
    {
        return _copyJob.Start();
    }

    public bool Stop()
    {
        return _copyJob.Stop();
    }

    public bool AnySetting()
    {
        return _copyJob.AnySetting();
    }

    public void Initialize()
    {
        _copyJob = new CopyJob();
    }
}

經過此重構, JobRunner都是統一呼叫CodeJob的方法, 不必再判斷null.

Null object的類型

以上範例是以class繼承的null object, 但未來子類別可能忘記要override.
則可以改用interface.

重構的好處

  1. 不需要重複的null邏輯就可以避免null錯誤
  2. 通過最小化null測試簡化了程式碼

重構的壞處

  1. 如果開發者不知道null object的存在, 就會產生多餘的null測試
  2. 使維護變更複雜: 當有父類別的null object必須override所有新繼承的public方法

上一篇
實作Value Type 為 Immutable物件
下一篇
Replace Type Code with Class 的重構
系列文
程式淨化計畫:痛苦是重構的起源!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言