Sự khác biệt giữa Dịch vụ trò chơi XNA và các biến toàn cầu được tôn vinh là gì?


10

Các Microsoft.Xna.Framework.Gamelớp học có một dịch vụ bất động sản, cho phép các lập trình viên để thêm một dịch vụ trò chơi của họ để bằng cách cung cấp các loại hình lớp và một thể hiện của lớp để Add phương pháp.

Bây giờ, thay vì phải truyền một AudioComponentcho tất cả các lớp và phương thức yêu cầu nó, thay vào đó bạn chỉ cần truyền Gameví dụ của bạn và tra cứu dịch vụ. ( Định vị dịch vụ )

Giờ đây, vì các trò chơi có nhiều dịch vụ (GraphicsDevice, SceneGraph, AudioComponent, EffectsManager, et cetera), nên về cơ bản bạn sẽ chuyển Game sang mọi thứ.

Vậy tại sao không biến những trường hợp này thành Singleton? Chà, bởi vì Singletons rất tệ bởi vì chúng có trạng thái toàn cầu, ngăn chặn thử nghiệm và làm cho thiết kế của bạn dễ vỡ hơn nhiều. Các trình định vị dịch vụ được coi là một mô hình chống đối với nhiều người vì thay vì chỉ truyền phụ thuộc vào một đối tượng, bạn chuyển một trình định vị dịch vụ (Trò chơi) kết hợp với các dịch vụ còn lại.

Vậy thì tại sao Dịch vụ được đề xuất trong XNA và phát triển trò chơi? Có phải vì các trò chơi khác với các chương trình thông thường và rất đan xen với các thành phần của chúng và phải vượt qua mọi thành phần cần thiết cho hoạt động của một lớp sẽ rất cồng kềnh? Có phải Dịch vụ trò chơi sau đó là một điều ác cần thiết trong thiết kế trò chơi? Có những lựa chọn thay thế không liên quan đến danh sách tham số dài và khớp nối?


3
"Các trình định vị dịch vụ được coi là một mô hình chống đối với nhiều người" - [cần dẫn nguồn]. Rõ ràng việc sử dụng chúng khi bạn không cần chúng là xấu - đúng với tất cả các cấu trúc phần mềm - nhưng tôi chưa bao giờ nghe thấy các công cụ định vị dịch vụ được gọi là chống mẫu. (Mặt khác, tôi cũng cố gắng tránh các lập trình viên dành phần lớn thời gian để thảo luận về các chi tiết nhỏ nhất.)

@JoeWreschnig mặc dù tôi đồng ý với bạn, tôi đã thực hiện một số hoạt động đào và tìm thấy điều này: blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPotype.aspx
Roy T.

2
Có, nhưng anh chàng đó đang bán một cuốn sách về việc sử dụng DI; rõ ràng anh ta không muốn bạn sử dụng thứ gì đó đơn giản, sau đó bạn sẽ không mua sách của anh ta! (Trong tất cả các mức độ, bài viết DI / SL gốc Fowler của phủ chủ đề chính xác này - martinfowler.com/articles/... - và blog rant của anh chàng đó cho biết thêm không có gì để thảo luận.)

Tôi ước tôi có thể đánh dấu liên kết mà bạn vừa đăng từ Martin Fowler là câu trả lời (mặc dù đó không phải là câu hỏi của tôi)
Roy T.

Câu trả lời:


6

Tôi không nghĩ mọi người đồng ý rằng những người định vị dịch vụ là xấu. Bộ định vị dịch vụ cung cấp một cách để tách rời chức năng quan trọng mà mọi người cần từ việc triển khai thực tế của họ. Định vị dịch vụ cũng cung cấp một cách để trao đổi dịch vụ trong thời gian chạy. Ngoài ra tôi không nghĩ đúng là bạn cần phải đi qua công cụ định vị dịch vụ ở khắp mọi nơi. Tôi nghĩ bạn có thể truy cập nó từ khắp mọi nơi. Trong khi một lớp trò chơi với toàn cầu sẽ cần phải được thông qua khoảng một nghìn lần trên mỗi khung hình (điều này sẽ gây ra hiệu suất kém).

Để tạo sự khác biệt giữa trình định vị dịch vụ và một lớp có toàn cầu rõ ràng hơn một chút, hãy xem xét ví dụ sau:

Tôi đang tạo một trò chơi và sử dụng một đối tượng lớp gameA có một biến toàn cục: trình tải nội dung. Bây giờ trong trò chơi tiếp theo của tôi, tôi không muốn sử dụng lớp gameA mà tạo một lớp gameB mới. Bây giờ tôi phải thêm một lần nữa toàn cầu của gameA vào gameB, đây là công việc làm thêm. Ngoài ra, nó trở nên khó khăn để cấu hình loại trình tải nội dung tôi muốn. Nói rằng tôi có một trò chơi chạy cả trên PC và trên XBOX. Trên PC tôi muốn một trình tải nội dung cũng có thể mở hộp thoại 'mở tệp'. Trong khi trên XBOX tôi chắc chắn không muốn điều này. Bằng cách có một tệp cấu hình, tôi thậm chí có thể thay đổi nửa chừng trò chơi một cách dễ dàng thay đổi trình tải nội dung, thậm chí từ một nơi khác ngoài lớp gameA, mà không cần công khai toàn cầu trong gameA.

Bây giờ hãy xem xét tôi đang sử dụng một công cụ định vị dịch vụ. Tôi luôn có thể tiếp tục sử dụng nó. Và thậm chí loại dịch vụ nào cũng có thể khác nhau mọi lúc. Cũng đúng là tôi thậm chí sẽ không quan tâm đến việc triển khai của họ miễn là họ có giao diện chung. (Mặc dù tôi có thể sử dụng nó trong một gamA giống như lớp).

