2016-09-10 3 views
0

Я работаю над проектом связи. В моем проекте я реализовал принцип Open/Closed. Ниже приведены мои занятия.Принцип Open/Close в 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 и добавит туда новый метод и сделает ваш клиент зависимым от этого класса. Оттуда, чтобы расширить существующие классы WebServiceClass, VoiceSericeClass, вам нужно будет создать новый класс и наследовать от 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 интерфейс и, если вам нужно добавить что-то новое вы просто создающих новый интерфейс принадлежности из него, и, как и в предыдущем примере, сделать свой клиентский класс зависит от вашего нового интерфейса, оттуда вы можете просто создать новый класс, наследующий от WebServiceClass, VoiceSericeClass и т. д. и реализовать новый интерфейс.

Пример:

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

Смежные вопросы