Ý tưởng nào đằng sau việc đặt tên các lớp với hậu tố của Info Info, ví dụ:


20

Tôi đang làm việc trong một dự án liên quan đến các thiết bị vật lý và tôi đã nhầm lẫn về cách đặt tên đúng cho một số lớp trong dự án này.

Xem xét các thiết bị thực tế (cảm biến và máy thu) là một chuyện, và sự thể hiện của chúng trong phần mềm là một điều khác, tôi đang suy nghĩ về việc đặt tên cho một số lớp với mẫu tên hậu tố "Thông tin".

Ví dụ, trong khi một Sensorlớp sẽ là đại diện cho cảm biến thực tế (khi nó thực sự được kết nối với một số thiết bị làm việc), SensorInfosẽ chỉ được sử dụng để đại diện cho các đặc điểm của cảm biến đó. Ví dụ, khi lưu tệp, tôi sẽ tuần tự hóa một SensorInfotiêu đề tệp, thay vì tuần tự hóa một Sensor, điều này thậm chí sẽ không có ý nghĩa.

Nhưng bây giờ tôi bối rối, bởi vì có một khoảng giữa trong vòng đời của các đối tượng mà tôi không thể quyết định liệu tôi nên sử dụng cái này hay cái khác, hoặc làm thế nào để lấy cái này từ cái khác, hoặc thậm chí cả hai biến thể có thực sự được thu gọn thành một lớp hay không.

Ngoài ra, tất cả các Employeelớp ví dụ quá phổ biến rõ ràng chỉ là một đại diện của người thật, nhưng không ai có thể đề nghị đặt tên cho lớp EmployeeInfothay vào đó, theo như tôi biết.

Ngôn ngữ tôi đang làm việc là .NET và mẫu đặt tên này dường như phổ biến trong toàn khung, ví dụ như với các lớp này:

  • DirectoryDirectoryInfocác lớp học;
  • FileFileInfocác lớp học;
  • ConnectionInfolớp (không có Connectionlớp phóng viên );
  • DeviceInfolớp (không có Devicelớp phóng viên );

Vì vậy, câu hỏi của tôi là: có một lý do phổ biến về việc sử dụng mẫu đặt tên này? Có trường hợp nào có ý nghĩa khi có các cặp tên ( ThingThingInfo) và các trường hợp khác chỉ tồn tại ThingInfolớp hoặc Thinglớp mà không có đối tác của nó không?


5
Ben Aaronson đã hiểu đúng trong câu trả lời của mình dưới đây; các Infohậu tố phân biệt một staticlớp chứa phương pháp hữu ích từ đối tác stateful của nó. Đó không phải là một "thực hành tốt nhất" như vậy; đó chỉ là một cách mà nhóm .NET nghĩ ra để giải quyết một vấn đề cụ thể. Họ có thể có giống như dễ dàng đưa ra FileUtilityFile, nhưng File.DoSomething()FileInfo.FileNamedường như đọc tốt hơn.
Robert Harvey

1
Điều đáng chú ý là đây là một mẫu chung, nhưng có nhiều quy ước đặt tên khác nhau như có ngôn ngữ và API. Ví dụ, trong Java, nếu bạn có một lớp trạng thái Foo, bạn có thể có một lớp tiện ích không thể thực hiện được Foos. Khi nói đến việc đặt tên, điều quan trọng là tính nhất quán trong API và lý tưởng là các API trên nền tảng.
Kevin Krumwiede

1
Có thật không? "Không ai có thể đề nghị đặt tên lớp EmployeeInfo" ?? KHÔNG AI? Điều đó có vẻ hơi mạnh mẽ cho một cái gì đó không quá rõ ràng.
ThePopMachine 14/05/2015

@ThePopMachine Tôi đồng ý từ "không ai" có thể quá khó trong trường hợp này, nhưng các Employeeví dụ được tìm thấy bởi hàng tá, trực tuyến hoặc trong các cuốn sách cổ điển, trong khi tôi chưa thấy EmployeeInfo(có lẽ vì một nhân viên là một sinh vật sống, không phải một cấu trúc kỹ thuật như một kết nối hoặc một tập tin). Nhưng, đã đồng ý, nếu lớp học EmployeeInfođược đề xuất trong một dự án, tôi tin rằng nó có thể có công dụng của nó.
heltonbiker

