В даний час я працюю над веб-сервером, де нам часто потрібно визначати певну логіку сервера на основі сторінки, яку потрібно повернути користувачеві.
Кожній сторінці надається 4-літерний код сторінки, і ці коди сторінок в даний час перераховані в класі як статичні рядки:
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..
}
І часто в коді ми бачимо такий код ( перша форма ):
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
s частково спрощені з використанням списків сторінок , які оголошуються різними людьми в різних класах. Це робить код таким чином ( 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
класу як статичні константи, він все ще потребує дисципліни від розробників, щоб перевірити, чи вписується їх нова сторінка в якийсь із цих списків, і додати її відповідно.
Нове рішення
Моє рішення полягало в тому, щоб створити enum (оскільки існує кінцево відомий список кодів сторінок), де кожна сторінка містить деякі властивості, які нам потрібно встановити:
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 булеонів на кшталт цього, що робить конструктор справді великим, і, можливо, буде складно правильно визначити декларацію, коли ви додасте сторінку. Хтось має краще рішення?