我遇到了一个设计问题我可以使用一些建议。假设我们需要(原始......)员工在我们的新应用程序中。我通常会做的是这样的事情:
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文章,他们让我想知道应用程序在没有getter的情况下会是什么样子(静态和动态),所以我尝试在没有getter的情况下实现上面的应用程序第二篇文章中描述的技术。我想出了这个:
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();
还有类似的东西可以保存。
虽然后一种实现消除了Employee
上吸气剂的必要性,因此是更好的数据封装形式,但它似乎有点臃肿且过于复杂。你对这件事有什么看法?我是否遗漏或误解了文章中的内容?您对使用getter(和setter)的一般看法是什么?
这个小实验让我倾向于使用存取方法。也许你可以改变主意: - )
答案 0 :(得分:3)
我认为访问者(getter和setter)要好得多,至少在你的例子中如此。 我认为在这里使用DTO模式没有任何优势,最重要的是,代码变得不可读。编写优秀软件的关键之一就是简单性:代码越简单,可读性越强,可维护性越强。 一般来说,应该在解决问题时使用模式。因此,您首先需要检测问题,然后使用最简单的模式解决问题,从而解决问题。 使用DTO模式的选择应该得到它解决特定问题的事实的支持。
答案 1 :(得分:1)
查看简短的代码片段自然会显得过于简单,并且不会要求进行此类封装。随着程序规模的增长,我可以看到这种方法在维护期间节省了时间。我对这种方法没有多少经验,所以我无法给出明确的答案,但我认为它可以提供足够的好处,值得尝试和测量结果。
为了便于阅读,我认为这种方法比getter / setter有一些优势。假设您要将员工的工作时间表显示为表格。使用“构建器”方法,高级代码基本保持不变:
ScheduleDisplay display = new TableScheduleDisplay();
employee.Export(display);
display.Render();
这比指令列表更容易阅读,其主要目的是从对象中提取数据并将其放入另一个对象。我一眼就知道这段代码将时间表显示为一个表格。