Saat ini saya sedang mengerjakan webapp di mana kita sering perlu mengkondisikan beberapa logika server berdasarkan halaman yang akan dikembalikan kepada pengguna.
Setiap halaman diberi kode halaman 4 huruf, dan kode halaman ini saat ini terdaftar dalam kelas sebagai String statis:
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..
}
Dan seringkali dalam kode kita melihat kode seperti ini ( formulir 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
}
Yang agak mengerikan untuk dibaca karena tidak menunjukkan apa yang menjadi milik umum dari halaman-halaman ini yang menyebabkan penulis kode menyatukannya di sini. Kita harus membaca kode di if
cabang untuk mengerti.
Solusi saat ini
Ini if
sebagian disederhanakan menggunakan daftar halaman yang dideklarasikan oleh orang yang berbeda di kelas yang berbeda. Ini membuat kode terlihat seperti ( formulir ke-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
}
... yang menyatakan niatnya jauh lebih baik. Tapi...
Masalah saat ini
Masalahnya di sini adalah bahwa jika kita menambahkan halaman, secara teori kita harus melalui semua basis kode untuk menemukan apakah kita perlu menambahkan halaman kita ke if()
atau ke daftar seperti itu.
Bahkan jika kita memindahkan semua daftar itu ke PageCodes
kelas sebagai konstanta statis, masih perlu disiplin dari pengembang untuk memeriksa apakah halaman baru mereka cocok dengan salah satu daftar itu dan menambahkannya sesuai.
Solusi baru
Solusi saya adalah membuat enum (karena ada daftar kode halaman terkenal yang terbatas) di mana setiap halaman berisi beberapa properti yang perlu kita atur:
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
}
Maka kode kondisional sekarang terlihat seperti ini ( formulir ke-3 ):
if (destinationPage.hasShoppingCart()) {
// add some shopping-cart-related data to the response
}
if (destinationPage.isAvailabilityPage()) {
// add some info related to flight availability
}
Itu sangat mudah dibaca. Selain itu, jika seseorang perlu menambahkan halaman, dia dipaksa untuk memikirkan setiap boolean dan apakah ini benar atau salah untuk halaman barunya.
Masalah Baru
Satu masalah yang saya lihat adalah mungkin akan ada 10 boolean seperti ini, yang membuat konstruktornya sangat besar dan mungkin sulit untuk mendapatkan deklarasi dengan benar ketika Anda menambahkan halaman. Adakah yang punya solusi yang lebih baik?
false
, kemudian memodifikasi satu atau dua (mungkin yang salah, karena sangat sulit untuk melacak). Tidak ada perlindungan sempurna dari bodoh, dan ada titik di mana Anda harus memercayai pengembang Anda untuk melakukan hal yang benar.