Câu trả lời:


21

Tôi nghĩ rằng "thông tin" là một cách gọi sai. Các đối tượng có trạng thái và hành động: "thông tin" chỉ là một tên gọi khác của "trạng thái" đã được đưa vào OOP.

Bạn thực sự đang cố gắng làm gì ở đây? Bạn cần một đối tượng đại diện cho phần cứng trong phần mềm để các mã khác có thể sử dụng nó.

Điều đó là dễ dàng để nói nhưng như bạn phát hiện ra, có nhiều điều hơn thế. "Đại diện cho phần cứng" là rộng đáng ngạc nhiên. Một đối tượng có một số mối quan tâm:

  • Giao tiếp thiết bị cấp thấp, cho dù đó là nói chuyện với giao diện USB, cổng nối tiếp, TCP / IP hoặc kết nối độc quyền.
  • Quản lý nhà nước. Thiết bị đã được bật chưa? Sẵn sàng nói chuyện với phần mềm? Bận?
  • Xử lý các sự kiện. Thiết bị tạo dữ liệu: bây giờ chúng ta cần tạo các sự kiện để chuyển đến các lớp khác quan tâm.

Một số thiết bị như cảm biến sẽ có ít mối quan tâm hơn so với thiết bị đa chức năng của máy in / máy quét / fax. Một cảm biến có khả năng chỉ tạo ra một luồng bit, trong khi một thiết bị phức tạp có thể có các giao thức và tương tác phức tạp.

Dù sao, trở lại câu hỏi cụ thể của bạn, có một số cách để làm điều này tùy thuộc vào yêu cầu cụ thể của bạn cũng như sự phức tạp của tương tác phần cứng.

Dưới đây là một ví dụ về cách tôi sẽ thiết kế hệ thống phân cấp lớp cho cảm biến nhiệt độ:

  • ITem Nhiệt độ Nguồn: giao diện đại diện cho bất kỳ thứ gì có thể tạo ra dữ liệu nhiệt độ: cảm biến, thậm chí có thể là trình bao bọc tệp hoặc dữ liệu được mã hóa cứng (nghĩ: thử nghiệm giả).

  • Acme4680Sensor: Cảm biến ACME model 4680 (tuyệt vời để phát hiện khi có Roadrunner ở gần). Điều này có thể thực hiện nhiều giao diện: có lẽ cảm biến này phát hiện cả nhiệt độ và độ ẩm. Đối tượng này chứa trạng thái cấp chương trình, chẳng hạn như "cảm biến có được kết nối không?" và "lần đọc cuối cùng là gì?"

  • Acme4680SensorComm: chỉ được sử dụng để liên lạc với thiết bị vật lý. Nó không duy trì trạng thái nhiều. Nó được sử dụng để gửi và nhận tin nhắn. Nó có một phương thức C # cho mỗi thông điệp mà phần cứng hiểu.

  • Phần cứng quản lý: được sử dụng để nhận thiết bị. Đây thực chất là một nhà máy lưu trữ các trường hợp: chỉ nên có một phiên bản của một đối tượng thiết bị cho mỗi thiết bị phần cứng. Phải đủ thông minh để biết rằng nếu luồng A yêu cầu cảm biến nhiệt độ ACME và luồng B yêu cầu cảm biến độ ẩm ACME, thì đây thực sự là cùng một đối tượng và phải được trả lại cho cả hai luồng.


Ở cấp độ cao nhất, bạn sẽ có giao diện cho từng loại phần cứng. Chúng mô tả các hành động mà mã C # của bạn sẽ thực hiện trên các thiết bị, sử dụng các kiểu dữ liệu C # (không phải là các mảng byte mà trình điều khiển thiết bị thô có thể sử dụng).

Ở cùng cấp độ, bạn có một lớp liệt kê với một thể hiện cho mỗi loại phần cứng. Cảm biến nhiệt độ có thể là một loại, cảm biến độ ẩm khác.

Một cấp dưới đây là các lớp thực tế thực hiện các giao diện đó: chúng đại diện cho một thiết bị tương tự Acme4680Sensor mà tôi đã mô tả ở trên. Bất kỳ lớp cụ thể nào cũng có thể thực hiện nhiều giao diện nếu thiết bị có thể thực hiện nhiều chức năng.

