Những thay đổi trong hiệu suất có vi phạm Nguyên tắc thay thế Liskov không?


14

Nói rằng tôi có:

interface Thing
{
    GetThing();
}

class FastThing : Thing 
{
    public int GetThing()
    {
        return 1;
    }
}

class SlowThing : Thing
{
    public int GetThing()
    {
        return GetThingFromDatabase();
    }
}

Đây có phải là vi phạm Nguyên tắc thay thế Liskov không?


GetThingFromDatabase()không đủ chậm để làm cho điều này gây tranh cãi. Factor4096BitPublicKey();return 1;sẽ làm cho mọi thứ thú vị hơn một chút.
Patrick


1
Nếu bạn thay thế FastThingbằng SlowThing, LSP không áp dụng. Nếu bạn thêm một bình luận Thing::GetThingcó nội dung "Rất nhanh", câu hỏi có thể được thảo luận.
Cephalepad

Câu trả lời:


14

Điều đó thực sự phụ thuộc. Ví dụ, một số giao diện có các ràng buộc phức tạp (những giao diện này rõ ràng không thể được thi hành theo chương trình). Trường hợp cơ bản nhất là "GetThing () cung cấp cho int- tức là nó dừng lại", trong trường hợp đó, câu trả lời sẽ là "Không" - cả hai phiên bản của GetThing () đều dừng lại và trả về một int.

Nhưng nhiều giao diện đã ngụ ý hoặc tuyên bố rõ ràng đảm bảo hiệu suất, trong sự phức tạp hoặc trong thời gian phẳng. Ví dụ: trong Tiêu chuẩn C ++, việc triển khai thư viện với lệnh gọi chặn ngoại trừ trường hợp Tiêu chuẩn cho phép rõ ràng là bất hợp pháp.


3
Hiệu suất không phải là một cái gì đó có thể thi hành thông qua kiểm tra loại. Đó là một lời hứa của người thực hiện / bảo trì thư viện.
dietbuddha

3
Tôi tuyên bố rõ ràng như vậy trong câu trả lời của tôi?
DeadMG

1
Quan điểm của tôi là ngay khi bạn đưa vào bất cứ điều gì khác ngoài việc nhập vào các tiêu chí, bạn sẽ không còn nói về Liskov nữa vì nó là cụ thể để nhập. Trong khi "thực hành" không khuất phục các đối tượng hoạt động khác nhau có thể là tốt, bản thân Liskov không có gì để nói về nó.
dietbuddha

7
Liskov tuyên bố rằng đối với Người xuất phát, nó có thể được sử dụng ở bất cứ nơi nào có Căn cứ. Điều đó cũng có thể không đúng nếu Cơ sở đảm bảo các màn trình diễn hoặc đặc điểm nhất định. Ví dụ: nếu các khối Derogen, có thể có khả năng xảy ra bế tắc.
DeadMG

8

TL; DR: Không

Theo "Phân loại hành vi sử dụng bất biến và ràng buộc" (chính thức hóa nguyên tắc), nó chủ yếu liên quan đến các thuộc tính "an toàn" của một loại đối tượng. Các thuộc tính chi phối sự thay thế chỉ trong bối cảnh thông tin loại. Một loại đối tượng là trực giao với hiệu suất của nó. Do đó, một sự khác biệt trong hiệu suất không phải là vi phạm Nguyên tắc thay thế Liskov.


3
Tôi chỉ có một cái nhìn ngắn gọn về bài báo đó, nhưng bạn có chắc rằng những hạn chế về thời gian không thể được thực hiện chính thức? Và ngay cả khi Liskov không có nghĩa là bằng lời, bao gồm các hạn chế về thời gian có thể được coi là một phần mở rộng tốt của LSP cổ điển có thể liên quan đến lập trình trong thế giới thực.
Doc Brown

@Doc Brown: liệu thời gian có hữu ích khi xem xét thay thế một đối tượng hay không là trực giao với Liskov. Để có thể thêm nó dưới dạng giới hạn, nhưng không thể và sẽ không bao giờ là một phần của Liskov. Nó giống như có một phương trình logic Boolean và nói! Sai chỉ có thể được thay thế bằng True nếu nó đủ nhanh. Tốc độ không liên quan gì đến toán học hay logic.
Dietbuddha

Ví dụ mẫu: mã này được gọi trong EDT của Java hoặc trong vòng lặp sự kiện của Node. Hiệu suất hoàn toàn chậm hơn của phiên bản chậm sẽ phá vỡ phần mềm. Tôi nghĩ rằng câu trả lời thích hợp cho câu hỏi này là "có thể không nhưng có ngoại lệ".
user949300

6

Giao diện đảm bảo những gì? Vì GetThingkhông đảm bảo nên các kiểu con không cần phải tôn trọng nó.

Nếu giao diện giống như GetThingInLinearTimehoặc nếu loại cơ sở là ảo và việc triển khai mặc định là một độ phức tạp, thì làm cho độ phức tạp thuật toán đó tệ hơn sẽ vi phạm LSP.


4

Hiệu suất của phần mềm không liên quan gì đến Nguyên tắc thay thế Liskov.

Nguyên tắc phải làm với việc thay thế các kiểu con và tác động hành vi của việc thay thế đối tượng đó chỉ bằng thuật ngữ OOP.

Đầu vào và đầu ra getThing()vẫn giữ nguyên cho cả hai trường hợp và cả chậm và nhanh đều có thể đưa các đối tượng vào cùng một trạng thái.


1

Có vấn đề gì với nguyên tắc thay thế Liskov nói cụ thể không? Nếu một kiểu con vi phạm sự mong đợi của người tiêu dùng của siêu kiểu, điều đó có vẻ như là một điều xấu bất kể LSP có hạn chế hơn hay không.

Vì vậy, theo quan điểm của tôi, liệu tất cả các kỳ vọng hợp lý của người tiêu dùng về sự trừu tượng có được đáp ứng bởi tiểu loại dường như là một khái quát tốt về LSP.

Tuy nhiên, trong ví dụ bạn đã đăng và với các giao diện Java nói chung, không rõ người tiêu dùng Thinggiao diện có bất kỳ kỳ vọng hợp lý nào về việc nó nên nhanh hay chậm. Nếu javadocs của giao diện bao gồm ngôn ngữ về các hoạt động được hứa hẹn là nhanh, thì có thể có một đối số cho một vấn đề trên cơ sở hiệu suất. Nhưng quy ước Java chắc chắn là cho các triển khai khác nhau có các đặc tính hiệu năng khác nhau.


2
theo như tôi có thể nói, ví dụ được đăng không phải là Java
gnat

0

Chú Bob đã trả lời một câu hỏi tương tự trong đó ông nói rằng vi phạm LSP cần có 3 bên:

Loại T, Subtype S và chương trình P sử dụng T nhưng được cung cấp một thể hiện của S.

Tôi sẽ mạo hiểm đoán rằng câu hỏi này có cấu trúc tương tự như câu hỏi mà anh ta đã trả lời, trong đó nó không đề cập đến P đang sử dụng T và hành vi mà P mong đợi.

Bạn có thể tìm thấy câu trả lời của anh ấy ở đây . (Bạn sẽ cần cuộn xuống một số và tìm câu trả lời từ người dùng có tên Robert Martin)


1
Làm thế nào để trả lời câu hỏi này?
gnat

@gnat Vì câu hỏi, như đã hỏi, chưa đầy đủ. Phải mất 3 bên để xác định vi phạm LSP. Trong đó, ông chỉ cung cấp cho 2 bên.
TMc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.