Утверждение Класс, который имеет только поведение, но не имеет данных, обычно не является классом. совершенно неверно.
Извлечение поведения в отдельный класс - хорошая и распространенная вещь длясделать в рефакторинге.Он может иметь состояние, но также не должен иметь его.Вы должны иметь чистые интерфейсы и реализовывать их в любом случае, если сочтете это необходимым.
Кроме того, классы без состояния отлично подходят для вычислений, которые вам нужны только в течение короткого периода времени.Вы создаете их экземпляры (или запрашиваете какую-то Фабрику, чтобы получить их), делаете необходимые вычисления, а затем выбрасываете их в мусор.У вас может быть соответствующая «версия» вашего поведения, доступная где угодно и когда угодно.
Обычно я нахожу, что разные реализации интерфейса имеют некоторое состояние (например, в конструкторе), но иногда тип вашего классаможет полностью определить свое поведение.
Например:
public interface IExporter
{
/// <summary>
/// Transforms the specified export data into a text stream.
/// </summary>
/// <param name="exportData">The export data.</param>
/// <param name="outputFile">The output file.</param>
void Transform(IExportData exportData, string outputFile);
}
может быть реализовано как
class TabDelimitedExporter : IExporter { ... }
class CsvExporter : IExporter { ... }
class ExcelExporter : IExporter { ... }
Для реализации экспорта из IExportData
(что бы это ни было)к CSV-файлу, вам, вероятно, вообще не нужно никакого состояния.ExcelExporter
, с другой стороны, может иметь различные свойства для параметров экспорта, но также может не иметь состояния.
[Редактировать]
Перемещение GetInvoices
и GetArticles
в классе WebService
означает, что вы свяжете их реализацию с типом WebService.Наличие их в отдельных классах позволит вам иметь разные реализации как для счетов, так и для статей.В целом, кажется, лучше разделять их.