Mỗi lớp thiết bị có lớp Comm (giao tiếp) riêng xử lý tác vụ cấp thấp để nói chuyện với phần cứng.

Bên ngoài mô-đun phần cứng, lớp duy nhất có thể nhìn thấy là các giao diện / enum cộng với Phần cứng quản lý. Lớp Phần cứng Trình quản lý là bản tóm tắt của nhà máy xử lý việc khởi tạo các lớp thiết bị, các trường hợp bộ đệm (bạn thực sự không muốn hai lớp thiết bị nói chuyện với cùng một thiết bị phần cứng), v.v. Một lớp cần một loại cảm biến cụ thể yêu cầu Trình quản lý phần cứng lấy thiết bị cho enum cụ thể, sau đó nó sẽ tìm ra nếu nó đã được khởi tạo, nếu không làm thế nào để tạo và khởi tạo nó, v.v.

Mục tiêu ở đây là tách rời logic kinh doanh khỏi logic phần cứng cấp thấp. Khi bạn đang viết mã in dữ liệu cảm biến ra màn hình, mã đó sẽ không quan tâm bạn có loại cảm biến nào nếu và chỉ khi việc tách rời này được đặt ở vị trí trung tâm trên các giao diện phần cứng đó.


Ví dụ sơ đồ lớp UML hiển thị thiết kế được mô tả trong câu trả lời này

Lưu ý: có mối liên hệ giữa Phần cứng quản lý và từng lớp thiết bị mà tôi không vẽ vì sơ đồ sẽ biến thành súp mũi tên.


Câu trả lời rất thú vị. Tôi sẽ yêu cầu chỉnh sửa nhanh: để lại rõ ràng hơn sự kế thừa / ngăn chặn / cộng tác giữa bốn lớp bạn đã đề cập là gì. Cảm ơn nhiều!
heltonbiker

Tôi đã thêm một sơ đồ lớp UML. Không giúp đỡ à?

2
Tôi muốn nói rằng đây là một câu trả lời giết người , và nó không chỉ giúp tôi rất nhiều, mà tôi tin rằng có thể giúp nhiều người hơn trong tương lai. Ngoài ra, ví dụ phân cấp lớp bạn cung cấp bản đồ các vấn đề và miền giải pháp của chúng tôi rất tốt. Cảm ơn bạn rất nhiều một lần nữa!
heltonbiker

Khi tôi đọc câu hỏi tôi nhận ra có nhiều điều đang diễn ra, vì vậy tôi đã hơi quá mức và chia sẻ toàn bộ thiết kế. Đây không chỉ là một vấn đề đặt tên đơn giản vì các tên là biểu thị của thiết kế. Tôi đã làm việc với các hệ thống được xây dựng theo cách này và chúng hoạt động khá tốt.

11

Có thể hơi khó để tìm một quy ước thống nhất duy nhất ở đây vì các lớp này được trải rộng trên một số không gian tên, ( ConnectionInfodường như là trong CrystalDecisionsDeviceInfotrong System.Reporting.WebForms).

Tuy nhiên, nhìn vào các ví dụ này, dường như có hai cách sử dụng khác nhau của hậu tố:

  • Phân biệt một lớp cung cấp các phương thức tĩnh với một lớp cung cấp các phương thức cá thể. Đây là trường hợp cho các System.IOlớp, như được gạch chân bởi các mô tả của họ:

    Thư mục :

    Đưa ra các phương thức tĩnh để tạo, di chuyển và liệt kê thông qua các thư mục và thư mục con. Lớp này không thể được thừa kế.

    DirectoryInfo :

    Đưa ra các phương thức thể hiện để tạo, di chuyển và liệt kê thông qua các thư mục và thư mục con. Lớp này không thể được thừa kế.

    InfoCó vẻ như là một lựa chọn hơi kỳ lạ ở đây, nhưng nó tạo ra sự khác biệt tương đối rõ ràng: một Directorylớp có thể đại diện hợp lý cho một thư mục cụ thể hoặc cung cấp các phương thức trợ giúp liên quan đến thư mục chung mà không giữ bất kỳ trạng thái nào, trong khi DirectoryInfochỉ có thể thực sự là trước đây.

  • Nhấn mạnh rằng lớp chỉ lưu giữ thông tin và không cung cấp hành vi có thể được mong đợi một cách hợp lý từ tên không có hậu tố .

    Tôi nghĩ rằng phần cuối của câu đó có thể là mảnh ghép để phân biệt, nói, ConnectionInfotừ EmployeeInfo. Nếu tôi có một lớp được gọi Connection, tôi sẽ mong đợi nó thực sự cung cấp cho tôi chức năng mà một kết nối có - Tôi đang tìm kiếm các phương thức như void Open(), v.v. Tuy nhiên, không ai có thể nghĩ rằng một Employeelớp có thể thực sự làm những gì thực sự Employeelàm, hoặc tìm kiếm các phương pháp như void DoPaperwork()hoặc bool TryDiscreetlyBrowseFacebook().


