Cả hai câu trả lời hiện tại dường như chỉ đạt được một phần, và họ tập trung vào các ví dụ che mờ ý tưởng cốt lõi. Đây cũng không phải (chỉ) một nguyên tắc OOP mà là một nguyên tắc thiết kế phần mềm nói chung.
Điều "thay đổi" trong cụm từ này là mã. Barshe có quan điểm khi nói rằng nó thường là một cái gì đó có thể thay đổi, đó là bạn thường dự đoán điều này. Mục tiêu là để bảo vệ bản thân khỏi những thay đổi trong tương lai của mã. Điều này liên quan chặt chẽ đến lập trình dựa trên giao diện . Tuy nhiên, Barshe không chính xác để giới hạn điều này trong "chi tiết thực hiện". Trên thực tế, giá trị của lời khuyên này thường là do những thay đổi trong yêu cầu .
Điều này chỉ liên quan gián tiếp đến trạng thái đóng gói, đó là điều tôi tin David Arno đang nghĩ đến. Lời khuyên này không phải lúc nào cũng (nhưng thường không) đề xuất trạng thái đóng gói và lời khuyên này cũng áp dụng cho các đối tượng bất biến. Trong thực tế, chỉ đơn thuần đặt tên hằng là một hình thức (rất cơ bản) để gói gọn những gì khác nhau.
CandiedOrange kết hợp rõ ràng "những gì thay đổi" với "chi tiết". Điều này chỉ đúng một phần. Tôi đồng ý rằng bất kỳ mã nào thay đổi là "chi tiết" theo một nghĩa nào đó, nhưng "chi tiết" có thể không thay đổi (trừ khi bạn xác định "chi tiết" để tạo ra tautological này). Có thể có lý do để gói gọn các chi tiết không thay đổi, nhưng điều này không phải là một. Nói một cách đơn giản, nếu bạn rất tự tin rằng "chó", "mèo" và "vịt" sẽ là những loại duy nhất bạn cần phải đối phó, thì điều này không đề xuất việc tái cấu trúc CandiedOrange.
Đúc ví dụ của CandiedOrange trong một ngữ cảnh khác, giả sử chúng ta có ngôn ngữ thủ tục như C. Nếu tôi có một số mã có chứa:
if (pet.type() == dog) {
pet.bark();
} else if (pet.type() == cat) {
pet.meow();
} else if (pet.type() == duck) {
pet.quack()
}
Tôi có thể mong đợi một cách hợp lý rằng đoạn mã này sẽ thay đổi trong tương lai. Tôi có thể "gói gọn" nó chỉ bằng cách xác định một thủ tục mới:
void speak(pet) {
if (pet.type() == dog) {
pet.bark();
} else if (pet.type() == cat) {
pet.meow();
} else if (pet.type() == duck) {
pet.quack()
}
}
và sử dụng thủ tục mới này thay vì khối mã (tức là tái cấu trúc "phương thức trích xuất"). Tại thời điểm này, thêm một loại "bò" hoặc bất cứ điều gì chỉ yêu cầu cập nhật speak
thủ tục. Tất nhiên, bằng ngôn ngữ OO, thay vào đó, bạn có thể tận dụng công văn động như được ám chỉ bởi câu trả lời của CandiedOrange. Điều này sẽ xảy ra một cách tự nhiên nếu bạn truy cập pet
thông qua một giao diện. Loại bỏ logic có điều kiện thông qua công văn động là một mối quan tâm trực giao, đó là một phần lý do tại sao tôi thực hiện biểu hiện thủ tục này. Tôi cũng muốn nhấn mạnh rằng điều này không yêu cầu các tính năng đặc biệt đối với OOP. Ngay cả trong ngôn ngữ OO, việc gói gọn những gì thay đổi không nhất thiết có nghĩa là một lớp hoặc giao diện mới cần được tạo.
Là một ví dụ điển hình hơn (gần với OO hơn), chúng tôi muốn xóa các bản sao khỏi danh sách. Giả sử chúng tôi thực hiện nó bằng cách lặp lại danh sách theo dõi các mục chúng tôi đã thấy cho đến nay trong một danh sách khác và xóa bất kỳ mục nào chúng tôi đã thấy. Thật hợp lý khi cho rằng chúng tôi có thể muốn thay đổi cách chúng tôi theo dõi các mục được nhìn thấy, ít nhất là vì lý do hiệu suất. Dictum để gói gọn những gì khác nhau cho thấy rằng chúng ta nên xây dựng một kiểu dữ liệu trừu tượng để thể hiện tập hợp các mục được nhìn thấy. Thuật toán của chúng tôi hiện được xác định theo kiểu dữ liệu Đặt trừu tượng này và nếu chúng tôi quyết định chuyển sang cây tìm kiếm nhị phân, thuật toán của chúng tôi không cần phải thay đổi hoặc quan tâm. Trong ngôn ngữ OO, chúng tôi có thể sử dụng một lớp hoặc giao diện để nắm bắt kiểu dữ liệu trừu tượng này. Trong một ngôn ngữ như SML / O '
Đối với một ví dụ hướng theo yêu cầu, giả sử bạn cần xác thực một số lĩnh vực liên quan đến logic kinh doanh. Mặc dù bạn có thể có các yêu cầu cụ thể bây giờ, bạn hoàn toàn nghi ngờ rằng chúng sẽ phát triển. Bạn có thể gói gọn logic hiện tại trong thủ tục / hàm / quy tắc / lớp của chính nó.
Mặc dù đây là một mối quan tâm trực giao không phải là một phần của "đóng gói những gì thay đổi", nhưng nó thường là tự nhiên để trừu tượng hóa, được tham số hóa bởi, logic hiện được đóng gói. Điều này thường dẫn đến mã linh hoạt hơn và cho phép thay đổi logic bằng cách thay thế trong một triển khai thay thế thay vì sửa đổi logic được đóng gói.