Tôi đang cố gắng tìm một thiết kế lớp cho một thư viện hoạt động trên các biểu đồ có trọng số. Các thuật toán khác nhau có thể được thực hiện trên biểu đồ này, ví dụ: tìm khoảng cách ngắn nhất giữa hai nút, khoảng cách dài nhất giữa hai nút, số lượng đường dẫn giữa hai nút có khoảng cách nhỏ hơn 10 (ví dụ), v.v.
Mối quan tâm của tôi không phải là các thuật toán hoặc cấu trúc dữ liệu mà tôi biết cách triển khai biểu đồ mà là thiết kế lớp cấp cao tổng thể. Vấn đề là trong tương lai chúng ta có thể muốn thêm các thuật toán khác để giải pháp có thể dễ dàng mở rộng. Một tùy chọn để triển khai là chỉ viết một lớp có các phương thức để triển khai từng thuật toán này. Sau đó, các phương thức bổ sung có thể được thêm vào lớp này cho bất kỳ thuật toán mới nào.
lớp công khai GraphCalculator
{
Đồ thị_đồ thị;
int công khai GetLongestDistance(chuỗi startPlaceName, chuỗi endPlaceName)
{
}
int công khai GetShortestDistance(chuỗi startPlaceName, chuỗi endPlaceName)
{
}
int công khai GetNumberOfPaths(int minDistance)
{
}
// mọi thuật toán mới sẽ được triển khai khi các phương thức mới được thêm vào lớp này
}
Mối quan tâm của tôi là điều này vi phạm nguyên tắc đóng mở RẮN. Mỗi thuật toán có nên được triển khai trong lớp riêng của nó không? Nếu vậy, cấu trúc lớp được đề xuất để triển khai điều này là gì để nó được liên kết lỏng lẻo và dễ kiểm tra cũng như cách gọi nó từ lớp API công khai? Có mẫu thiết kế nào được đề xuất không?
câu hỏi của bạnMỗi thuật toán có nên được triển khai trong lớp riêng của nó khôngCâu trả lời chắc chắn làĐúng!Bạn đang nói rằng bạn muốnDễ dàng mở rộng giải pháp. một Một lớp duy nhất với các phương thức thực hiện các thuật toán này. Sau đó, các phương thức bổ sung có thể được thêm vào lớp này cho bất kỳ thuật toán mới nào.Nó hoàn toàn không thể mở rộng được! Bạn đang thay đổi mã, bạn cầnÔn lạiViệc triển khai cơ sở hiện tại của bạn! Điều này hoàn toàn trái ngược với các nguyên tắc OOP - đóng cửa để sửa đổi, mở rộng!
Mọi thuật toán bạn phải triển khai (hiện tại hoặc trong tương lai) đều là một hành vi và phải được xác định bằng giao diện. Tất cả các triển khai nên triển khai giao diện chung này. Bằng cách này, bạn cũng có thể dễ dàng tự mình kiểm tra từng cách triển khai thuật toán. Điều này cũng cho phép bạn xác định danh sách các thuật toán dễ dàng được duy trì linh hoạt (thông qua mã hoặc cấu hình). Với tất cả những điều này, điều bạn cần là một loại kiến trúc plugin nào đó.
Một mẫu thiết kế phù hợp với nhu cầu của bạn có thể là Mẫu khách truy cập , bởi vì nó thêm các hoạt động mới (= đường dẫn ngắn nhất, đường dẫn dài nhất, v.v. thuật toán) vào cấu trúc dữ liệu hiện có (đối tượng đồ họa).
Một lựa chọn khác có thể là Mẫu thiết kế PlugIn , mặc dù IMO chế độ này có thể khó triển khai hơn chế độ khách. Nếu có thể sử dụng phần mềm của bên thứ 3 và các framework hiện có thì bạn có thể xem qua Dự án plugin Sprint , sử dụng khung công tác Spring và định nghĩa mộtTrợ lý lược đồ có thể cắm. Một giải pháp tương tự (phần nào) cho .NET là Khung mở rộng được quản lý和/或 Thư viện doanh nghiệp - Khối ứng dụng Unity .
Tôi là một lập trình viên xuất sắc, rất giỏi!