他们对设计模式的看法确实如此,它们只是已经普遍使用的技术的体现。我从1985年开始使用Active Record Pattern。
此模式的一个属性是在实现中使用静态成员来执行返回基础数据集合的搜索。
class Customer {
static Customer FindCustomerById( int Id ) { ... }
static Customer[] FindActiveCustomers() { ... }
}
在我需要更多灵活性的许多情况下,我打破了封装并包含诸如
之类的方法static Customer[] FindCustomers( string criteria ) { ... }
其中一个人称之为
Customer[] customers = Customer.FindCustomers( "LastName = 'Smith'" );
当然这是我在C中使用这种模式的时候,显然不是最佳实践,并且在错误的手中会导致SQL注入和其他问题。
是否有适当的模式或做法可以让Customer类成为此类搜索的“标准”?
例如,假设我想找到姓氏为Smith的客户,我可能会考虑编写一个实现,例如:
static Customer[] FindCustomers( Customer customer ) { ... }
被称为(当然使用适当的构造函数):
Customer[] customersnamedsmith =
Customer.FindCustomer( new Customer( "Smith" ) );
或者创建一个定义标准的联合课更好吗?
答案 0 :(得分:1)
仅仅使用LINQ,我喜欢传入表达式而不是字符串的想法。但是,也许那只是我?我也不喜欢ActiveRecord,因为它混合了同一个对象中的状态和行为。包装精美,但不是模型和数据访问的清晰分离。
我见过将客户类传递给活动记录的情况,但是如果您要使用该路由,则存储库模式会更清晰,并且会将行为与状态分开。但是,我认为使用您在活动记录中已经拥有的投资并传递一个对象没有错。
如果您想创建一个标准类,您最终会得到一些策略模式,这可以使您的活动记录比现在更活跃。然而,这是一种适用的模式,也将解决任何注射问题。
答案 1 :(得分:0)
虽然它会将您推出数据库级别,但您可以使用与比较器类似的东西。我不知道C#,所以我只是捏造它,但你得到了要点:
class CustomerLastNameEvaluator : IEvaluate
{
private Customer _customer;
public CustomerLastNameEvaluator (String lastName)
{
_customer = new Customer (lastName);
}
bool IEvaluate.Evaluate(Customer c)
{
return (_customer.LastName == c.LastName);
}
}
Customer[] customers = Customer.FindCustomers( new CustomerLastNameEvaluator("Smith") );
答案 2 :(得分:0)
没有理由不这样做,我会提供这样的方法:
public static IEnumerable<Customer> AllCustomers()
{
return Customers.AsEnumerable();
}
如果您有理由不这样做,您需要明确说明这些理由并详细检查,以便设计出正确的解决方案。
答案 3 :(得分:0)
查看codeplex上的WWPlatform DataAccess示例。它显示了一个很好的例子,即尽管通过存储库模式提供搜索规范实例作为参数。