2010-09-10 2 views
4

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

public interface IEmployee 
{ 
    string EmployeeId { get; } 
    string Name { get; } 
    void Update(string newName, ...); 
    ... 
} 

public class Employee : IEmployee 
{ 
    public Employee(string id, string name, ...) 
    { 

    } 
    ... 
} 

Это заставляет сотрудников из источника данных

public class SqlEmployeeRepository : IEmployeeRepository 
{ 
    ... 

    public IEmployee GetEmployee(string id) 
    { 
     ... 
     IEmployee employee = new Employee(id, name, ...); 
     return employee 
    } 

    public IEmployee SaveEmployee(IEmployee employee) 
    { 
     // Execute SQL command. 
    } 
} 

Визуализация будет выглядеть примерно так:

TextBox nameTextBox = new TextBox(); 
... 
nameTextBox.Text = employee.Name; 

И экономия будет выглядеть например:

string name = nameTextBox.Text; 
employee.Update(name, ...); 
myEmployeeRepository.Save(employee); 

Пока, так хорошо. Но затем я опубликовал статью this и this, и они задали мне вопрос, как приложение будет выглядеть (как статически, так и динамически) без геттеров, поэтому я попытался реализовать вышеупомянутое приложение без геттера, используя технику, описанную во второй статье. Я пришел с этим:

public interface IEmployee 
{ 
    public interface Importer 
    { 
     string ProvideId(); 
     string ProvideName(); 
     ... 
    } 

    public interface Exporter 
    { 
     void AddId(); 
     void AddName(); 
     ... 
    } 

    void Export(IExporter exporter) 
    ... 
} 

public class Employee : IEmployee 
{ 
    private string _id; 

    private string _name; 

    public Employee(IEmployee.Importer importer) 
    { 
     _id = importer.ProvideId(); 
     _name = importer.ProvideName(); 
     ... 
    } 

    public void Export(IEmployee.Exporter exporter) 
    { 
     exporter.AddId(_id); 
     exporter.AddName(_name); 
     ... 
    } 
} 

Затем хранилище становится:

public class SqlEmployeeExporter : IEmployee.Exporter 
{ 
    ... 
    public void Save() { ... } 
} 

public class SqlEmployeeRepository : IEmployeeRepository 
{ 
    ... 

    public IEmployee GetEmployee(string id) 
    { 
     IEmployee.Importer importer = new SqlEmployeeImporter(id); 
     IEmployee employee = new Employee(importer); 
     return employee 
    } 

    public IEmployee SaveEmployee(IEmployee employee) 
    { 
     SqlEmployeeExporter exporter = new SqlEmployeeExporter(); 
     employee.Export(exporter); 
     exporter.Save(); 
    } 
} 

становится Визуализация:

EmployeeNameTextBoxExporter exporter = new EmployeeNameTextBoxExporter(); 
employee.Export(exporter); 
exporter.Render(); 

И что-то similair для экономии.

Хотя последняя реализация устранила необходимость для геттеров на Employee и, следовательно, является лучшей формой инкапсуляции данных, она также кажется немного раздутой и чрезмерно сложной. Каково ваше мнение по этому вопросу? Я упускаю или неправильно истолковываю что-то в статьях? Каково ваше общее мнение об использовании геттеров (и сеттеров)?

Этот небольшой эксперимент заставляет меня, как правило, использовать подход к аксессуарам. Может быть, вы можете передумать :-)

+0

Похоже, что ваш объект 'Экспортер' действительно является DTO: http://en.wikipedia.org/wiki/Data_transfer_object – Sjoerd

+0

Статьи, на которые вы ссылаетесь, довольно противоречивы (особенно название) и должны быть взяты с пинчем соли :-) Общее понимание заключается в том, что они не против геттеров/сеттеров в целом, а только против разоблачения ненужных геттеров/сеттеров. Это уже обсуждалось на SO, например. http://stackoverflow.com/questions/2747721/getters-and-setters-are-bad-oo-design, http://stackoverflow.com/questions/565095/java-are-getters-and-setters-evil –

ответ

1

Глядя на фрагмент короткого кода, естественно, будет выглядеть упрощенным и не будет требовать такой инкапсуляции. По мере увеличения размера программы я вижу, что этот подход экономит время при обслуживании. У меня нет большого опыта в этом подходе, поэтому я не могу дать определенный ответ, но я думаю, что он может обеспечить достаточную выгоду, чтобы попытаться и измерить результаты.

Для удобства чтения, я думаю, что есть некоторые преимущества для этого подхода к геттерам/сеттерам. Предположим, вы хотите показать график работы сотрудника как таблицу.Использование «строитель» подход, код высокого уровня остается в основном неизменной:

ScheduleDisplay display = new TableScheduleDisplay(); 
employee.Export(display); 
display.Render(); 

Это гораздо легче читать, чем список инструкций, основной целью которых является извлечение данных из объекта и поместить его в другой объект , Я сразу понимаю, что этот код отображает расписание в виде таблицы.

3

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

+0

Полностью согласился. Я думаю, свойства выглядят гораздо более знакомыми. Правила удобочитаемости :) – dmitko

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