2016-09-10 47 views
0

我正在開發一個電信項目。我在我的項目中實施了Open/Closed原則。以下是我的課程。OOPS中的打開/關閉原理

MainServiceClass.CS

public abstract class BaseServiceClass 
{ 
    public abstract IEnumerable<string> GetServiceData(); 
    public abstract IEnumerable<string> GetDashBoardData(); 
} 

Web_Service.CS

public class WebServiceClass : BaseServiceClass 
{ 
    public override IEnumerable<string> GetServiceData() 
    { 
     List<string> MyList = new List<string>(); 
     return MyList; 
    } 

    public override IEnumerable<string> GetDashBoardData() 
    { 
     List<string> MyList = new List<string>(); 
     return MyList; 
    } 
} 

Voice_Service.CS

public class VoiceSericeClass : BaseServiceClass 
{ 
    public override IEnumerable<string> GetServiceData() 
    { 
     List<string> MyList = new List<string>(); 
     return MyList; 
    } 

    public override IEnumerable<string> GetDashBoardData() 
    { 
     List<string> MyList = new List<string>(); 
     return MyList; 
    } 
} 

在未來,如果我需要實現視頻服務,我將創建一個新的Video_Service類。我相信我會實現Open/Close原則。

如果我需要在我的MainServiceClass.cs中添加一個新方法,我將添加一個新方法(GetNewTypeOfData())。

問題:在這裏,我正在修改一個類。不過,我是否遵循OCP?或者,有沒有什麼辦法可以在MainServiceClass.cs中添加新的方法?

請建議。

P.S.我需要在所有的派生類即Web_Service.cs,Voice_Service.cs實現這個方法,並Video_Service.cs

更新CrudaLilium後答覆我的問題。

這是我的理解。如果我錯了,請糾正我。

我當前的代碼:

public interface IMainBase 
{ 
    IEnumerable<string> GetData2016(); 
} 

public class VoiceService : IMainBase 
{ 
    public IEnumerable<string> GetData2016() 
    { 
     return Enumerable.Empty<string>(); 
    } 
} 

我會得到一個新的要求,在2017年因此,我將更新2017年

public interface IMainBase 
{ 
    IEnumerable<string> GetData2016(); 
}  

public class VoiceService : IMainBase 
{ 
    public IEnumerable<string> GetData2016() 
    { 
     return Enumerable.Empty<string>(); 
    } 
} 

//New Code will be Added in 2017....Start 

public interface IMainBase2017 : IMainBase 
{ 
    IEnumerable<string> GetData2017(); 
} 

public class voiceService2017 : VoiceService, IMainBase2017 
{ 
    public IEnumerable<string> GetData2017() 
    { 
     return Enumerable.Empty<string>(); 
    } 
} 

//New Code Added be in 2017...Ended 

我的代碼,我會在2018年再次獲得了新的要求。所以,我會在2018年更新我的代碼。

public interface IMainBase 
{ 
    IEnumerable<string> GetData2016(); 
}  

public class VoiceService : IMainBase 
{ 
    public IEnumerable<string> GetData2016() 
    { 
     return Enumerable.Empty<string>(); 
    } 
} 

//New Code will be Added in 2017....Start 

public interface IMainBase2017 : IMainBase 
{ 
    IEnumerable<string> GetData2017(); 
} 

public class voiceService2017 : VoiceService, IMainBase2017 
{ 
    public IEnumerable<string> GetData2017() 
    { 
     return Enumerable.Empty<string>(); 
    } 
} 

//New Code Added be in 2017...Ended 

//New Code will be Added in 2018...Start 

public class WebService2018 : IMainBase2017 
{ 
    public IEnumerable<string> GetData2016() 
    { 
     return Enumerable.Empty<string>(); 
    } 

    public IEnumerable<string> GetData2017() 
    { 
     return Enumerable.Empty<string>(); 
    } 
} 


//New Code will be Added in 2018...End 

根據上面的代碼,我沒有違反OCP。這是一個很好的做法,還是我有其他方法?

+0

