2015-06-03 19 views
8

GIỚI THIỆUNguyên tắc SOLID nào bị vi phạm?


tôi làm việc trên luận án thạc sĩ của tôi về vấn đề thừa kế và làm việc ra một số chỉ số đó cho thấy một vấn đề thừa kế tồn tại.

Giống như ví dụ sau:

VÍ DỤ


public static String getAnimalNoise(Animal animal) { 
    if (animal instanceof Dog) 
    return "Woof"; 
    if (animal instanceof Cat) 
    return "Miau"; 
    return ""; 
} 

Phương pháp này trả về chuỗi "Woof" nếu trường hợp động vật nhất định là một Dog"Miau" nếu nó là một Cat. Chuỗi rỗng bởi vì một số động vật không gây tiếng động gì cả.

Vì vậy, giải pháp đúng cho điều đó nên sử dụng đa hình với phương thức getNoise trong lớp Động vật.

Tôi đã phân tích các chỉ báo khác nhau về các vấn đề kế thừa và muốn nói nếu một số trong số chúng vi phạm SOLID Principle.

Tôi nghĩ ví dụ trên vi phạm:

  1. nguyên tắc trách nhiệm đơn (SRP)
  2. mở/đóng nguyên tắc (OCP)
  3. Liskov nguyên tắc thay thế (LSP)
  4. Nguyên tắc đảo ngược phụ thuộc (DIP)

Nhưng tôi không thực sự chắc chắn cho dù đó là sự thật cho tất cả.

tôi nghĩ:

NGUYÊN TẮC VI PHẠM


SRP Vi phạm

Bởi vì báo cáo có điều kiện ở tất cả các vi phạm SRP, bởi vì như switch trường hợp tuyên bố trở lên hơn một câu lệnh if-else được xem xét nhiều hơn một câu trả lời sibility.

Nó tồn tại hai trường hợp vì vậy có nhiều lý do để thay đổi phương pháp.

OCP Vi phạm

Bởi vì nếu một con vật mới được thêm một trường hợp mới phải được bổ sung vào phương pháp nên Phương pháp chưa chặt chẽ cho sửa đổi.

LSP VI PHẠM

Mỗi chi nhánh thực hiện hành động khác nhau phụ thuộc của các loại phụ gia súc. Tôi cho rằng vi phạm số LSP?! Tôi biết ví dụ về hình chữ nhật và hình vuông và getArea nhưng ví dụ tôi nghĩ này cũng phù hợp với vi phạm.

DIP VI PHẠM

Các báo cáo có điều kiện đi sự phụ thuộc đó có nghĩa là những điều khoản phụ thuộc vào chi tiết và không phải trên trừu tượng vi phạm các DIP.

HỎI:


Vì vậy, câu hỏi là, cho ví dụ được đưa ra, được các nguyên tắc cho sự vi phạm và là lý do đúng không?

+0

Đây có thể là chủ đề về Programmers.SE hơn. – MSalters

Trả lời

8

SRP Bởi vì báo cáo có điều kiện ở tất cả các vi phạm SRP, bởi vì như báo cáo trường hợp chuyển mạch hoặc nhiều hơn một lệnh if-else được xem xét nhiều hơn một trách nhiệm. Nó tồn tại hai trường hợp vì vậy có nhiều lý do để thay đổi phương thức.

Tôi rất không đồng ý. SRP có nghĩa là được giải thích với một nhúm muối. Đọc Uncle Bob's article on it here - ông đã đặt ra nguyên tắc này.

tôi sẽ báo giá các bit quan trọng:

gì định nghĩa một lý do để thay đổi?

Nguyên tắc này là về con người. Khi bạn viết một module phần mềm, bạn muốn đảm bảo rằng khi thay đổi được yêu cầu, những thay đổi đó chỉ có thể bắt nguồn từ một người, hay đúng hơn, một nhóm người kết hợp chặt chẽ đại diện cho một chức năng kinh doanh được xác định hẹp. Bạn muốn tách biệt các mô-đun của bạn khỏi sự phức tạp của toàn bộ tổ chức và thiết kế các hệ thống của bạn sao cho mỗi mô-đun có trách nhiệm (đáp ứng) nhu cầu của chỉ một chức năng kinh doanh đó.

[...] khi bạn nghĩ về nguyên tắc này, hãy nhớ rằng lý do thay đổi là con người. Đó là những người yêu cầu thay đổi. Và bạn không muốn gây nhầm lẫn cho những người đó, hoặc bản thân bạn, bằng cách trộn lẫn mã mà nhiều người khác nhau quan tâm vì những lý do khác nhau.


OCP Bởi vì nếu một con vật mới được thêm một trường hợp mới phải được bổ sung vào phương pháp này nên Phương không đóng cho sửa đổi.