Dù sao, tôi nghĩ rằng bạn sẽ tìm thấy các dịch vụ trò chơi khá tiện dụng. Mọi người tôi biết đều sử dụng nó. Để giúp bạn ra ngoài một chút. Tôi đã tạo một lớp người trợ giúp nhỏ xung quanh các dịch vụ trò chơi để bạn có thể thực hiện ít hơn một chút thời gian: http://roy-t.nl/index.php/2010/08/25/xna-accessing-contentmanager -và đồ họa-bất cứ nơi nào-bất cứ lúc nào-the-gameservicecontainer / Tôi sử dụng nó khá nhiều.


Cảm ơn vi đa trả lơi. Trong một lớp sẽ yêu cầu dịch vụ, bạn thường chỉ yêu cầu lớp GameService cho dịch vụ bất cứ khi nào cần hoặc bạn có tạo một biến thành viên trong lớp và chỉ yêu cầu dịch vụ trong hàm tạo không? Tôi cho rằng những gì tôi đang hỏi là làm thế nào chậm return (T)Instance.GetService(typeof(T));.
John Pollick

Ngoài ra, bạn nghĩ gì về việc triển khai lớp GameService này? Tôi đã loại bỏ các singleton không cần thiết vì nó không có bất kỳ tính năng nào mà sự trừu tượng không có. Ngoài ra, tôi đã loại bỏ Servicehậu tố dư thừa ở cuối mỗi phương thức.
John Pollick

Ngoài ra, tôi nghĩ lý do mà AddServicephương thức Dịch vụ lấy một loại là để bạn có thể chỉ định giao diện của dịch vụ. Ví dụ , Services.AddService(typeof(IGraphicsDeviceManager), graphics);. Sau đó, khi truy xuất dịch vụ, bạn có thể chỉ định giao diện là loại và chuyển nó sang lớp con đã chọn.
John Pollick

@JohnPollick, cho câu hỏi đầu tiên. Tôi cố gắng luôn yêu cầu nó (vì nó có thể thay đổi) nhưng nếu tôi thực sự cần thứ gì đó thì mỗi khung hình tôi sẽ tạo một biến thành viên. Tôi không có nhiều số liệu thống kê hiệu suất khác hơn là nó chưa bao giờ là nút cổ chai đối với tôi. Thứ hai, yeah nó có vẻ tốt :). Và cho thứ ba. Đó thực sự là lý do cho đối số kiểu, tuy nhiên, bạn không bao giờ nên tạo thói quen hạ thấp các giá trị được truy xuất vì điều đó sẽ phá hủy khả năng của bạn để trao đổi các lớp dưới dạng dịch vụ. Nếu bạn không muốn một IGraphicsDeviceManger nhưng MyGDM thì có thể tạo giao diện mới.
Roy T.

1
Oh tôi đã không nhìn thấy bạn cũng đúc. Tất nhiên là nó có thể suy ra kiểu nếu bạn chọn đầu tiên :).
Roy T.

5

Vậy tại sao không biến những trường hợp này thành Singleton? Chà, bởi vì Singletons rất tệ bởi vì chúng có trạng thái toàn cầu, ngăn chặn thử nghiệm và làm cho thiết kế của bạn dễ vỡ hơn nhiều.

Singletons thường có rất nhiều đặc điểm hữu ích và kết hợp chúng lại với nhau trong một sự kết hợp khủng khiếp mang đến cho bạn một số điều bạn không muốn cùng với bất kỳ điều gì bạn muốn. (Đó có phải là đặc điểm 'tạo theo yêu cầu' không? Phạm vi toàn cầu? Thi hành ít nhất một trường hợp? Cấm nhiều trường hợp?)

Các trình định vị dịch vụ được coi là một mô hình chống đối với nhiều người vì thay vì chỉ truyền phụ thuộc vào một đối tượng, bạn chuyển một trình định vị dịch vụ (Trò chơi) kết hợp với các dịch vụ còn lại.

Bạn không thể tránh khớp nối hoàn toàn. Mọi thứ sử dụng những thứ khác và không có điều đó chương trình của bạn không làm gì cả. Vì vậy, câu hỏi thực sự duy nhất là mức độ trừu tượng của nó.

Hầu hết các văn bản về định hướng đối tượng tạo nên sự khác biệt giữa Thành phần và Tập hợp. Điều quan trọng là phải biết sự khác biệt về khái niệm giữa một cái gì đó mà bạn sở hữu và một cái gì đó mà bạn biết. Thật không may, hầu hết các ngôn ngữ hiện đại không có sự phân biệt rõ ràng ở đây và một tham chiếu đến một đối tượng có thể có nghĩa là một trong những điều này. (Trớ trêu thay, C ++ thực hiện công việc tốt hơn, nếu bạn sử dụng các loại con trỏ thông minh khác nhau.)

Một cách mà bạn có thể làm cho thành phần và tổng hợp rõ ràng trong mã của mình là sử dụng các dịch vụ cho các đối tượng tổng hợp. Dịch vụ là một cách để cung cấp quyền truy cập vào nội dung bạn không sở hữu nhưng bạn có thể sử dụng dịch vụ.

Vậy thì tại sao Dịch vụ được đề xuất trong XNA và phát triển trò chơi?

Tôi không nghĩ rằng chúng được khuyến khích phổ biến trong phát triển trò chơi.

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.