Я хотел бы получить несколько советов и критических замечаний в отношении дизайна, управляемого доменами, ниже.Я включил псевдокод ниже.Реальный код будет иметь инкапсулированные свойства.
Проблемы
Меня беспокоит только то, что это выглядит анемично.
Шаги
- Создание нового запроса со значениями
- подтвержден ли запрос?
- Если да, показать значения
- Если нет, показать причины, не утвержденные
Классы
enum UnitedStatesState {
ALABAMA,
//...
CALIFORNIA,
//...
MAINE,
//...
WASHINGTON
}
class License {
int id;
String name;
//enum of state that the license is applicable in
UnitedStatesState state;
}
class LicenseRequest {
//the name of the person making the request
String name;
//enum of state to which the user is requesting a license in
UnitedStatesState state;
LicenseResponse submit()
{
//TODO: move creation of the rules out of this class
RuleGroup<LicenseRequest> ruleGroup = new RuleGroup<>();
ruleGroup.add(new StateExclusionLicenseRequestRule(UnitedStatesState.MAINE));
boolean approved = ruleGroup.execute(this);
if(approved) {
License license = createLiscense(request);
return new ApprovedLicenseResponse(license);
} else {
DeniedLicenseResponse response = new DeniedLicenseResponse();
response.rules = newArrayList(ruleGroup);
return response;
}
}
//TODO: move create license out of Request. maybe a factory class?
private License createLicense()
{
License license = LicenseIdGenerator.generate(this.state);
license.name = this.name;
license.state = this.state;
save(license);
return license;
}
}
//visitor for the rule
interface Rule<T> {
public boolean execute(T o);
public List<String> getMessages();
}
//rule that auto denies when the request is made in an excluded state
class StateExclusionLicenseRequestRule : Rule<LicenseRequest> {
public List<String> getMessages();
UnitedStatesState excludedState;
public boolean execute(LicenseRequest request) {
if(request.state == excludedState)
{
messages.add("No license for " + request.state + " is available at this time.");
return false;
}
return true;
}
}
//rule that groups all other rules
class RuleGroup<T> : Rule<T> {
public void addRule(Rule<T> rule);
public List<Rule<T>> getFailedRules();
public List<String> getMessages() {
List<String> messages = new ArrayList<>();
for(Rule<T> rule : rules) {
messages.addAll(rule.getMessages());
}
return messages;
}
public boolean execute(T o) {
List<Rule<T>> failedRules = new ArrayList<>(rules.size());
for(Rule<T> rule : rules) {
boolean approve = rule.execute(o);
if(!approve) {
failedRules.add(rule);
}
}
return !failedRules.isEmpty();
}
}
interface LicenseResponse {
boolean approved;
}
class ApprovedLicenseResponse : LicenseResponse {
License license;
}
class DeniedLicenseResponse : LicenseResponse {
private List<Rule<LicenseRequest>> rules;
public List<String> getMessages()
{
List<String> messages = new ArrayList<>();
for(Rule<LicenseRequest> rule : rules) {
messages.addAll(rule.getMessages());
}
return messages;
}
}
Пример кода
request = new Request(name: 'Test', state: UnitedStatesState.CALIFORNIA)
response = request.submit()
if(response.approved)
{
out('Your request is approved');
out('license id = ' + reponse.id);
}
else
{
out('Your request was denied');
for(String message : response.messages)
{
out(message);
}
}
Обновление 1: фон
Это всего лишь макет того, что я хотел бы реализовать.Это простая система, в которой пользователь вводит информацию в форму о себе, и ему утверждают или отказывают в лицензии.После утверждения сертификат доступен для печати.
В качестве примера, единственное правило состоит в том, что запрос на получение лицензии в штате Мэн отклоняется.
Обновление 2: Правила рефакторинга и удалениеОбработчик
Я внес некоторые изменения в приведенный выше пример.Удалил обработчик и переместил весь код в LicenseRequest.Я также перенес Правила одобрения / отклонения для классов, реализующих шаблон vistor.