iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0

Removing Shotgun Surgery

簡介

當異動一項功能, 導致系統其他的程式碼也得異動.
稱為Shotgun surgery是一種比喻, 霰彈槍發射(功能異動), 打到的目標(其他模組)都會變化

重構前範例

假設有個聊天室系統, ChatService處理當前使用者能傳訊息、傳送檔案與變更狀態(上線、忙碌等)

public class ChatService
{
    private User _user;
    public void SendMessage(User recipient, string message)
    {
        if(!_user.IsLogged())
        {
            throw new AuthenticationException("User is not logged");
        }
        // ...
    }

    public void UploadFile(User recipient, File file)
    {
        if(!_user.IsLogged())
        {
            throw new AuthenticationException("User is not logged");
        }
        // ...
    }

    public void ChangeStatus(Status status)
    {
        if(!_user.IsLogged())
        {
            throw new AuthenticationException("User is not logged");
        }
        // ...
    }
}

重構後範例

試想如果if(!_user.IsLogged())這個if block要異動時, 這3個甚至多個函數, 都得全部一筆一筆修改.
於是Extract function,將這段邏輯都只移到一函數處理:

public class ChatService
{
    private User _user;
    public void SendMessage(User recipient, string message)
    {
        AssertUserIsLogged();
        // ...
    }

    public void UploadFile(User recipient, File file)
    {
        AssertUserIsLogged();
        // ...
    }

    public void ChangeStatus(Status status)
    {
        AssertUserIsLogged();
        // ...
    }

    private void AssertUserIsLogged()
    {
        if(!_user.IsLogged())
        {
            throw new AuthenticationException("User is not logged");
        }
    }
}

經過這種重構, 未來要變更是否登入的流程, 範圍已限縮於AssertUserIsLogged函數.

為何要重構

Shotgun surgery很常發生, 只要你完成一段邏輯, 而別的模組又得用到而你要懶得設計, 直接複製貼上,
此時這code smell慢慢出現, 久而久之維護程式碼就變得很耗時.
最好的做法是時時要有"Don't repeat yourself"的原則, 別讓程式碼大量重複.


上一篇
Coupling 耦合
下一篇
Introduce Parameter Object 的重構
系列文
程式淨化計畫:痛苦是重構的起源!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言