Đúng. Phương thức này giả định một bộ triển khai cụ thể và sẽ không thể xử lý các cài đặt mới mà không bị sửa đổi.


LSP Mỗi chi nhánh thực hiện hành động khác nhau phụ thuộc của các loại phụ gia súc. Mà tôi nghĩ rằng vi phạm LSP?!

Vi phạm LSP, nhưng vì một lý do khác. Nếu tôi đi ngang qua một con hươu cao cổ, tôi sẽ nhận được một kết quả bất ngờ, một sợi dây trống. Điều này có nghĩa là phương pháp không chính xác đối với bất kỳ loại phụ nào là Animal.


DIP Các báo cáo có điều kiện đi sự phụ thuộc đó có nghĩa là những điều khoản phụ thuộc vào chi tiết và không phải trên trừu tượng vi phạm các DIP.

Về mặt kỹ thuật, nhưng đây chỉ là tác dụng phụ của việc vi phạm hai nguyên tắc khác ở trên. Nó không thực sự là cốt lõi của vấn đề.


Hãy nhớ rằng nguyên tắc không phải là quy tắc, do đó, đừng quá nghiêm khắc/theo nghĩa đen khi diễn giải chúng. Chủ nghĩa thực dụng và sự hiểu biết lý do tại sao một nguyên tắc là cần thiết là chìa khóa.

+0

Tôi muốn thêm DIP: phương thức sẽ phụ thuộc vào 'MakesNoiseInterface' thay vì các lớp cụ thể. – deceze

+0

@deceze Không cần giao diện, sự trừu tượng đã tồn tại: 'Động vật'. Vấn đề là loại kiểm tra đối với các động vật cụ thể, và cá nhân tôi sẽ giải quyết nó bằng cách di chuyển phương thức 'getNoise' bên trong' Động vật', giải quyết tất cả 3 hành vi vi phạm. – dcastro

+1

Cảm ơn rất nhiều vì câu trả lời nhanh! Đối với SRP tôi nghĩ rằng bạn thấy sai Sách của Robert C. Martin Mã số trang web sạch 38> Có một số vấn đề với chức năng này. Đầu tiên, nó lớn và khi mới thêm loại nhân viên, nó sẽ phát triển. Thứ hai, nó rất rõ ràng làm nhiều hơn một điều. Thứ ba, vi phạm Nguyên tắc về Trách nhiệm duy nhất7 (SRP) vì có nhiều hơn một số lý do để thay đổi. Đây là tham chiếu mã sạch: https://cleansourcecode.files.wordpress.com/2013/10/clean-code.pdf – Zelldon

1

Tôi không đồng ý với việc mã mẫu của bạn vi phạm LSP. LSP được định nghĩa như sau:

Cho Φ (x) là tài sản có thể chứng minh được về các đối tượng x loại T. Sau đó, (y) phải đúng đối với các đối tượng y loại S trong đó S là một phân loại của T.

Căn cứ vào hai nguồn gốc từ động vật, cụ thể là DogCat và phương pháp của bạn getAnimalNoise bạn không đưa ra quyết định về một số tài sản proveable của đối tượng cụ thể. Phương pháp của bạn là quyết định những gì tiếng ồn nên được trả lại và không phải là các đối tượng của chính nó.

Vì vậy, hãy tưởng tượng bạn có thể đặt số chân cho một con vật.

Animal a = new Animal() 
a.setLegFront(2); 
a.setLegRear(2); 

Và nếu Dog bạn ghi đè này như thế này:

class Dog extends Animal 
{ 
    public void setFrontLegs(int legs) 
    { 
    this.frontLegs = legs; 
    this.rearLegs = legs + 2; 
    } 
    public void setRearLegs(int legs) 
    { 
    // do nothing here for demonstration purposes 
    } 
} 

Nếu bây giờ bạn có một nhà máy trả lại một Animal

Animal createAnimal() 
{ 
    return new Dog(); 
} 
Animal a = createAnimal(); 
a.setFrontLegs(2); 
a.setRearLegs(2); 

Và bạn gọi phương pháp setFront/setRearLegs bạn đang mong đợi kết quả là 2 và 2 nhưng trên thực tế kết quả là hoàn toàn khác nhau, cụ thể là 2 và 4. Vì vậy, ví dụ này được ràng buộc chặt chẽ với dấu phẩy Ví dụ LSP với hình vuông và hình chữ nhật. Nhưng đối với tôi, nó là một ví dụ chính xác hơn về sự vi phạm các đặc tính có thể chứng minh được trong ví dụ của bạn.

Cập nhật cho các nguyên tắc khác

Tôi đồng ý với bạn rằng các nguyên tắc khác cũng bị vi phạm nhưng đối với SRP Tôi đồng ý với @dcastro.

+0

Cảm ơn. Whats về các nguyên tắc khác? – Zelldon

Các vấn đề liên quan