Khó khăn khiến lớp học này đóng cửa


8

Đây là vấn đề của tôi: Tôi muốn đọc đầu vào từ các thiết bị HID khác nhau như gamepad, đua tốt, cần điều khiển, v.v ... Khá nhiều bộ điều khiển trò chơi. Vấn đề là tất cả chúng đều có đầu vào khác nhau.

Các gamepad có nút, công tắc và gậy trong khi xe đua có thể có một bánh răng. Tôi đã quản lý để trừu tượng tất cả các thành phần khác nhau này thành chỉ 3 vì vậy thay vì có một lớp cơ sở với tất cả các kết hợp có thể:

abstract class Device
    {
    public Buttons Buttons;
    public Axes Axes;
    public Switches Switches;
    public GearSticks GearSticks;
    //many more
    }

Bây giờ tôi có thể có:

abstract class Device
{
public Buttons Buttons;   //on or off
public Axes Axes;         //range [-100%:100%]
public Switches Switches; //multiple states
}

Lúc đầu, tôi rất hài lòng với điều này vì nó dường như bao gồm tất cả các loại đầu vào có thể và vì vậy lớp của tôi có thể bị đóng trong khi mở để mở rộng thông qua tất cả các triển khai cụ thể vì mọi thứ có thể được trừu tượng hóa chỉ với 3 loại đầu vào.

NHƯNG sau đó tôi tự nghĩ rằng nếu tôi chỉ trì hoãn điều không thể tránh khỏi thì sao? Điều gì sẽ xảy ra nếu một ngày tôi sẽ phải thêm một lĩnh vực khác vào Devicelớp học của mình ? Nó không hỗ trợ một cái gì đó như trackball!

Có cách nào để tôi có thể chứng minh lớp học này trong tương lai không? Theo cách tôi nhìn thấy, tôi sẽ kết thúc với một thứ như thế này:

public Device1 : Device
{
//buttons
//trackball
}

public Device2 : Device
{
//Switch
//Axis
}

public Device3 : Device
{
//trackball
//switch
}

Và tôi sẽ phải tiếp tục thêm các thuộc tính vào lớp cơ sở của mình mỗi khi có một cái gì đó mới để thực hiện.


Cách duy nhất để chứng minh hoàn toàn một lớp như vậy trong tương lai là lưu trữ các cặp khóa-giá trị dưới dạng chuỗi và truyền các giá trị xung quanh các lớp của bạn bằng một số loại giao thức không chữ như Bộ đệm giao thức. Nhưng HID cụ thể hơn thế. Bạn đang ở trên nền tảng nào? Có một số thư viện trợ giúp có thể dễ dàng quá trình này; đây là một cái cho .NET Framework: github.com/mikeobrien/HidL Library . Hoặc cái này: github.com/jcoenraadts/hid-sharp
Robert Harvey

Đây là một câu hỏi kỹ thuật phần mềm tuyệt vời và tôi không biết tại sao bạn lại có một downvote cho nó.
Doc Brown

@RobertHarvey Khi bạn nói các cặp khóa-giá trị, một cái gì đó bắt đầu có ý nghĩa trong tâm trí tôi nhưng ý nghĩa của giao thức không chữ là gì? Tôi đang ở trên nền tảng UWP.
Mihai Bratulescu

Giao thức không chữ là giao thức hoạt động hoàn toàn trên các cặp chuỗi, giống như giao thức mà URL sử dụng : parameter1=value1&parameter2=value2, v.v.
Robert Harvey

Câu trả lời:


7

Tôi khá chắc chắn rằng điều này có thể được thực hiện bằng cách giới thiệu một khái niệm như một bản tóm tắt InputChannelvà các thiết bị có một danh sách các kênh đầu vào có thể định cấu hình. Một kênh đầu vào sẽ có một tên, một loại, có thể là một số dữ liệu meta và nó cần có khả năng tạo ra một số "trạng thái" phù hợp với loại đó. Có thể có các kênh được xác định trước như nút, rìu hoặc công tắc hoặc một số kênh mới mà bạn hiện không biết (nhưng có thể được thêm vào sau bằng cách giới thiệu một InputChannellớp con mới ).

Theo cách này, một thiết bị sẽ trở thành một loại mô hình meta và bạn cũng sẽ cần một cách để quản lý trạng thái của thiết bị, tương ứng với danh sách các kênh đầu vào của thiết bị.

