2012-04-09 22 views
9

Tôi đang viết một trình mô phỏng có một số giao diện mà tất cả các đối tượng mô phỏng thực hiện. Giao diện Entity có các phương thức mà tất cả các đối tượng phải có, chẳng hạn như truy xuất ID và tiến hành bước thời gian cho trạng thái của đối tượng. Collidable mở rộng Entity và đại diện cho bất kỳ thứ gì có khối lượng và vị trí cần được xem xét khi thuật toán phát hiện xung đột chạy. Field mở rộng Entity và đại diện cho bất kỳ thứ gì bản đồ vị trí thành giá trị; chúng được sử dụng để mô hình hóa những thứ như từ trường thấm vào thế giới nhưng không có khối lượng hoặc dạng vật lý. RigidBody là một lớp thực hiện Collidable và cung cấp các thuật toán động lực học cứng nhắc. Tôi có một lớp học World quản lý tất cả Entities và có phương pháp để thúc đẩy đồng hồ của trình mô phỏng và phân vùng thế giới để phát hiện va chạm hiệu quả hơn.Mô hình tốt để lưu trữ triển khai của một giao diện và truy xuất các triển khai cụ thể là gì?

Vấn đề của tôi liên quan đến việc truy xuất Entity loại phụ từ World. Ban đầu, World vừa có bản đồ là Entities được khóa bằng ID và để lấy Field hoặc RigidBody sẽ có các phương pháp lấy Entity ra khỏi bản đồ và thực hiện kiểm tra instanceof cộng với dàn diễn viên phụ. Tôi nhận thức rõ rằng việc sử dụng instanceof không được chấp nhận, tuy nhiên, vì vậy tôi đã thử một cách tiếp cận khác.

Hiện tại, tôi có bản đồ riêng trong phạm vi World cho mỗi giao diện. Ví dụ: có bản đồ cho Collidables cũng như bản đồ cho tất cả Entities. Phương thức addCollidable() sẽ thêm vào cả hai bản đồ và getCollidable() sẽ chỉ truy xuất từ ​​bản đồ Collidable. Điều này tránh instanceof, nhưng nó vẫn có vẻ như thiết kế kém cho tôi. Nếu tôi mơ lên ​​một giao diện khác để mở rộng Entity, tôi sẽ cần một bản đồ khác trong World và các phương thức tương ứng.

Tôi cảm thấy vấn đề này không quá tối nghĩa, vì vậy điều gì thường được thực hiện trong trường hợp này?

EDIT

Tôi không tin rằng mô hình khách sẽ làm việc ở đây, khi khách cho phép bạn để gửi vào loại bê tông, và một số các phương pháp phục hồi của tôi cần phải lấy loại giao diện. Ví dụ: Khách truy cập sẽ làm việc nếu World chỉ các phương thức cần thiết để truy xuất RigidBodies và các lớp cụ thể khác, nhưng tôi không thể tạo phương thức truy xuất tất cả Collidables với Khách truy cập.

+2

Bạn có thể có một cái gì đó như ' T getEntityFromMap (Clase clazz)', phương pháp này loại bỏ sự cần thiết của bản đồ 'Collidables', và bạn chỉ cần yêu cầu' getEntityFromMap (Entity.class) 'để có được một Thực thể trong trường hợp chung nhất của nó, và .... –

Trả lời

1

Ở đây những gì bạn có thể sử dụng là mẫu khách truy cập, Hướng dẫn này về Mô hình khách truy cập sử dụng nó dựa trên vấn đề tương tự bạn đang gặp phải. http://www.youtube.com/watch?v=KSEyIXnknoY

+0

Điều này gần với những gì tôi cần, nhưng tiếc là Khách truy cập gửi các loại cụ thể, và tôi yêu cầu khả năng gửi các loại trừu tượng/giao diện cũng như các loại cụ thể. – derefed

0

Có vẻ hợp lý với tôi, bạn sử dụng trường bổ sung cho collidables trong lớp học thế giới của bạn, vì nó là tập con dữ liệu đặc biệt, yêu cầu xử lý chuyên biệt.

Điều duy nhất tôi sẽ thay đổi (chủ yếu do sở thích cá nhân), sử dụng List<Collidable> làm loại, vì nhu cầu của bạn - lặp qua tất cả chúng để kiểm tra va chạm - danh sách nhanh hơn & cách tiếp cận nhẹ hơn.

+0

Câu hỏi tôi có ở đây là khi một số đối tượng 'obj' đang thực hiện' Collidable' được thêm vào 'World', thế nào' World' có thể nói rằng 'obj' nên được đặt vào' List 'mà không sử dụng kiểm tra 'instanceof'? – derefed

+0

Tôi giả sử bạn đã có một cái gì đó như 'World.addEntity (Entity newEntity)' Chỉ cần thêm 'World.addEntity (CollableableCollidable)', thực hiện nó một cách thích hợp, và để javac xử lý phần còn lại. – KJP

1

Sử dụng instanceof được tán thành vì nó thường là xuất hiện trong các ngữ cảnh mà nó gợi ý khi đóng gói không hoàn chỉnh. Ví dụ, instanceof đôi khi được sử dụng để phân biệt giữa các loại đối tượng khác nhau và sau đó hoạt động trên chúng tùy thuộc vào loại của chúng.Một cách làm sạch hơn có thể là đặt mã vào các lớp tương ứng của các đối tượng và sử dụng polymorphism để thay thế. Vì vậy, thay vì không bao giờ sử dụng instanceof, thay vì tự hỏi liệu việc sử dụng hiện tại của bạn là instanceof có thể là hợp pháp không?

Nói cách khác: Có thể di chuyển mã phụ thuộc vào loại thực thể vào lớp thực thể tương ứng không? (Tất nhiên, một khi bạn đạt đến một kết luận này nên được ghi chép, như mọi thứ có thể thay đổi.)

BTW Tôi nghĩ rằng bạn có thể dễ dàng khái quát bạn thiết kế hiện bằng cách sử dụng một Map<Class,List<Entity>>, mà sẽ cho phép bạn giữ danh sách thực thể cho một số loại tùy ý. Bạn cũng có thể có một mảng Class[] types = {...} có chứa tất cả các loại cần được phân biệt. Bây giờ, bạn chỉ cần một toán tử instanceof duy nhất trong vòng for trong các phương thức add/removeEntity(...) của bạn, sẽ đi qua tất cả các loại cần phân biệt và thêm/xóa đối tượng vào/khỏi tất cả danh sách có liên quan.

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