Jay*_*Jay 8 java oop design-patterns rules strategy-pattern
这个问题是我早期帖子的延续:java中的访问者模式实现 - 这看起来如何?
重构我的代码时我有点困惑.我试图将我的访问者模式(在前一篇文章中解释)转换为复合策略模式.我想做这样的事情:
public interface Rule {
public List<ValidatonError> check(Validatable validatable);
}
Run Code Online (Sandbox Code Playgroud)
现在,我将定义一个这样的规则:
public class ValidCountryRule {
public List<ValidationError> check(Validatable validatable) {
// invokeDAO and do something, if violation met
// add to a list of ValidationErrors.
// return the list.
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我可以有两个不同类型的对象进行验证.这两个可能是完全不同的:说我有一个商店是Validatable,再一个Schedule是Validatable.现在,如果我写一个看起来像这样的复合:
class Validator implements Rule {
private List<Rule> tests = new ArrayList<Rule>();
public void addRule(Rule rule) {
tests.add(rule);
}
public List<ValidationError> check(Visitable visitable) {
List<ValidationError> list = new ArrayList<ValidationError>();
for(Rule rule : tests) {
list.addAll(rule.check(visitable);
}
}
public Validator(ValidatorType type) {
this.tests = type.getRules();
}
}
Run Code Online (Sandbox Code Playgroud)
我会定义一个enum定义哪些检查集在哪里...
public Enum ValidatorType {
public abstract List<Rule> getRules();
STORE_VALIDATOR {
public List<Rule> getRules() {
List<Rule> rules = new ArrayList<Rule>();
rules.add(new ValidCountryRule());
rules.add(new ValidXYZRule());
}
// more validators
}
Run Code Online (Sandbox Code Playgroud)
最后,我会像这样使用它:
Validator validator = new Validator(ValidatorType.STORE_VALIDATOR);
for (Store store : stores) {
validator.check(store);
}
Run Code Online (Sandbox Code Playgroud)
我有一种奇怪的感觉,我的设计有缺陷.我不喜欢我的Rule接口期望的想法Validatable.你能否建议我如何改进这个?
感谢您的帮助.
当我第一次了解设计模式时,我一直在努力寻找使用它们的地方.我已经了解到过早的"模式化"有点像过早的优化.首先,尝试以直接的方式进行,然后看看给你的问题.
尝试使用最少的接口和子类设计.然后应用适合您找到的明显冗余的任何模式.我从这篇文章和上一篇文章中得到的印象是,您可能过度设计代码.
将 Validatable 替换为泛型类型参数 T 以使验证框架类型安全。
public interface Rule<T> {
public List<ValidationError> check(T value);
}
Run Code Online (Sandbox Code Playgroud)
让我们用 ValidationStrategy 接口扩展我们的框架:
public interface ValidationStrategy<T> {
public List<Rule<? super T>> getRules();
}
Run Code Online (Sandbox Code Playgroud)
我们正在处理以“? super T”为界的规则,因此我们可以将 Animal 的规则添加到 Dog 验证器(假设 Dog 扩展 Animal)。验证器现在看起来像这样:
public class Validator<T> implements Rule<T> {
private List<Rule<? super T>> tests = new ArrayList<Rule<? super T>>();
public Validator(ValidationStrategy<T> type) {
this.tests = type.getRules();
}
public void addRule(Rule<? super T> rule) {
tests.add(rule);
}
public List<ValidationError> check(T value) {
List<ValidationError> list = new ArrayList<ValidationError>();
for (Rule<? super T> rule : tests) {
list.addAll(rule.check(value));
}
return list;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以像这样实现一个示例 DogValidationStrategy:
public class DogValidationStrategy implements ValidationStrategy<Dog> {
public List<Rule<? super Dog>> getRules() {
List<Rule<? super Dog>> rules = new ArrayList<Rule<? super Dog>>();
rules.add(new Rule<Dog>() {
public List<ValidationError> check(Dog dog) {
// dog check...
return Collections.emptyList();
}
});
rules.add(new Rule<Animal>() {
public List<ValidationError> check(Animal animal) {
// animal check...
return Collections.emptyList();
}
});
return rules;
}
}
Run Code Online (Sandbox Code Playgroud)
或者,就像在您的示例中一样,我们可能有一个提供多种狗验证策略的枚举:
public enum DogValidationType implements ValidationStrategy<Dog> {
STRATEGY_1 {
public List<Rule<? super Dog>> getRules() {
// answer rules...
}
},
// more dog validation strategies
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4403 次 |
| 最近记录: |