I noticed my code looks really ugly, and is hard to maintain. Basically I need do to some person check. Pseudo code is like this (BTW I can't "cut" anything in query, and it's not really the point of my question):
List<Person> persons = getPersonsBySomeQuery();
if (checkAnyPersonExists(persons)) {
if (atLeastOneWithGivenNameExist(persons)) {
if (noOneWithOtherNameExists(persons)) {
filteredPersons = filterPersonsWithGivenName(persons);
if (singleName(filteredPersons)) {
// single person found
if (someParameterFromQueryIsTrue) {
if (someComplicatedLogicIsOK) {
// found exactly one person, all OK!!!
} else {
// found exactly one person with given name, but not OK
}
} else {
// found exactly one person but parameter from query is not OK
}
} else {
// found only persons with given name, but more than one
}
} else {
// found person(s) with given name, but also some with different name
}
} else {
// found person(s), all have different name
}
} else {
// no one found
}
So I don't have that much experience with design patterns, but i read about them, and I started thinking I could implement Chain of Responsibility pattern. Like, every if-else could be one element in chain, and also this filter element on line 6 could also be "Chainable".
In the end it could look something like:
AbstractChainElement getCheckChain() {
return new CheckAnyExist(
new CheckOneWIthGivenNameExist(
new CheckNoOneWithOtherNameExist(
new FilterOnlyGivenName(
new CheckIsSingleName(
new CheckOtherParameters(
new CheckWithSomeComplicatedLogic()))))));
}
getCheckChain().doChain(persons);
Do you think it's good way to do it or is there anything more elegant?
With this I could construct chain for checking for different check types also, using factory or even abstract factory pattern.
Something like:
FactoryCheckThesePersonsByTheseParameters implements AbstractFactory {
List<Person> getPersons() {
// get persons with THIS query
}
AbstractChainElement getCheckChain() {
// check persons THIS way
}
}
FactoryCheckThatPersonsByThatParameters implements AbstractFactory {
List<Person> getPersonsBySomeParameters() {
// get persons with THAT query
}
AbstractChainElement getCheckChain() {
// check persons THAT way
}
}