1
Cảm ơn bạn rất nhiều vì câu trả lời của bạn! Tôi tin rằng viên đạn đầu tiên trong câu trả lời của bạn chắc chắn mô tả những gì diễn ra trong các lớp .NET, nhưng viên đạn thứ hai có nhiều giá trị hơn (và nhân tiện thì khác), bởi vì nó cho thấy sự trừu tượng hóa tốt hơn: một thứ được sử dụng so với điều cần được mô tả Thật khó để chọn câu trả lời nào để chấp nhận.
heltonbiker

4

Nói chung, một Infođối tượng đóng gói thông tin về trạng thái của một đối tượng tại một thời điểm nào đó . Nếu tôi yêu cầu hệ thống xem xét một tệp và đưa cho tôi một FileInfođối tượng được liên kết với kích thước của nó, tôi sẽ mong muốn đối tượng đó báo cáo kích thước của tệp tại thời điểm yêu cầu được đưa ra (hoặc chính xác hơn là kích thước của tập tin tại một thời điểm giữa khi cuộc gọi được thực hiện và khi nó được trả lại). Nếu kích thước của tệp thay đổi giữa thời gian yêu cầu trả về và thời gian FileInfođối tượng được kiểm tra, tôi sẽ không mong đợi sự thay đổi như vậy được phản ánh trong FileInfođối tượng.

Lưu ý rằng hành vi này sẽ rất khác với hành vi của một Fileđối tượng. Nếu aa yêu cầu mở tệp đĩa ở chế độ không độc quyền mang lại một Fileđối tượng có thuộc Sizetính, tôi sẽ mong giá trị được trả về do đó thay đổi khi kích thước của tệp đĩa thay đổi, vì Fileđối tượng không chỉ đại diện cho trạng thái của một tập tin - nó đại diện cho tập tin chính nó .

Trong nhiều trường hợp, các đối tượng gắn vào tài nguyên phải được dọn sạch khi dịch vụ của chúng không còn cần thiết nữa. Bởi vì *Infocác đối tượng không gắn vào tài nguyên, chúng không yêu cầu dọn dẹp. Kết quả là, trong trường hợp một Infođối tượng sẽ đáp ứng các yêu cầu của khách hàng, có thể sử dụng mã tốt hơn là sử dụng một đối tượng đại diện cho tài nguyên bên dưới, nhưng kết nối với tài nguyên đó sẽ phải được làm sạch.


1
Đây không phải là chính xác sai, nhưng nó không xuất hiện để giải thích mô hình đặt tên NET của rất tốt ở tất cả, kể từ khi Filelớp học không thể được khởi tạo và FileInfođối tượng làm cập nhật với hệ thống tập tin cơ bản.
Nathan Tuggy

@NathanTuggy Tôi đồng ý rằng điều này không liên quan tốt đến quy ước đặt tên này trong .NET, nhưng liên quan đến vấn đề hiện tại của tôi, tôi tin rằng nó rất phù hợp và có thể tạo ra một giải pháp nhất quán. Tôi đã đưa ra câu trả lời này, nhưng thật khó để chỉ chọn một người chấp nhận ...
heltonbiker

@NathanTuggy: Tôi không khuyên bạn nên sử dụng .NET như một mô hình của bất kỳ loại thống nhất nào. Đó là một Khung tốt và hữu ích, gói gọn rất nhiều ý tưởng hay, nhưng cũng có một vài ý tưởng tồi được nắm bắt trong hỗn hợp.
supercat

