Có phải là một ý tưởng tồi khi có Game1 tĩnh trong XNA?


10

Có phải là một ý tưởng thực sự tồi tệ để có Game1lớp học của tôi là tĩnh? Hiện tại trong Game1lớp tôi có một lớp gọi là TileHandlerxử lý mọi việc phải làm với bộ gạch hiện tại của tôi và AnimalHandlerxử lý tất cả các con vật của tôi (đáng ngạc nhiên).

Bây giờ nếu tôi đang ở trong AnimalHandlervà muốn kiểm tra xem một lát có thể đi bộ được không TileHandlerthì điều đó có gây ra sự cố không hoặc tôi phải chuyển một danh sách các gạch có thể đi bộ vào AnimalHandler, điều mà tôi không muốn làm.

Điều gì sẽ dễ dàng hơn là làm cho Game1tĩnh và sau đó AnimalHandlerchỉ cần đi Game1._tileHandler.WalkableTile(position).

Bây giờ tôi không thể thấy bất cứ điều gì sai ngay lập tức với điều này hoặc bất cứ điều gì gây ra bất kỳ vấn đề nào nhưng tôi chỉ mới bắt đầu sử dụng các lớp tĩnh, vậy có ai hiểu biết hơn về bất kỳ lý do lớn nào tại sao đó là một ý tưởng tồi không?

Câu trả lời:


9

Bây giờ tôi không thể thấy bất cứ điều gì sai ngay lập tức với điều này hoặc bất cứ điều gì gây ra bất kỳ vấn đề nào nhưng tôi chỉ mới bắt đầu sử dụng các lớp tĩnh, vậy có ai hiểu biết hơn về bất kỳ lý do lớn nào tại sao đó là một ý tưởng tồi không?

Khi bạn có một cái búa mới sáng bóng, mọi vấn đề trông giống như một cái đinh.

Nói chung, không có gì sai với các lớp và / hoặc các phương thức tĩnh, nếu được sử dụng đúng cách (đối với những thứ không có hoặc phụ thuộc vào trạng thái của từng thể hiện). Tuy nhiên, trong trường hợp của bạn, bạn đang lạm dụng chúng để che giấu sự phụ thuộc vào từng trường hợp, nhầm lẫn điều này với việc loại bỏ sự phụ thuộc. Nó cũng xuất hiện rằng bạn đang tiết lộ chi tiết thực hiện củaGame1 lớp, điều này cũng thường là xấu.

Đây là mấu chốt của vấn đề của bạn:

... Nếu tôi đang ở trong AnimalHandlervà muốn kiểm tra xem một lát có thể đi được không TileHandlerthì điều đó có gây ra sự cố không hoặc tôi phải chuyển một danh sách các gạch có thể đi được vào AnimalHandler, điều mà tôi không muốn làm.

Bỏ qua khả năng AnimalHandlercần các gạch này có thể là một thiết kế tồi (với tên bạn đã chọn, thật khó để nói chi tiết về các lớp này) vào lúc này ... nếu AnimalHandlercần một danh sách các gạch có thể đi bộ, thì nó cần một danh sách gạch có thể đi bộ. Nói chung là tốt hơn để làm cho các phụ thuộc rõ ràng hơn ít hơn , vì nó làm cho mã nhiều tài liệu hơn. Bằng cách chuyển danh sách trực tiếp đến AnimalHandler, bạn gọi rõ ràng thực tế rằng nó cần một danh sách như vậy. Thay vào đó, nếu bạn làm cho mọi thứ tĩnh và công khai để bạn chỉ có thể truy cập vào danh sách tĩnh được giữ ở nơi khác trong mã, tất cả những gì bạn làm là ẩn sự phụ thuộc mà không thực sự giải quyết hoặc loại bỏ nó.

Đối với một trò chơi nhỏ không cần phải mở rộng quy mô, điều này sẽ không thành vấn đề, nhưng điều đó có thể dẫn bạn đến con đường của một thói quen xấu, vì vậy bạn có thể muốn xem xét việc không làm điều đó. Ít nhất hãy ghi nhớ điều này cho dự án tiếp theo bạn làm.


Amen! Bạn chạm vào một điểm tuyệt vời mà tôi không thực sự nói về câu trả lời của mình.
Nate

+1 phụ thuộc ẩn và giới thiệu trạng thái toàn cầu thực sự là vấn đề ở đây
tro999

