【问题标题】:Using accessors: Good or bad? [closed]使用访问器:好还是坏? [关闭]
【发布时间】: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);

到目前为止,一切都很好。但后来我跑了thisthis 文章,他们让我想知道没有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)的使用有什么总体看法?

这个小实验让我现在倾向于使用访问器方法。也许你可以改变我的想法:-)

【问题讨论】:

标签: design-patterns oop


【解决方案1】:

我认为访问器(getter 和 setter)要好得多,至少在您的示例中是这样。 我在这里没有看到使用 DTO 模式的任何优势,最重要的是,代码变得不可读。编写好软件的关键之一是简单:代码越简单,可读性和可维护性就越高。 通常,在解决问题时应该使用该模式。因此,您首先需要检测一个问题,然后应用解决问题的最简单模式来解决它。 使用 DTO 模式的选择应该得到它解决特定问题的支持。

【讨论】:

  • 完全同意。我认为属性看起来更熟悉。可读性规则:)
【解决方案2】:

看一个短代码 sn-p 自然会显得过于简单,不需要这样的封装。随着程序大小的增长,我可以看到这种方法在维护期间节省了时间。我对这种方法没有太多经验,所以我无法给出明确的答案,但我认为它可以提供足够的好处,值得尝试和衡量结果。

为了可读性,我认为这种方法比 getter/setter 有一些优势。假设您要将员工的工作时间表显示为表格。使用“builder”方法,高级代码基本保持不变:

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

这比主要目的是从一个对象中提取数据并将其放入另一个对象的指令列表更容易阅读。我一眼就知道,这段代码将日程表显示为表格。

【讨论】:

    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 2011-02-01
    • 1970-01-01
    • 2012-06-28
    • 2014-02-27
    相关资源
    最近更新 更多