@supercat: Chắc chắn rồi; Có vẻ như thật kỳ lạ khi trả lời một câu hỏi về "tại sao .NET lại làm việc này?" với "sẽ là một ý tưởng tốt để làm mọi thứ% THIS_WAY%".
Nathan Tuggy

@NathanTuggy: Tôi không nhớ các chi tiết chính xác của các lớp trong câu hỏi, nhưng tôi nghĩ FileInfochỉ cần giữ thông tin nắm bắt tĩnh. Có phải không? Ngoài ra, tôi chưa bao giờ có cơ hội mở tệp ở chế độ không độc quyền, nhưng điều đó là có thể và tôi hy vọng sẽ tồn tại một phương thức báo cáo kích thước hiện tại của tệp, ngay cả khi đối tượng được sử dụng để mở không gọi File(thường tôi chỉ sử dụng ReadAllBytes, WriteAllBytes, ReadAllText, WriteAllText, vv).
supercat

2

Xem xét các thiết bị thực tế (cảm biến và máy thu) là một chuyện, và sự thể hiện của chúng trong phần mềm là một điều khác, tôi đang suy nghĩ về việc đặt tên cho một số lớp với mẫu tên hậu tố "Thông tin".

Ví dụ, trong khi một Sensorlớp sẽ là đại diện cho cảm biến thực tế (khi nó thực sự được kết nối với một số thiết bị làm việc), SensorInfosẽ chỉ được sử dụng để đại diện cho các đặc điểm của cảm biến đó. Ví dụ, khi lưu tệp, tôi sẽ tuần tự hóa một SensorInfotiêu đề tệp, thay vì tuần tự hóa một Sensor, điều này thậm chí sẽ không có ý nghĩa.

Tôi không thích sự khác biệt này. Tất cả các đối tượng là "đại diện [s] trong phần mềm." Đó là từ "đối tượng" nghĩa là gì.

Bây giờ, có thể có ý nghĩa để tách thông tin về một thiết bị ngoại vi khỏi mã thực tế có giao diện với thiết bị ngoại vi. Vì vậy, ví dụ, Bộ cảm biến có - Bộ cảm biến, chứa hầu hết các biến đối tượng, cùng với một số phương thức không yêu cầu phần cứng, trong khi lớp Cảm biến chịu trách nhiệm tương tác thực sự với cảm biến vật lý. Bạn không có - Sensortrừ khi máy tính của bạn có cảm biến, nhưng bạn có thể có - a SensorInfo.

Vấn đề là loại thiết kế này có thể được khái quát hóa cho (gần như) bất kỳ lớp nào. Vì vậy bạn phải cẩn thận. Bạn rõ ràng sẽ không có một SensorInfoInfolớp học, ví dụ. Và nếu bạn có một Sensorbiến, bạn có thể thấy mình vi phạm luật của Demeter bằng cách tương tác với SensorInfothành viên của nó . Tất nhiên, điều này không gây tử vong, nhưng thiết kế API không chỉ dành cho các tác giả thư viện. Nếu bạn giữ API của riêng mình sạch sẽ và đơn giản, mã của bạn sẽ dễ bảo trì hơn.

Theo tôi, tài nguyên hệ thống tập tin như thư mục, rất gần với cạnh này. Có một số tình huống mà bạn muốn mô tả một thư mục không thể truy cập cục bộ, đúng, nhưng nhà phát triển trung bình có lẽ không phải là một trong những tình huống đó. Làm phức tạp cấu trúc giai cấp trong thời trang này, theo tôi, là không có ích. Tương phản cách tiếp cận của Python trong pathlib: Có một lớp duy nhất "rất có thể là thứ bạn cần" và các lớp phụ trợ khác nhau mà hầu hết các nhà phát triển có thể bỏ qua một cách an toàn. Tuy nhiên, nếu bạn thực sự cần chúng, chúng cung cấp phần lớn giao diện giống nhau, chỉ với các phương thức cụ thể được loại bỏ.