4

Lý do gọi cho TileHandler trong ngữ cảnh tĩnh không phải là thiết kế tốt nhất có thể, là vì nó kết hợp các thành phần trong thiết kế của bạn mà có thể tách rời.

Nếu bạn chọn có nhiều hơn một TileHandler trong tương lai, bạn sẽ phải làm rất nhiều việc để thích ứng với sự thay đổi này.

Nếu bạn chọn loại bỏ TileHandler, bạn sẽ phải thực hiện rất nhiều công việc để thích ứng với sự thay đổi này.

Giả sử bạn xây dựng một cấp độ / vùng khác nhau trong tương lai, xử lý các ô theo cách khác với Ngói hiện tại của bạn. Sau đó, bạn cần phải có một cách để xác định phương thức xếp gạch để sử dụng hoặc bạn cần gọi một trình xử lý khác.

Nếu TileHandler được truyền dưới dạng tham số cho các đối tượng sử dụng nó, thì bạn có thể chỉ cần chuyển một cái khác vào lần sau hoặc đặt một trình xử lý ô khác cho các đối tượng sử dụng nó sau này.

Cá nhân, tôi truy cập nhiều thứ trong các trò chơi XNA của mình từ ngữ cảnh tĩnh và cho rằng tôi sẽ không bao giờ có nhiều hơn một trong số chúng.

Nếu bạn muốn có thể sử dụng lại mã công cụ trò chơi của mình trong trò chơi tiếp theo, bạn có thể sẽ phải viết lại nhiều nội dung mà bạn hiện đang viết dưới dạng tĩnh.

Nói ngắn gọn:

Có lợi cho việc không sử dụng bối cảnh tĩnh:

Truyền các đối tượng dưới dạng tham số càng nhiều càng tốt tách các yếu tố trò chơi và cho phép bạn sửa đổi / tái sử dụng chúng cho các dự án hiện tại hoặc tương lai dễ dàng hơn. Nó cũng cho phép bạn quản lý sự phức tạp của số lượng lớn mã dễ dàng hơn một chút (nghĩ rằng có hàng trăm trình quản lý tĩnh trong lớp trò chơi của bạn, trong một trò chơi lớn).

Có lợi cho bối cảnh tĩnh:

Khai báo và truy cập các đối tượng từ ngữ cảnh tĩnh giúp viết các trò chơi nhỏ không cần hàng trăm người quản lý tĩnh dễ dàng hơn. Đơn giản hóa nhiều phương thức và hàm tạo bằng cách không yêu cầu một hoặc nhiều tham số bổ sung thay vào đó được truy cập tĩnh.


2

Tôi không nghĩ rằng đó là một ý tưởng siêu tồi cho một trò chơi đơn giản, nhưng bạn cũng có thể xem tại http://www.nuclex.org/articles/4-arch architecture / 6- trò chơi-components-and-game- service cho một ý tưởng tốt hơn về cách xây dựng các thành phần trò chơi liên thông


Bạn có thể nghĩ ra bất kỳ vấn đề nào nếu đó không chỉ là một trò chơi đơn giản?
Harold

Khả năng đọc mã, khả năng kiểm tra và thực hành kiến ​​trúc tốt sẽ đề xuất để tránh nó.
smnbss

2

Những thứ như TileHandler và AnimalHandler Tôi sẽ đưa một cấp độ cao hơn vào màn hình trò chơi. Màn hình tiêu đề của bạn có cần quyền truy cập vào TileHandler và nó có được khởi chạy khi trò chơi được tải lần đầu không? Chắc là không.

Kiểm tra mẫu Quản lý Nhà nước XNA . Nó có rất nhiều mã trong đó, nhưng về cơ bản, trò chơi cơ bản chỉ khởi tạo một chồng trạng thái trò chơi (hoặc màn hình). Mỗi màn hình khá độc lập với các màn hình khác và chạy như một phiên bản đơn giản hóa của Trò chơi. PlayScreen của bạn có thể có các thành viên tĩnh để họ có thể truy cập vào các thành phần PlayScreen.

