2011-10-17 26 views
0

假設你有這樣的代碼:「基類PARAMS並不總是使用」代碼味道

public Base 
{ 
    abstract void Register(); 
} 

public Registrator1: Base 
{ 
    override void Register() 
    { 
     //uses the current state of the object to populate the UI captions 
    } 
} 

public Registrator2: Base 
{ 
    override void Register() 
    { 
     //uses the current state of the object to populate the UI captions 
    } 
} 

但是當你收到這實際上寄存器基於某些參數的新業務規則要求你寫Registrator3和更改您的代碼基地到下一個:

public Base 
{ 
    abstract void Register(externalParam); 
} 

public Registrator1: Base 
{ 
    override void Register(externalParam) 
    { 
     //uses the current state of the object to populate theUI 
    } 
} 

public Registrator2: Base 
{ 
    override void Register(externalParam) 
    { 
     //uses the current state of the object to populate the UI 
    } 
} 

public Registrator3: Base 
{ 
    override void Register(externalParam) 
    { 
    //uses a DDD - service passed in the params to populate the UI 
    } 
} 

但是註冊器1和註冊器2不需要該參數和代碼變得臭。有什麼方法可以重寫這段代碼?

+0

如果你提到oop你可以添加一些虛擬的方法也許。這看起來像代碼氣味「目前同名的新方法」。 –

+0

@Valentin Kuzub,完成 –

+0

我還是遇到了這個問題。最初的方法沒有參數,這意味着它只是操縱它所調用的對象的狀態。它不清楚該登記冊實際上在做什麼,因此很難想到缺陷或更好的方式。當我們添加一個externalParam類似於完全改變了整個圖片時,現在註冊者正在接受這些東西,並且可能會根據這些參數註冊參數或其他內容,這意味着它的狀態已不夠了嗎?無論如何,我認爲如果你想得到一些好的建議,你可以擴大這個問題,例如爲註冊函數顯示一些僞代碼。 –

回答

2

你可以在這裏使用一個對象作爲參數;這通常用於根據所使用的呼叫參數數量可能變化的情況。

struct RegistrationInfo 
{ 
    public static readonly RegistrationInfo Empty = new RegistrationInfo(); 
    public string Username; 
    public string CustomerName; 
    public string Validity; 
} 

abstract class Base 
{ 
    public abstract void Register(RegistrationInfo info); 
    // If you want to retain the paramaterless call: 
    public void Register() 
    { 
     Register(RegistrationInfo.Empty); 
    } 
} 

class Registrar1 : Base 
{ 
    public override void Register(RegistrationInfo info) 
    { 
     if (info.Username == null) throw new ArgumentNullException("info.Username"); 
    } 
} 

class Registrar2 : Base 
{ 
    public override void Register(RegistrationInfo info) 
    { 
     if (info.CustomerName == null) throw new ArgumentNullException("info.CustomerName"); 
    } 
} 

這樣做的好處是,每次添加參數時都不需要更改方法參數(這是斷開接口)。的使用也變得有些自我記錄:

var r = new Registrar1(); 
r.Register(new RegistrationInfo(){ Username = "JimJoe" }); 
r.Register(RegistrationInfo.Empty); 

這就像空氣清新劑這類代碼的氣味,同時它還是臭;你可以讓它聞起來更好。

最後,您可以通過使參數爲params(這有少量開銷)來使呼叫站點更清潔;儘管它比較臭,但它是一種語言破解。最後,你可以改進它與泛型:

class RegistrationInfo 
{ 

} 

class RegistrationInfo1 : RegistrationInfo 
{ 
    public string Arg; 
} 

class RegistrationInfo2 : RegistrationInfo 
{ 
    public int Arg; 
} 

interface IBase<in TRegistration> 
    where TRegistration : RegistrationInfo 
{ 
    void Register(TRegistration registration); 
} 

class Base : IBase<RegistrationInfo> 
{ 
    public void Register(RegistrationInfo registration) 
    { 

    } 
} 

class Registrar1 : IBase<RegistrationInfo1> 
{ 
    public void Register(RegistrationInfo1 arg) 
    { 
    } 
} 

class Registrar2 : IBase<RegistrationInfo2> 
{ 
    public void Register(RegistrationInfo2 arg) 
    { 
    } 
} 
+0

是的,你的解決方案很整潔,謝謝。但 - 我有一個沒有(空)類型的註冊信息90%的時間,並收到一個空,因爲這個參數不是很好。雖然可能是不可解決的另一種方式 –

+0

@Hohhi你可以在基類上調用一個方法通過null。 –

+0

我不能在我腦海裏想像你在說什麼 –

0

在註冊器3中不可能包含externalParam的邏輯嗎? 換句話說,註冊器3使用參數,然後調用未修改的無參數基?

很大程度上取決於邏輯所屬的位置。如果它是基本內在的東西,然後把它放在基地,並重載Register()函數或爲param提供一個默認值,以便子類不需要提供它。

0

假設要重複使用從基類中的註冊邏輯,可以按如下方式更新代碼:

public class Base 
{ 
    public virtual void Register(object externalParam) 
    { 
     // base registration logic goes here 
    } 
} 

public class Registrator1: Base 
{ 
    public override void Register(object externalParam) 
    { 
     base.Register(null); 
     // custom registration logic goes here 
    } 
} 

public class Registrator2: Base 
{ 
    public override void Register(object externalParam) 
    { 
     base.Register(null); 
     // custom registration logic goes here 
    } 
} 

public class Registrator3: Base 
{ 
    public override void Register(object externalParam) 
    { 
     base.Register(externalParam); 
     // custom registration logic goes here 
    } 
} 

HTH,

科斯明

編輯:更新後的代碼進行編譯。

+1

此代碼不能編譯 –

+0

我已經更新了代碼。 – CosminB

相關問題