Cảm ơn câu trả lời của bạn và danh tiếng cho cấu trúc "có-a" của bạn;) Câu trả lời của bạn nhắc nhở tôi về sự khó chịu gây ra bởi một số khái niệm "DTO" (Đối tượng truyền dữ liệu) - hoặc anh chị em của Đối tượng tham số - được tán thành bởi những người quá khích OO chính thống hơn bởi vì nó thường không chứa các phương thức (sau tất cả, nó là một đối tượng truyền dữ liệu ). Theo nghĩa đó và cũng tóm tắt những gì người khác đã nói, tôi nghĩ rằng SensorInfođó sẽ là một loại DTO, và / hoặc cũng giống như "ảnh chụp nhanh", hoặc thậm chí là "thông số kỹ thuật", chỉ đại diện cho phần dữ liệu / trạng thái của Sensorđối tượng thực tế rằng "có thể không có ở đó".
heltonbiker

Như với hầu hết các vấn đề thiết kế, không có quy tắc cứng và nhanh. Trong ví dụ pathlib mà tôi đã cung cấp, PureWindowsPathhoạt động hơi giống một đối tượng Thông tin, nhưng nó có các phương thức để thực hiện những việc không yêu cầu hệ thống Windows (ví dụ: lấy thư mục con, tách phần mở rộng tệp, v.v.). Điều này hữu ích hơn là chỉ cung cấp một cấu trúc được tôn vinh.
Kevin

1
Một lần nữa, danh tiếng cho phần "cấu trúc được tôn vinh" :). Điều đó làm tôi nhớ đến một câu trích dẫn liên quan từ cuốn sách "Clean Code" của chú Bob, Chương 6: "Các lập trình viên trưởng thành biết rằng mọi thứ đều là một đối tượng là một huyền thoại. Đôi khi, bạn thực sự muốn các cấu trúc dữ liệu đơn giản với các thủ tục hoạt động trên chúng."
heltonbiker

2

Tôi muốn nói rằng bối cảnh / miền quan trọng, vì chúng ta có mã logic nghiệp vụ cấp cao và các mô hình cấp thấp, các thành phần kiến ​​trúc, v.v.

'Thông tin', 'Dữ liệu', 'Người quản lý', 'Đối tượng', 'Lớp', 'Mô hình', 'Trình điều khiển', v.v. có thể là các hậu tố có mùi, đặc biệt ở cấp độ thấp hơn, vì mọi đối tượng đều có một số thông tin hoặc dữ liệu, vì vậy thông tin đó là không cần thiết.

Tên lớp của miền doanh nghiệp phải giống như tất cả các bên liên quan nói về nó, bất kể nó có vẻ lạ hay ngôn ngữ không chính xác 100%.

Các hậu tố tốt cho cấu trúc dữ liệu, ví dụ: 'Danh sách', 'Bản đồ' và cho các mẫu gợi ý 'Trình trang trí', 'Bộ điều hợp' nếu bạn nghĩ cần thiết.

Theo kịch bản cảm biến của bạn, tôi sẽ không SensorInfolưu lại cảm biến của bạn là gì, nhưng SensorSpec. InfoImho là một thông tin có nguồn gốc, giống FileInfonhư kích thước, bạn không lưu hoặc filepath được xây dựng từ đường dẫn và tên tệp, v.v.

Điểm khác:

Chỉ có hai điều khó trong Khoa học máy tính: vô hiệu hóa bộ đệm và đặt tên.

- Phil Karlton

Điều đó luôn nhắc nhở tôi về việc nghĩ về một cái tên chỉ trong vài giây và nếu tôi không tìm thấy cái nào, tôi sử dụng những cái tên lạ và 'TODO' - đánh dấu chúng. Tôi luôn có thể thay đổi nó sau này vì IDE của tôi cung cấp hỗ trợ tái cấu trúc. Đó không phải là một khẩu hiệu của công ty phải tốt, nhưng chỉ cần một số mã chúng ta có thể thay đổi mỗi khi chúng ta muốn. Ghi nhớ nó trong tâm trí.


1

ThingInfo có thể phục vụ như một Proxy chỉ đọc tuyệt vời cho Điều.

xem http://www.dofactory.com/net/proxy-design-potype

Proxy: "Cung cấp người thay thế hoặc giữ chỗ cho một đối tượng khác để kiểm soát quyền truy cập vào nó."

