У меня проблема с дизайном, с которой я мог бы воспользоваться советом. Допустим, нам нужно (как оригинально ...) Сотрудники в нашем новом приложении. Что я обычно делаю что-то вроде этого:Использование аксессуаров: хорошо или плохо?
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
и, следовательно, является лучшей формой инкапсуляции данных, она также кажется немного раздутой и чрезмерно сложной. Каково ваше мнение по этому вопросу? Я упускаю или неправильно истолковываю что-то в статьях? Каково ваше общее мнение об использовании геттеров (и сеттеров)?
Этот небольшой эксперимент заставляет меня, как правило, использовать подход к аксессуарам. Может быть, вы можете передумать :-)
Похоже, что ваш объект 'Экспортер' действительно является DTO: http://en.wikipedia.org/wiki/Data_transfer_object – Sjoerd
Статьи, на которые вы ссылаетесь, довольно противоречивы (особенно название) и должны быть взяты с пинчем соли :-) Общее понимание заключается в том, что они не против геттеров/сеттеров в целом, а только против разоблачения ненужных геттеров/сеттеров. Это уже обсуждалось на SO, например. http://stackoverflow.com/questions/2747721/getters-and-setters-are-bad-oo-design, http://stackoverflow.com/questions/565095/java-are-getters-and-setters-evil –