Интерфейс или абстрактный класс или оба лучше в следующей ситуации? - PullRequest
0 голосов
/ 31 марта 2011

Предположим, у меня есть программа, которая извлекает данные об авиакомпании.В данных каждой авиакомпании используется своя система, из которой мне нужно получить данные (xml).Из-за различий в каждой системе, в основном в xml, и, возможно, в некоторых свойствах, я решил реализовать интерфейс для каждой системы авиакомпаний.Однако я обнаружил, что каждая авиакомпания, хотя и отличается во многих аспектах, также имеет много общего, поэтому, если я сначала сделаю это интерфейсным способом, мне, возможно, придется сделать что-то вроде этого:

public interface IAirlineSystem {
    public void PullData();
}

Теперь дляВ каждой системе авиакомпаний (я придумываю эти названия) я мог бы сделать что-то вроде:

public class Oberon : IAirlineSystem {
    string Name {get;set;}
    int Code {get;set;}
    public void Initialize()
    {
        //initialize code here
    }
    public void PullData()
    {
       //code here
    }
}

Выше приведена только одна система авиакомпаний, но представьте, что у меня есть больше (например, +10), другая может быть:

public class AirSys: IAirlineSystem {
    string Name {get;set;}
    int Code {get;set;}
    public void Initialize()
    {
        //initialize code here
    }
    public void PullData()
    {
       //code here
    }
}

В приведенном выше коде:

Свойства имени и кода уникальны для каждой системы авиакомпании.Initialize содержит одинаковый код для каждой реализации, а PullData уникален для каждой системы.Из-за дубликатов в классах, здесь я мог бы использовать абстрактный класс для хранения кода метода Initialize.Я слышал, что это хорошая практика - на самом деле смешивать интерфейсы и абстрактные классы, что будет примером для этого на примере моей системы авиакомпаний?

Еще одна вещь, которая возникает, - это предположить, что у меня есть другой метод винтерфейс называется ValidateData, но не все системы авиакомпаний должны вызывать его, но если я добавлю его в интерфейс, мне потребуется реализовать пустой метод, если он не нужен.Есть ли способ, которым я могу предотвратить необходимость сделать это.Является ли это еще одной причиной для использования абстрактного класса, возможно, с виртуальным методом, чтобы он мог быть переопределен при необходимости.Если бы я сделал ValidateData абстрактным методом, его все равно нужно было бы реализовать, верно?

Ответы [ 2 ]

1 голос
/ 31 марта 2011

Ваше объяснение указывает на использование абстрактного класса. У вас может быть абстрактный класс, который будет иметь реализацию метода Initialize, и вам не нужно будет повторять его в подклассах Oberon и AirSys. PullData может быть абстрактным методом, который затем будет реализован в отдельных подклассах. И да, только класс, которому требуется метод ValidateData, будет реализован.

Примером будет:

public abstract class AirlineSystemBase
{
    string Name { get; set; }
    int Code { get; set; }

    public void Initialize()
    {
        //code goes here
    }

    public abstract void PullData();

}

public class Oberon : AirlineSystemBase
{
    public override void PullData()
    {
        //code goes here
    }
}

public class AirSys : AirlineSystemBase
{
    /// <summary>
    ///     that is if say only AirSys class had a need for this ValidateData() method
    /// </summary>
    public void ValidateData()
    {
        //code goes here
    }

    public override void PullData()
    {
        //code goes here
    }

}

ИЛИ, если вы хотите использовать интерфейс и абстрактный класс:

public interface IAirlineSystem
{
    void PullData();
    void ValidateData();
}

public abstract class AirlineSystemBase : IAirlineSystem
{
    string Name { get; set; }
    int Code { get; set; }

    public void Initialize()
    {
        //code goes here
    }

    public abstract void PullData();

    public virtual void ValidateData() 
    { 
        //code goes here
    }

}

public class Oberon : AirlineSystemBase
{
    public override void PullData()
    {
        //code goes here
    }
}

public class AirSys : AirlineSystemBase
{
    /// <summary>
    ///     that is if say only AirSys class had a need for this ValidateData() method
    /// </summary>
    public override void ValidateData()
    {
        //code goes here
    }

    public override void PullData()
    {
        //code goes here
    }

}
0 голосов
/ 31 марта 2011

Например, я бы реализовал что-то вроде:

public interface IAirlineSystem {
    public void PullData();
    public void ValidateData();
}

public abstract class BaseAirlineSystem : IAirlineSystem {
    string Name {get;set;}
    int Code {get;set;}

    public void Initialize()
    {
        // common initialize code here
    }        

    public virtual void ValidateData()
    {
       //empty, override when necessary
    }
}

И пример реализации:

public class AirSys: BaseAirlineSystem{
    public void PullData()
    {
        //code here
    }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...