2010-11-26 125 views
2

我有一个客户类与属性和方法定义。目前它包含与客户关联的任何类型任务的方法。例如,它包含一个方法“InsertOrUpdateCustomer”。该方法将新的客户记录插入到数据库中,或者便于编辑现有的客户记录。分离业务逻辑

该类还包含一些客户字段的验证方法。

我认为这不是一个更好的方法。我想有些突破这样的:

interface ICustomer 
{ 
    string CustomerName; 
    date FinancialYearStartDate; 
    date FinancialYearEndDate; 
    string TaxNo; 
    string Address; 
} 

我想实现这个接口到另一个类,说客户:

class Customers: ICustomer 
{ 
    // Properties 
    CustomerName { get; set; } 
    FinancialYearStartDate { get; set; } 
    FinancialYearEndDate { get; set; } 
    TaxNo { get; set; } 
    Address { get; set; } 

    // Constructor 
} 

我想知道:

  1. 在哪里添加插入或更新新客户的方法?我应该创建另一个类还是向上面的类添加方法?

  2. 用上面给出的方式打破我的旧单班是有益的或不是?上述代码中界面有什么优点?

  3. 我想删除验证方法并使用验证框架来代替。我是否需要创建一个不同的“CustomerValidations”类,在那里进行验证,或者我应该使用上面的类本身?

回答

4
  1. 对于插入和更新方法,我会创建一个带有CRUD方法的repository(例如,ICustomerRepository
  2. 我没有看到ICustomer接口的直接好处
  3. 我会使用验证在业务实体之外的方法;例如在专用的验证类中,或者在像spring.net validation这样的配置文件中。

总体而言,我认为每个班级有single responsibility是个好主意 - 例如,业务状态Customer,持久存储NHibernateCustomerRepository : ICustomerRepository和验证CustomerValidator

存储库的一个例子:

interface ICustomerRepository 
{ 
    // Get by id 
    Customer Get(int id); 
    void Delete(Customer customer); 
    IList<Customer> GetAll(); 
    // creates a new instance in datastore 
    // returns the persistent identifier 
    int Save(Customer customer); 
    // updates if customer exists, 
    // creates if not 
    // returns persistent identifier 
    int SaveOrUpdate(Customer customer); 
    // updates customer 
    void Update(Customer customer); 

    // specific queries 
    IList<Customer> GetAllWithinFiscalYear(DateTime year); 
    // ... 
} 

正如你所看到的,这个接口的第一个方法对于大多数企业实体相似,可以抽象为:

interface IRepository<TId, TEntity> 
{ 
    // Get by id 
    TEntity Get(TId id); 
    void Delete(TEntity entity); 
    IList<TEntity> GetAll(); 
    // creates a new instance in datastore 
    // returns the persistent identifier 
    TId Save(TEntity entity); 
    // updates if customer exists, 
    // creates if not 
    // returns persistent identiefier 
    TId SaveOrUpdate(TEntity entity); 
    // updates customer 
    void Update(TEntity entity); 
} 

interface ICustomerRepository : IRepository<int, Customer> 
{ 
    // specific queries 
    IList<Customer> GetAllWithinFiscalYear(DateTime year); 
} 
1

的动作,如“InsertOrUpdateCustomer”通常是一个客户实体服务的一部分(适配器模式)(在另一类即你的建议)

想它的方式是:“谁的责任是挽救客户?“

一种可能性是将'ICustomerValidator'注入到Save方法中。

2

我的答案:

  1. 我把插入法将包含ICustomers类(我想会有一个或多个)。至于更新,这取决于这个方法的作用。如果您正在更新某些客户的内部字段/属性,则应与ICustomers一起进行;

  2. 恕我直言,最大的好处之一就是单元测试代码依赖于客户,因为您可以轻松地模拟/存根,因此更容易。

  3. 我会使用类本身。

+1

哪里是关注的分离? – 2010-11-26 08:36:32

+0

我请你原谅,但我没有得到这个问题... – Simone 2010-11-26 08:42:23

0

介绍基本上是数据容器的类的接口很少有益。相反,您可能需要分别创建两个具有数据库持久性和验证角色的类。有一个接口可能会让您有机会使这些类可以互换用于测试或不同的存储/验证策略。