Абстрактный базовый класс, реализующий методы интерфейса производного класса - PullRequest
1 голос
/ 23 февраля 2012

У меня есть следующие классы и интерфейсы.Я хочу по существу заморозить интерфейс IOld (который будет устаревшим) и заставить пользователей использовать интерфейс INew, который будет содержать те же методы, что и IOld.Однако метод INew Meth3 представляет собой ту же функциональность, что и IOld Meth2, но с отличающимся типом возврата, и чтобы лучше их различать, я подумал, что этот дизайн подойдет.Мой вопрос: считается ли это хорошей практикой кодирования?

ПРИМЕЧАНИЕ. IOld и INew живут в отдельных сборках.NewClass не может ссылаться на IOld каким-либо образом, так как он будет представлен как удаленный (MarshalByRef) объект, к которому клиенты будут подключаться через интерфейс INew.Я не хочу, чтобы новые клиенты ссылались на сборку IOld.

public interface IOld
{
    void Meth1();
    double Meth2(int input);
} 

public interface INew
{
    void Meth1();
    float Meth3(int input);
} 

public abstract class BaseClass
{
    public virtual void Meth1()
    {
    } 

    public virtual double Meth2(int input)
    {
        throw new NotImplementedException();
    } 
} 

public class OldClass
:
    BaseClass,
    IOld
{
    public override double Meth2(int input)
    {
        return 0;
    } 
} 

public class NewClass
:
    BaseClass,
    INew
{
    public float Meth3(int input)
    {
        return 0;
    } 
}

Ответы [ 3 ]

3 голосов
/ 23 февраля 2012

Сядьте и постройте свою пирамиду на прочной основе.То, как вы все настроили, абстрактный базовый класс и интерфейс - конкурирующие методы реализации одной и той же концепции.Вы делаете это, прежде всего, чтобы облегчить «Старый» против «Нового», но при этом вы получите довольно прикольный граф зависимостей.

С тем, что вы написали, ваша единственная хитрость - это методы с такой же сигнатурой.Если бы не эта проблема, вы могли бы легко расширить старый интерфейс и не столкнуться с проблемами.Если этот метод изменяется в новом, это изменение рефактора (приемлемо) или совершенно другой результат?Другими словами, может ли старый клиент назвать нового?Если это так, то нет необходимости использовать этот метод в другом интерфейсе.

Убедитесь, что вы устарели, так что пользователи знают, что они потеряют старые методы.Также убедитесь, что это задокументировано.

2 голосов
/ 23 февраля 2012

Я бы предпочел добавить новый метод с немного другим именем вместо создания нового интерфейса.

Таким образом, старый интерфейс будет, например:

public interface IOld
{
    void Meth1();
    [Obsolete("Use Meth22 instead.")]
    double Meth2(int input);
    float Meth22(int input);
} 
2 голосов
/ 23 февраля 2012

Я бы попробовал что-то вроде этого:

public class OldClass : BaseClass, IOld
{
    public override double Meth2(int input)
    {
        return 0.0;
    }
}

public class NewClass : OldClass, INew // now implements IOld and INew using the Method2() from OldClass
{
    [Obsolete("This method is deprecated . Use Method3() instead.")]
    public override double Meth2(int input)
    {
        return base.Meth2(input);
    }
    public float Meth3(int input)
    {
        return return 0.0f;
    }
}

Рекомендуется помечать метод как устаревший, чтобы сообщить разработчику, что ему нужно обновить свой код, а не нарушать его, убив старый метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...