天天看點

消滅 if-else 地獄:使用面向對象程式設計技巧改善你的 Java 代碼

消滅 if-else 地獄:使用面向對象程式設計技巧改善你的 Java 代碼

Java 中的 if else 語句是我們經常會用到的判斷語句,但如果在代碼中出現大段的 if else 語句,将導緻代碼變得難以維護和擴充。那麼,我們應該如何消滅大段的 if else 呢?

一、問題分析

實際上,出現大段的 if else 語句通常是由于業務邏輯複雜或需要處理多種情況所導緻的。例如,在一個簡單的銀行賬戶管理系統中,一個訂單系統,需要根據訂單狀态進行不同處理,傳統的做法是:

if (order.getStatus() == OrderStatus.TO_BE_PAID) {
    // 處理待付款訂單
} else if (order.getStatus() == OrderStatus.PAID_WAITING_DELIVERY) {
    // 處理已付款待發貨訂單
} else if (order.getStatus() == OrderStatus.DELIVERED_WAITING_SIGN) {
    // 處理已發貨待簽收訂單
} else if (order.getStatus() == OrderStatus.COMPLETED) {
    // 處理已簽收已完成訂單
}
           

如果需要添加新的訂單狀态,就需要修改這些 if else 語句。而且,随着業務邏輯的複雜化,這種做法會使代碼越來越難以維護和擴充。

二、解決辦法

為了避免大段的 if else 語句,在 Java 中可以采用以下幾種方式(為了減少代碼量隻列出兩種狀态):

  1. 使用多态或政策模式

将每個處理邏輯封裝成一個實作類,并使用一個抽象類或接口來調用它們。例如:

interface OrderHandler {
    void handle(Order order);
}

class ToBePaidHandler implements OrderHandler {
    @Override
    public void handle(Order order) {
        // 處理待付款訂單
    }
}

class PaidWaitingDeliveryHandler implements OrderHandler {
    @Override
    public void handle(Order order) {
        // 處理已付款待發貨訂單
    }
}
........
}
           

然後,在使用時隻需要根據訂單狀态選擇不同的實作類進行處理,例如:

jMap<OrderStatus, OrderHandler> handlerMap = new HashMap<>();
handlerMap.put(OrderStatus.TO_BE_PAID, new ToBePaidHandler());
handlerMap.put(OrderStatus.PAID_WAITING_DELIVERY, new PaidWaitingDeliveryHandler());

OrderHandler handler = handlerMap.get(order.getStatus());
handler.handle(order);           
  1. 利用Map等資料結構

可以将訂單狀态和對應的處理邏輯存儲在一個Map等資料結構中,然後根據訂單狀态找到對應的處理邏輯進行處理。例如:

Map<OrderStatus, Consumer<Order>> handlerMap = new HashMap<>();
handlerMap.put(OrderStatus.TO_BE_PAID, order -> {
    // 處理待付款訂單
});
handlerMap.put(OrderStatus.PAID_WAITING_DELIVERY, order -> {
    // 處理已付款待發貨訂單
});

Consumer<Order> handler = handlerMap.get(order.getStatus());
handler.accept(order);
           
  1. 工廠模式
interface OrderProcessor {
    void process(Order order);
}

class ToBePaidProcessor implements OrderProcessor {
    @Override
    public void process(Order order) {
        // 處理待付款訂單
    }
}

class PaidWaitingDeliveryProcessor implements OrderProcessor {
    @Override
    public void process(Order order) {
        // 處理已付款待發貨訂單
    }
}

class OrderProcessorFactory {
    private static Map<OrderStatus, OrderProcessor> processorMap = new HashMap<>();

    static {
        processorMap.put(OrderStatus.TO_BE_PAID, new ToBePaidProcessor());
        processorMap.put(OrderStatus.PAID_WAITING_DELIVERY, new PaidWaitingDeliveryProcessor());
    }

    public static OrderProcessor createProcessor(OrderStatus status) {
        return processorMap.get(status);
    }
}
           

調用時隻需要使用工廠方法來建立對應的處理器對象:

OrderProcessor processor = OrderProcessorFactory.createProcessor(order.getStatus());
processor.process(order);           
  1. 觀察者模式
interface OrderObserver {
    void onToBePaid(Order order);
    void onPaidWaitingDelivery(Order order);
}

class DefaultOrderObserver implements OrderObserver {
    @Override
    public void onToBePaid(Order order) {
        // 處理待付款訂單
    }

    @Override
    public void onPaidWaitingDelivery(Order order) {
        // 處理已付款待發貨訂單
    }
}

class OrderObservable {
    private List<OrderObserver> observers = new ArrayList<>();

    public void addObserver(OrderObserver observer) {
        observers.add(observer);
    }

    public void removeObserver(OrderObserver observer) {
        observers.remove(observer);
    }

    public void notifyObservers(Order order) {
        for (OrderObserver observer : observers) {
            switch (order.getStatus()) {
                case TO_BE_PAID:
                    observer.onToBePaid(order);
                    break;
                case PAID_WAITING_DELIVERY:
                    observer.onPaidWaitingDelivery(order);
                    break;
                case DELIVERED_WAITING_SIGN:
                    observer.onDeliveredWaitingSign(order);
                    break;
                case COMPLETED:
                    observer.onCompleted(order);
                    break;
                default:
                    break;
            }
        }
    }
}
           

調用時隻需要将觀察者對象注冊到可觀察對象中即可:

OrderObservable observable = new OrderObservable();
observable.addObserver(new DefaultOrderObserver());
observable.notifyObservers(order);
           

三、總結

在 Java 中,我們可以采用多種方法消滅大段的 if else 語句,如政策模式、工廠模式和規則引擎。這些方法可以使代碼更加靈活、易于維護和擴充。但是,在應用這些方法時,需要根據具體業務場景來選擇合适的方式,避免過度設計和不必要的複雜性。

繼續閱讀