Thông thường, ThingInfo sẽ có các thuộc tính công khai không có setters. Các lớp này và các phương thức trên lớp là an toàn để sử dụng và sẽ không cam kết bất kỳ thay đổi nào đối với dữ liệu sao lưu, đối tượng hoặc bất kỳ đối tượng nào khác. Không có thay đổi trạng thái hoặc tác dụng phụ khác sẽ xảy ra. Chúng có thể được sử dụng để báo cáo và dịch vụ web hoặc bất cứ nơi nào bạn cần thông tin về đối tượng nhưng muốn giới hạn quyền truy cập vào chính đối tượng thực tế.

Sử dụng ThingInfo bất cứ khi nào có thể và giới hạn việc sử dụng Thing thực tế đến những lúc bạn thực sự cần thay đổi đối tượng Thing. Nó làm cho việc đọc và gỡ lỗi nhanh hơn đáng kể khi bạn quen với việc sử dụng mẫu này.


Xuất sắc. Đầu ngày hôm nay tôi đã phân tích nhu cầu kiến ​​trúc của mình, liên quan đến các lớp tôi đã sử dụng trong câu hỏi, và đi đến kết luận rất giống nhau. Trong trường hợp của tôi, tôi có một Receiverluồng nhận dữ liệu từ nhiều Sensors. Ý tưởng là: người nhận nên trừu tượng hóa các cảm biến thực tế. Nhưng vấn đề là: Tôi cần thông tin cảm biến để tôi có thể ghi chúng vào một số tiêu đề tệp. Các giải pháp: mỗi IReceiversẽ có một danh sách SensorInfo. Nếu tôi gửi lệnh đến người nhận ngụ ý thay đổi trạng thái cảm biến, những thay đổi này sẽ được phản ánh (thông qua getter) tương ứng SensorInfo.
heltonbiker

(tiếp tục ...) đó là: Tôi không nói chuyện với các cảm biến, tôi chỉ nói chuyện với Người nhận thông qua các lệnh cấp cao hơn và Người nhận lần lượt nói chuyện với từng Cảm biến. Nhưng cuối cùng tôi cũng cần thông tin từ các cảm biến mà tôi nhận được từ thể hiện Người nhận thông qua List<SensorInfo>thuộc tính chỉ đọc của nó .
heltonbiker

1

Cho đến nay, không ai trong câu hỏi này dường như đã chọn ra lý do thực sự cho quy ước đặt tên này.

A DirectoryInfokhông phải thư mục. Nó là một DTO với dữ liệu về thư mục. Có thể có nhiều trường hợp như vậy mô tả cùng một thư mục. Nó không phải là một thực thể. Nó là một đối tượng giá trị vứt đi. A DirectoryInfokhông đại diện cho thư mục thực tế. Bạn cũng có thể nghĩ về nó như một tay cầm hoặc bộ điều khiển cho một thư mục.

Tương phản với một lớp có tên Employee. Đây có thể là một đối tượng thực thể ORM và nó là đối tượng duy nhất mô tả nhân viên đó. Nếu nó là một đối tượng giá trị mà không có danh tính thì nó phải được gọi EmployeeInfo. An Employeethực sự đại diện cho nhân viên thực tế. Một lớp DTO giống như giá trị được gọi EmployeeInforõ ràng sẽ không đại diện cho nhân viên mà chỉ mô tả nó hoặc lưu trữ dữ liệu về nó.

Thực sự có một ví dụ trong BCL nơi cả hai lớp tồn tại: A ServiceControllerlà một lớp mô tả một Dịch vụ Windows. Có thể có bất kỳ số lượng bộ điều khiển như vậy cho mỗi dịch vụ. Một ServiceBase(hoặc một lớp dẫn xuất) dịch vụ thực tế và về mặt khái niệm không có nhiều trường hợp của nó cho mỗi dịch vụ riêng biệt.


Điều này nghe có vẻ giống với Proxymẫu được đề cập bởi @Shmoken, phải không?
heltonbiker

@heltonbiker không nhất thiết phải là proxy. Nó có thể là một đối tượng không được kết nối theo bất kỳ cách nào với điều mà nó mô tả. Ví dụ, bạn có thể nhận được EmployeeInfotừ một dịch vụ web. Đó không phải là một proxy. Ví dụ khác: Một AddressInfothậm chí không một thứ mà nó có thể ủy quyền vì một địa chỉ không phải là một thực thể. Đó là một giá trị độc lập.
usr

1
Tôi thấy, điều đó có ý nghĩa!
heltonbiker
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.