Trong Trò chơi cơ bản, tôi sử dụng một vài số liệu thống kê, nhưng chúng là những thứ rất thấp như InputHelper, Log hoặc Trình đọc cấu hình. Chúng là tiêu chuẩn khá trên tất cả các trò chơi để động cơ cơ sở có thể được chuyển nhanh chóng và dễ dàng. Các màn hình là nơi logic trò chơi thực tế xảy ra. Rất dài câu trả lời ngắn gọn - không, tôi không nghĩ rằng đó là một ý tưởng tồi trong lý thuyết, chỉ cần cẩn thận những gì bạn làm cho tĩnh. Một khi bạn tiếp tục và làm cho một cái gì đó tĩnh, đó là một khối lượng công việc khổng lồ nếu bạn thay đổi tâm trí của bạn.


0

Những điểm nêu ra ở đây đều tốt. Theo kinh nghiệm của tôi (được thừa nhận là có trọng số đối với các ứng dụng kinh doanh hơn là các trò chơi), có những ứng dụng tuyệt vời cho các lớp và thành viên tĩnh và tôi đã sử dụng chúng nhiều lần. Tôi đã phát hiện ra rằng khi các yêu cầu và độ phức tạp tăng lên, tôi kết thúc việc tái chế các lớp tĩnh đó và chuyển đổi chúng thành các lớp cá thể và bắt đầu chuyển chúng đi xung quanh.

Điểm tôi muốn đưa ra là, nếu sử dụng một lớp tĩnh giúp bạn thoát khỏi trò chơi này , hãy chơi nó, nhưng vẫn làm đúng: triển khai một giao diện hoặc lớp cơ sở để dễ dàng tách nó ra và chuyển đổi nó đến một lớp thể hiện sau này

Một ounce phòng ngừa đáng giá một pound thuốc chữa bệnh, vì vậy hãy chắc chắn rằng lớp tĩnh của bạn không trói buộc bạn ở phía xa khiến bạn khó thay đổi. Thật dễ dàng để cấu trúc lại một phương thức bằng cách sử dụng một lớp tĩnh thực hiện một giao diện để nó chấp nhận một tham số giao diện mới và sử dụng giao diện đó thay vì tham chiếu lớp tĩnh.


0

Vâng, nói chung luôn luôn là một ý tưởng tồi.

Biến các đối tượng chứa dữ liệu thay đổi (nghĩa là bất cứ thứ gì ngoại trừ các hằng số chỉ đọc và bảng tra cứu) thành các lớp tĩnh là nơi thiết kế tốt sẽ bổ nhào.

  1. Nó thúc đẩy sự phụ thuộc hỗn loạn giết chết tính mô đun và cản trở việc tái sử dụng mã. Giả sử bạn muốn viết một trình soạn thảo cho trò chơi của mình - bạn đột nhiên có rất nhiều lớp khóc vì Game1bạn không thể dễ dàng chuyển đến thư viện dùng chung.

  2. Mã của bạn trở nên không thể kiểm chứng. Kiểm thử đơn vị hoạt động bằng cách cách ly các lớp riêng lẻ với phần còn lại bằng cách chế nhạo hoặc mô phỏng các phụ thuộc của chúng (cần được giữ ở mức tối thiểu nhất có thể). Bất kỳ lớp tĩnh nào cũng là một trách nhiệm pháp lý bởi vì nó có thể được truy cập bất cứ lúc nào, mang trạng thái qua nhiều thử nghiệm hoặc yêu cầu được khởi tạo trước khi các thử nghiệm có thể thành công.

  3. Nó che giấu sự phụ thuộc. Giống như mô hình chống nhà cung cấp dịch vụ (cũng được XNA, Game.Service sử dụng), các lớp của bạn có thể chọn các phụ thuộc mà bạn không nhìn thấy ở bên ngoài.

Cách tiếp cận này trở nên đặc biệt độc hại nếu người ta kết hợp các lớp tĩnh với các cuộc gọi tàu chở hàng (Thingsl ike Game.Instance.ActorManager.Enemies.FindInRange(10)- được gọi là do các biểu tượng bị xiềng xích giống như xe lửa), trong đó các thành phần đột nhiên không chỉ yêu cầu một Gamelớp, mà một lớp có thuộc tính tĩnh Instancetrả lại thứ gì đó với một thuộc ActorManagertính có một thuộc Enemiestính trả về một đối tượng bằng một FindInRange()phương thức.

Lý do duy nhất tôi chấp nhận để viết các lớp tĩnh có thể thay đổi sẽ là lớp vẫn đang học và không có khả năng áp dụng thiết kế tốt và một con mắt được đào tạo để phát hiện ra các lựa chọn xấu.

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.