Đa hình
Miễn là bạn sử dụng getType()
hoặc bất cứ thứ gì tương tự, bạn không sử dụng đa hình.
Tôi hiểu cảm giác như bạn cần biết bạn có loại gì. Nhưng bất kỳ công việc nào bạn muốn làm trong khi biết rằng thực sự nên được đẩy xuống lớp. Sau đó, bạn chỉ cần nói khi nào để làm điều đó.
Mã thủ tục nhận thông tin sau đó đưa ra quyết định. Mã hướng đối tượng cho các đối tượng làm việc.
- Alec sắc nét
Nguyên tắc này được gọi là nói, đừng hỏi . Làm theo nó giúp bạn không lan truyền các chi tiết như gõ xung quanh và tạo ra logic hoạt động trên chúng. Làm điều đó biến một lớp học từ trong ra ngoài. Tốt hơn là giữ hành vi đó bên trong lớp để nó có thể thay đổi khi lớp thay đổi.
Đóng gói
Bạn có thể nói với tôi rằng sẽ không cần hình dạng nào khác nhưng tôi không tin bạn và bạn cũng không nên.
Một hiệu ứng tuyệt vời của việc đóng gói sau là dễ dàng thêm các loại mới vì các chi tiết của chúng không lan truyền vào mã nơi chúng hiển thị if
và switch
logic. Mã cho một loại mới tất cả phải ở một nơi.
Một loại hệ thống phát hiện va chạm không biết gì
Hãy để tôi chỉ cho bạn cách tôi thiết kế một hệ thống phát hiện va chạm có hiệu suất và hoạt động với bất kỳ hình dạng 2D nào bằng cách không quan tâm đến loại.
Nói rằng bạn phải vẽ nó. Có vẻ đơn giản. Đó là tất cả các vòng tròn. Thật hấp dẫn khi tạo ra một lớp vòng tròn hiểu được sự va chạm. Vấn đề là điều này khiến chúng ta suy nghĩ về một dòng suy nghĩ sụp đổ khi chúng ta cần 1000 vòng tròn.
Chúng ta không nên nghĩ về vòng tròn. Chúng ta nên suy nghĩ về pixel.
Điều gì sẽ xảy ra nếu tôi nói với bạn rằng cùng một mã bạn sử dụng để vẽ những kẻ này là những gì bạn có thể sử dụng để phát hiện khi họ chạm vào hoặc ngay cả những mã mà người dùng đang nhấp vào.
Ở đây tôi đã vẽ mỗi vòng tròn bằng một màu duy nhất (nếu mắt bạn đủ tốt để nhìn đường viền màu đen, hãy bỏ qua điều đó). Điều này có nghĩa là mọi pixel trong ảnh ẩn này ánh xạ trở lại những gì đã vẽ nó. Một hashmap chăm sóc điều đó độc đáo. Bạn thực sự có thể làm đa hình theo cách này.
Hình ảnh này bạn không bao giờ phải hiển thị cho người dùng. Bạn tạo nó với cùng một mã đã vẽ cái đầu tiên. Chỉ với màu sắc khác nhau.
Khi người dùng nhấp vào vòng tròn tôi biết chính xác vòng tròn nào vì chỉ có một vòng tròn là màu đó.
Khi tôi vẽ một vòng tròn lên trên một vòng tròn khác, tôi có thể nhanh chóng đọc mọi pixel tôi sắp ghi đè bằng cách bỏ chúng vào một tập hợp. Khi tôi thực hiện xong các điểm được đặt cho mỗi vòng tròn mà nó va chạm và bây giờ tôi chỉ phải gọi cho mỗi người một lần để thông báo về vụ va chạm.
Một loại mới: Hình chữ nhật
Tất cả điều này được thực hiện với các vòng tròn nhưng tôi hỏi bạn: nó có hoạt động khác với hình chữ nhật không?
Không có kiến thức vòng tròn đã bị rò rỉ vào hệ thống phát hiện. Nó không quan tâm đến bán kính, chu vi hoặc điểm trung tâm. Nó quan tâm đến pixel và màu sắc.
Phần duy nhất của hệ thống va chạm này cần được đẩy xuống thành các hình dạng riêng lẻ là một màu độc đáo. Khác hơn là các hình dạng chỉ có thể nghĩ về việc vẽ hình dạng của chúng. Dù sao thì đó cũng là những gì họ giỏi.
Bây giờ khi bạn viết logic va chạm, bạn không quan tâm bạn có loại phụ nào. Bạn bảo nó va chạm và nó cho bạn biết những gì nó tìm thấy dưới hình dạng nó giả vờ vẽ. Không cần biết loại. Và điều đó có nghĩa là bạn có thể thêm bao nhiêu loại phụ tùy thích mà không phải cập nhật mã trong các lớp khác.
Lựa chọn thực hiện
Thực sự, nó không cần phải là một màu độc đáo. Nó có thể là các tham chiếu đối tượng thực tế và lưu một mức độ gián tiếp. Nhưng những điều đó sẽ không đẹp khi được rút ra trong câu trả lời này.
Đây chỉ là một ví dụ thực hiện. Chắc chắn có những người khác. Điều này có nghĩa là cho thấy rằng bạn càng để các kiểu con hình dạng này gắn bó với trách nhiệm duy nhất của chúng thì toàn bộ hệ thống hoạt động càng tốt. Có thể có các giải pháp sử dụng nhiều bộ nhớ nhanh hơn và ít bộ nhớ hơn nhưng nếu chúng buộc tôi phải truyền bá kiến thức về các kiểu con xung quanh thì tôi sẽ không thích sử dụng chúng ngay cả khi đạt được hiệu suất. Tôi sẽ không sử dụng chúng trừ khi tôi rõ ràng cần chúng.
Công văn đôi
Cho đến bây giờ tôi đã hoàn toàn bỏ qua công văn đôi . Tôi đã làm điều đó bởi vì tôi có thể. Chừng nào logic va chạm không quan tâm hai loại va chạm nào bạn không cần nó. Nếu bạn không cần nó, đừng sử dụng nó. Nếu bạn nghĩ rằng bạn có thể cần nó, hãy ngừng giao dịch với nó miễn là bạn có thể. Thái độ này được gọi là YAGNI .
Nếu bạn quyết định bạn thực sự cần các loại va chạm khác nhau thì hãy tự hỏi nếu các kiểu con hình n thực sự cần n 2 loại va chạm. Cho đến nay tôi đã làm việc rất chăm chỉ để dễ dàng thêm một kiểu con hình dạng khác. Tôi không muốn làm hỏng nó bằng cách thực hiện công văn kép buộc các vòng tròn phải biết rằng hình vuông tồn tại.
Có bao nhiêu loại va chạm có? Một chút suy đoán (một điều nguy hiểm) phát minh ra các va chạm đàn hồi (bouncy), không đàn hồi (dính), tràn đầy năng lượng (khám phá) và phá hoại (damagy). Có thể có nhiều hơn nhưng nếu điều này nhỏ hơn n 2 thì đừng cho phép thiết kế va chạm của chúng ta.
Điều này có nghĩa là khi ngư lôi của tôi chạm vào thứ gì đó chấp nhận thiệt hại, nó không phải BIẾT nó trúng tàu không gian. Nó chỉ phải nói với nó, "Ha ha! Bạn đã nhận 5 điểm sát thương."
Những thứ gây sát thương sẽ gửi thông điệp thiệt hại đến những thứ chấp nhận thông điệp thiệt hại. Thực hiện theo cách đó bạn có thể thêm hình dạng mới mà không cần nói với các hình dạng khác về hình dạng mới. Bạn chỉ kết thúc lan truyền xung quanh các loại va chạm mới.
Con tàu không gian có thể gửi lại cho ngư lôi "Ha ha! Bạn đã nhận 100 điểm thiệt hại." cũng như "Bây giờ bạn đang bị mắc kẹt vào thân tàu của tôi". Và sự đau khổ có thể gửi lại "Chà, tôi đã làm xong vì vậy hãy quên tôi đi".
Không có gì biết chính xác mỗi cái là gì. Họ chỉ biết nói chuyện với nhau thông qua giao diện va chạm.
Bây giờ chắc chắn, công văn kép cho phép bạn kiểm soát mọi thứ mật thiết hơn thế này nhưng bạn có thực sự muốn điều đó không?
Nếu bạn làm, ít nhất hãy nghĩ về việc thực hiện gửi hai lần thông qua sự trừu tượng về loại va chạm nào mà hình dạng chấp nhận và không phải trên hình thực hiện hình dạng thực tế. Ngoài ra, hành vi va chạm là thứ bạn có thể tiêm như một người phụ thuộc và ủy thác cho sự phụ thuộc đó.
Hiệu suất
Hiệu suất luôn luôn quan trọng. Nhưng điều đó không có nghĩa là nó luôn luôn là một vấn đề. Hiệu suất thử nghiệm. Đừng chỉ suy đoán. Hy sinh tất cả mọi thứ khác trong tên hiệu suất thường không dẫn đến mã đục lỗ.