【发布时间】:2010-09-10 07:37:01
【问题描述】:
我遇到了一个设计问题,我可以提出一些建议。假设我们在新应用程序中需要(多么原始......)员工。我通常会做的是这样的:
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 的必要性,因此是更好的数据封装形式,但它也似乎有点臃肿和过于复杂。您对此事有何看法?我是否遗漏或误解了文章中的某些内容?您对 getter(和 setter)的使用有什么总体看法?
这个小实验让我现在倾向于使用访问器方法。也许你可以改变我的想法:-)
【问题讨论】:
-
看来你的
Exporter对象真的是一个 DTO:en.wikipedia.org/wiki/Data_transfer_object -
您所引用的文章颇具争议(尤其是标题),应该加点盐 :-) 普遍的理解是,它们一般不反对 getter/setter,只反对暴露不必要的 getter/setter。这已经在 SO 上讨论过了,例如stackoverflow.com/questions/2747721/…, stackoverflow.com/questions/565095/…
标签: design-patterns oop