你是說你想添加新的方法和實現,將出現在所有類? – Turbot

+0

是的,我想在MainService類中添加一個新方法,稍後我將在派生類中重寫它。 – KiddoDeveloper

+0

當您在添加新功能時必須更改現有課程時,您將違反OCP。所以你沒有遵循OCP;你正在破壞它。 – Steven

回答

1

創建Video_Service不是問題,但更改BaseServiceClass是,您不會遵循該原則。

如果將其設置爲抽象,則需要修改從BaseServiceClass繼承的所有其他類。但即使你沒有把它抽象化,它似乎也沒什麼意義,因爲所有使用你的BaseServiceClass的客戶類都不使用除已有的2之外的其他方法。

如果您的客戶端類需要使用第三個方法,如果你再拍抽象類,它會更好(只是舉例BaseServiceClass2)將從BaseServiceClass繼承並添加新的方法還有,讓你的客戶依賴於這個類。從那裏擴展你現有的類WebServiceClassVoiceSericeClass你將不得不創建新的類並繼承BaseServiceClass2並使用適配器模式。

示例代碼:

public abstract class BaseServiceClass 
    { 
     public abstract IEnumerable<string> GetServiceData(); 
     public abstract IEnumerable<string> GetDashBoardData(); 
    } 

    public abstract class BaseServiceClass2 : BaseServiceClass 
    { 
     public abstract IEnumerable<string> GetNewTypeOfData(); 
    } 


    public class WebServiceClass2 : BaseServiceClass2 
    { 
     private BaseServiceClass adaptee; 

     WebServiceClass2(BaseServiceClass adaptee) 
     { 
      this.adaptee = adaptee; 
     } 

     public override IEnumerable<string> GetDashBoardData() 
     { 
      return adaptee.GetDashBoardData(); 
     } 

     public override IEnumerable<string> GetNewTypeOfData() 
     { 
      return Enumerable.Empty<string>(); 
     } 

     public override IEnumerable<string> GetServiceData() 
     { 
      return adaptee.GetServiceData(); 
     } 
    } 

這將是好得多,如果你讓BaseServiceClass一個接口,如果你需要添加任何新的東西,你也只是創造新的接口從它inhering並像在前面的例子中,讓你的客戶端類別取決於您的新界面,從那裏您可以創建從WebServiceClassVoiceSericeClass等繼承的新類並實現新界面。

例子:

public interface IBaseServiceClass 
    { 
     IEnumerable<string> GetServiceData(); 
     IEnumerable<string> GetDashBoardData(); 
    } 

    public interface IBaseServiceClass2 : IBaseServiceClass 
    { 
     IEnumerable<string> GetNewTypeOfData(); 
    } 


    public class WebServiceClass2 : WebServiceClass, IBaseServiceClass2 
    { 
     public IEnumerable<string> GetNewTypeOfData() 
     { 
      return Enumerable.Empty<string>(); 
     } 
    } 

    public class WebServiceClass : IBaseServiceClass 
    { 
     public IEnumerable<string> GetServiceData() 
     { 
      List<string> MyList = new List<string>(); 
      return MyList; 
     } 

     public IEnumerable<string> GetDashBoardData() 
     { 
      List<string> MyList = new List<string>(); 
      return MyList; 
     } 
    } 

類/接口名稱僅用於佔位符,這將是更好的名字他們更有意義的方式。

+0

謝謝你的回覆。我有個問題。 問題:今天,我已經在生產服務器上部署了我的項目。下一年會產生一個需求,所以我需要在MainService類中實現一個新的方法。所以,我絕不應該違反OCP,並根據您的建議添加新的界面/類。好的,我會添加它。經過一段時間之後,我可能會得到新方法的請求。那麼,我應該爲每個請求生成一個新的抽象/接口嗎? – KiddoDeveloper

+0

請讓我知道,如果我不能解釋我的問題,我會詳細說明。 – KiddoDeveloper

+0

是的,你將不得不創建新的界面,並創建新的類來擴展你現有的類,但是避免創建上帝類。 – CrudaLilium