Tôi có một lớp được sử dụng để xử lý thanh toán của khách hàng. Tất cả trừ một trong những phương thức của lớp này đều giống nhau cho mọi khách hàng, ngoại trừ một phương pháp tính toán (ví dụ) số tiền mà người dùng của khách hàng nợ. Điều này có thể khác nhau rất nhiều từ khách hàng này sang khách hàng khác và không có cách nào dễ dàng để nắm bắt logic của các tính toán trong một cái gì đó như tệp thuộc tính, vì có thể có bất kỳ số lượng các yếu tố tùy chỉnh nào.
Tôi có thể viết mã xấu mà chuyển đổi dựa trên ID khách hàng:
switch(customerID) {
case 101:
.. do calculations for customer 101
case 102:
.. do calculations for customer 102
case 103:
.. do calculations for customer 103
etc
}
nhưng điều này đòi hỏi phải xây dựng lại lớp mỗi khi chúng ta có một khách hàng mới. Cách tốt hơn là gì?
[Chỉnh sửa] Bài viết "trùng lặp" là hoàn toàn khác nhau. Tôi không hỏi làm thế nào để tránh câu lệnh chuyển đổi, tôi đang hỏi về thiết kế hiện đại áp dụng tốt nhất cho trường hợp này - điều mà tôi có thể giải quyết bằng câu lệnh chuyển đổi nếu tôi muốn viết mã khủng long. Các ví dụ được cung cấp có chung chung và không hữu ích, vì về cơ bản chúng nói "Này, công tắc hoạt động khá tốt trong một số trường hợp, không phải trong một số trường hợp khác."
[Chỉnh sửa] Tôi quyết định chọn câu trả lời được xếp hạng hàng đầu (tạo một lớp "Khách hàng" riêng cho từng khách hàng thực hiện giao diện chuẩn) vì các lý do sau:
Tính nhất quán: Tôi có thể tạo giao diện đảm bảo tất cả các lớp Khách hàng nhận và trả lại cùng một đầu ra, ngay cả khi được tạo bởi nhà phát triển khác
Khả năng bảo trì: Tất cả các mã được viết bằng cùng một ngôn ngữ (Java), do đó không cần ai khác phải học một ngôn ngữ mã hóa riêng biệt để duy trì tính năng đơn giản.
Tái sử dụng: Trong trường hợp một vấn đề tương tự xuất hiện trong mã, tôi có thể sử dụng lại lớp Khách hàng để giữ bất kỳ số phương thức nào để thực hiện logic "tùy chỉnh".
Tính quen thuộc: Tôi đã biết cách thực hiện việc này, vì vậy tôi có thể hoàn thành nhanh chóng và chuyển sang các vấn đề khác, cấp bách hơn.
Hạn chế:
Mỗi khách hàng mới yêu cầu biên dịch lớp Khách hàng mới, có thể thêm một số phức tạp vào cách chúng tôi biên dịch và triển khai các thay đổi.
Mỗi khách hàng mới phải được thêm bởi nhà phát triển - một người hỗ trợ không thể thêm logic vào một cái gì đó như tệp thuộc tính. Điều này không lý tưởng ... nhưng sau đó tôi cũng không chắc chắn làm thế nào một Người hỗ trợ có thể viết ra logic kinh doanh cần thiết, đặc biệt là nếu nó phức tạp với nhiều ngoại lệ (rất có thể).
Sẽ không có quy mô tốt nếu chúng ta thêm nhiều, nhiều khách hàng mới. Điều này không được mong đợi, nhưng nếu nó xảy ra, chúng ta sẽ phải suy nghĩ lại về nhiều phần khác của mã cũng như phần này.
Đối với những người bạn quan tâm, bạn có thể sử dụng Java Reflection để gọi một lớp theo tên:
Payment payment = getPaymentFromSomewhere();
try {
String nameOfCustomClass = propertiesFile.get("customClassName");
Class<?> cpp = Class.forName(nameOfCustomClass);
CustomPaymentProcess pp = (CustomPaymentProcess) cpp.newInstance();
payment = pp.processPayment(payment);
} catch (Exception e) {
//handle the various exceptions
}
doSomethingElseWithThePayment(payment);