Tôi nghĩ rằng rất nhiều điều này sẽ phụ thuộc vào phạm vi của dự án và chỉ cần làm thế nào lỏng lẻo cùng bạn cần phải được. Tôi làm rất nhiều công việc xung quanh các quy tắc kinh doanh và họ cần phải mở rộng càng tốt. Tôi sẽ không buộc mình vào một hệ thống quy tắc thứ tự nếu có ngay cả khối lượng nhỏ nhất của các quy tắc, hoặc thứ tự của chúng thậm chí còn phức tạp từ xa. Tôi nghĩ rằng tự động phát hiện/hệ thống dây điện của các quy tắc là hoàn toàn là cách để đi ở đây.
Chìa khóa cho loại tình huống này, theo ý kiến của tôi, là các quy tắc trường hợp chung là không phải được xác định bởi sự thiếu logic liên quan đến phạm vi của chúng. Các quy tắc trường hợp chung phải có logic phạm vi cũng giống như quy tắc cụ thể của từng trường hợp cụ thể. Chúng có thể nằm trong phạm vi 99 trên 100 lần, nhưng chúng vẫn cần có logic phạm vi cụ thể.
Sau đây là cách tôi tiếp cận điều này. Tôi không hồi hộp với InnerScope() được gắn trực tiếp với IRule, nhưng với điều kiện bạn đang xem xét một danh sách thứ tự, tôi giả sử logic có thể quản lý và tương đối tĩnh hoặc bạn có thể tiêm một đại biểu cho logic đó.
Khung giao diện
public interface IRule<in T>{
bool IsValid(T obj);
bool WithinScope();
}
public interface IValidator<in T>{
bool IsValid(T obj);
}
public interface IRuleFactory<in T>{
IEnumerable<IRule<T>> BuildRules();
}
Generic Validator và Quy tắc Factory
public class GenericValidator<T> : IValidator<T>
{
private readonly IEnumerable<IRule<T>> _rules;
public GenericValidator(IRuleFactory<T> ruleFactory){
_rules = ruleFactory.BuildRules();
}
public bool IsValid(T obj){
return _rules.All(p => p.IsValid(obj));
}
}
public class GenericRuleFactory<T> : IRuleFactory<T>
{
private readonly IEnumerable<IRule<T>> _rules;
public GenericRuleFactory(IEnumerable<IRule<T>> rules){
_rules = rules;
}
public IEnumerable<IRule<T>> BuildRules(){
return _rules.Where(x => x.WithinScope());
}
}
mẫu quy
public class VeryGeneralDefaultRuleAboutAllObjects : IRule<IMyClass>
{
private readonly Context _context;
public VeryGeneralDefaultRuleAboutAllObjects(Context context){
_context = context;
}
public bool IsValid(IMyClass obj){
return !obj.IsAllJackedUp;
}
public bool WithinScope(){
return !_context.IsSpecialCase;
}
}
public class SpecificCaseWhenGeneralRuleDoesNotApply : IRule<IMyClass>
{
private readonly Context _context;
public VeryGeneralDefaultRuleAboutAllObjects(Context context){
_context = context;
}
public bool IsValid(IMyClass obj){
return !obj.IsAllJackedUp && _context.HasMoreCowbell;
}
public bool WithinScope(){
return _context.IsSpecialCase;
}
}
IoC Dây (Sử dụng StructureMap)
public static class StructureMapBootstrapper
{
public static void Initialize()
{
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.AssembliesFromApplicationBaseDirectory();
scan.AddAllTypesOf(typeof (IRule<>));
});
x.For(typeof(IValidator<>))
.Use(typeof(GenericValidator<>));
x.For(typeof(IRuleFactory<>))
.Use(typeof(GenericRuleFactory<>));
});
}
}
Nguồn
2012-02-07 17:29:55
Rất gây phiền nhiễu vấn đề. Tôi đã tranh luận về điều này trong nhiều giờ, và đã không đi đến một giải pháp thỏa đáng. – CodesInChaos
Cân nhắc việc từ bỏ tự động phát hiện và tạo thủ công danh sách quy tắc trung tâm theo thứ tự ưu tiên. – CodesInChaos
Nhìn vào khái niệm về quy tắc Web (http://rule.codeeffects.com). Tôi nghĩ rằng bạn đang tìm kiếm một cái gì đó tương tự như những gì họ làm. – Kizz