Tuy nhiên, cách tiếp cận chung chung đó có nguy cơ áp đảo nhất định, còn được gọi là hiệu ứng Nền tảng bên trong . Ví dụ, có thể không dễ dàng để thêm chức năng cụ thể vào một thiết bị chung như vậy, hoặc các sự kiện cụ thể hoặc tương tác giữa các kênh đầu vào khác nhau. Nó cũng có thể khó sử dụng và hiểu hơn đối với người dùng thư viện thiết bị chung của bạn.

Lưu ý rằng không phải lúc nào cũng có lợi để tạo ra giải pháp trừu tượng nhất có thể. Việc thay đổi các yêu cầu trong phần cứng thường cần nhiều nỗ lực hơn để thực hiện trong chính phần cứng so với phần mềm tương ứng, vì vậy, tốt hơn là nên sử dụng một giải pháp cụ thể hơn trong phần mềm và thay đổi phần mềm khi cần thiết.


An InputChannelcó thể hoạt động, tất cả những gì tôi cần làm là cập nhật trạng thái và nâng cao onChangedEvent. Nhưng bạn có thể đúng về kỹ thuật hơn ... Tôi sẽ ghi nhớ điều này. Bạn có nghĩ rằng việc thêm một lĩnh vực khác vào một lớp mỗi giờ và sau đó là chấp nhận được không?
Mihai Bratulescu

1
@MihaiBratulescu: tùy thuộc vào loại phần mềm bạn viết - một số khung trò chơi cho chính bạn hoặc nhóm của bạn, nơi bạn biết các trường hợp sử dụng và có thể phản ứng phù hợp khi yêu cầu thay đổi, hoặc một số khung chung như Qt hoặc khung .Net sẽ là được sử dụng bởi hàng trăm ngàn nhà phát triển trong các tình huống không lường trước được. Đối với cái sau, một giải pháp rất chung chung và RẮN quan trọng hơn nhiều so với giải pháp trước.
Doc Brown

biển chỉ dẫn lên phía trước - điểm dừng tiếp theo của bạn, Twilight Zone : "Hỗ trợ bị giới hạn RẤT cho thư viện này. Hầu như không thể khắc phục sự cố với rất nhiều thiết bị và cấu hình." Đây là từ tài liệu tham khảo hidL Library @RobertHarvey . Lớn tiếng gợi ý những gì người ta đang nắm giữ một lý thuyết trường thống nhất Tar Baby
radarbob

3

Ý tưởng đằng sau nguyên tắc đóng mở là bạn ít có khả năng phá vỡ chức năng hiện có nếu bạn triển khai chức năng mới thông qua kế thừa thay vì sửa đổi một lớp hiện có. Và bạn có thể làm như vậy, bằng cách kế thừa từ Hid của bạn. Trong một năm và một vài tháng, bạn có thể tạo ra Hid2020 kế thừa từ Hid và thêm hỗ trợ cho trackball sẽ được phát minh vào quý 4 năm 2019. Sau khi phát minh và phổ biến máy dò bóp vào năm 2023, bạn có thể tạo một lớp Hid2024. xuống từ Hid2019.

Đó sẽ là phương pháp phòng thủ. Nhưng nó cũng sẽ là một chút cẩu thả từ quan điểm thiết kế sạch sẽ. Trong trường hợp của bạn, tôi sẽ không mất bất kỳ giấc ngủ nào khi vi phạm O và chỉ thay đổi lớp cơ sở khi thế giới xung quanh bạn thay đổi. Có vẻ như việc triển khai trackball hoặc bất kỳ loại điều khiển mới nào khác sẽ ảnh hưởng đến cách bạn xử lý các lần nhấn nút hoặc chuyển đổi trạng thái ngay bây giờ.


Ditto trên đoạn 2. Thiết kế mạch lạc là điều. Và nói về sự mạch lạc; O / C đã phục vụ mục đích của nó ở đây, chỉ cần xem xét O / C khiến người ta nhận ra rằng lớp sẽ được mở (sửa đổi) quá thường xuyên có thể do thiết kế không phù hợp. IMO đây là nguyên tắc của Nguyên tắc Mở / Đóng.
radarbob
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.