В настоящее время я работаю над веб-приложением, в котором нам часто нужно настроить логику сервера на основе страницы, которая будет возвращена пользователю.
Каждой странице присваивается четырехбуквенный код страницы, и эти коды страниц в настоящее время перечислены в классе как статические строки:
public class PageCodes {
public static final String FOFP = "FOFP";
public static final String FOMS = "FOMS";
public static final String BKGD = "BKGD";
public static final String ITCO = "ITCO";
public static final String PURF = "PURF";
// etc..
}
И часто в коде мы видим такой код ( 1-я форма ):
if (PageCode.PURF.equals(destinationPageCode) || PageCodes.ITCO.equals(destinationPageCode)) {
// some code with no obvious intent
}
if (PageCode.FOFP.equals(destinationPageCode) || PageCodes.FOMS.equals(destinationPageCode)) {
// some other code with no obvious intent either
}
Что-то ужасно читать, потому что не показывает, какое общее свойство этих страниц побудило автора кода соединить их здесь. Мы должны прочитать код в if
ветке, чтобы понять.
Текущее решение
Они if
были частично упрощены с помощью списков страниц, которые объявлены разными людьми в разных классах. Это делает код похожим ( 2-я форма ):
private static final List<String> pagesWithShoppingCart = Collections.unmodifiableList(Arrays.asList(PageCodes.ITCO, PageCodes.PURF));
private static final List<String> flightAvailabilityPages = Collections.unmodifiableList(Arrays.asList(PageCodes.FOMS, PageCodes.FOFP));
// later in the same class
if (pagesWithShoppingCart.contains(destinationPageCode)) {
// some code with no obvious intent
}
if (flightAvailabilityPages.contains(destinationPageCode)) {
// some other code with no obvious intent either
}
... который выражает намерение намного лучше. Но...
Текущая проблема
Проблема здесь заключается в том, что если мы добавим страницу, то теоретически нам нужно будет пройти через всю кодовую базу, чтобы найти, нужно ли нам добавлять нашу страницу в if()
или в подобный список.
Даже если мы переместим все эти списки в PageCodes
класс как статические константы, разработчикам все равно потребуется дисциплина, чтобы проверить, вписывается ли их новая страница в какой-либо из этих списков, и добавить ее соответствующим образом.
Новое решение
Мое решение состояло в том, чтобы создать перечисление (потому что есть конечный хорошо известный список кодов страниц), где каждая страница содержит некоторые свойства, которые мы должны установить:
public enum Page {
FOFP(true, false),
FOMS(true, false),
BKGD(false, false),
PURF(false, true),
ITCO(false, true),
// and so on
private final boolean isAvailabilityPage;
private final boolean hasShoppingCart;
PageCode(boolean isAvailabilityPage, boolean hasShoppingCart) {
// field initialization
}
// getters
}
Тогда условный код теперь выглядит так ( 3-я форма ):
if (destinationPage.hasShoppingCart()) {
// add some shopping-cart-related data to the response
}
if (destinationPage.isAvailabilityPage()) {
// add some info related to flight availability
}
Который очень читабелен. Кроме того, если кому-то нужно добавить страницу, он / она вынужден думать о каждом логическом значении и о том, является ли это верным или неверным для его новой страницы.
Новая проблема
Одна проблема, которую я вижу, состоит в том, что будет примерно 10 таких логических выражений, что делает конструктор действительно большим, и может быть трудно получить правильное объявление при добавлении страницы. У кого-нибудь есть лучшее решение?
false
, а затем изменят один или два (возможно, неправильный, так как отслеживать так сложно). Там нет идеальной защиты от глупости, и наступает момент, когда вы должны доверять своим разработчикам делать правильные вещи.