Tôi không thoải mái về cách tôi đã thiết kế một chương trình đơn giản. Có một đối tượng FileParser
có các sự kiện OnFileOpened
, OnLineParsed
và OnFileClosed
và một số đối tượng tạo tệp nhỏ hơn dựa trên nội dung của tệp mà các phân tích FileParser
.Thành ngữ C# cho đối tượng chỉ tương tác mặc dù đã đăng ký các sự kiện
Các đối tượng quan sát FileParser
đăng ký phương thức của họ với sự kiện FileParser
trong các nhà thầu của họ.
ParsedFileFrobber(FileParser fileParser)
{
fileParser.OnFileOpen += this.OpenNewFrobFile;
fileParser.OnLineParsed += this.WriteFrobbedLine;
fileParser.OnFileClose += this.CloseFrobFile;
}
Sau đó, ParsedFileFrobber
chỉ tiếp tục với những thứ không có tương tác rõ ràng hơn.
Điều làm phiền tôi là chương trình chính chỉ bao giờ gán một ParsedFileFrobber
và về cơ bản không sử dụng giá trị trả về của hàm tạo, do đó, để nói.
var fileParser = new FileParser(myFilename);
var parsedFileFrobber = new ParsedFileFrobber(fileParser);
// No further mentions of parsedFileFrobber.
Nó hoạt động, nhưng ReSharper phàn nàn về điều này, ít nhất khiến tôi tạm dừng suy nghĩ. Trên thực tế, tôi thậm chí không cần phải gán một biến cho kết quả của hàm khởi tạo, vì GC sẽ giữ cho số ParsedFileFrobber
còn sống bằng các tham chiếu của trình xử lý sự kiện, nhưng một số new
trống có vẻ rất sai với tôi. (Nó vẫn biên dịch và chạy đúng.)
var fileParser = new FileParser(myFilename);
new ParsedFileFrobber(fileParser);
Đây có phải là sự cố không? Nó có phải là một mẫu mã chống mùi hay không? Đã có một cách thành ngữ để làm điều này trong C#?
Cảm ơn!
Giải thích nhờ nhận xét hữu ích:
1) Tại sao không đảo ngược mối quan hệ? Cody Grey
Ah, ví dụ hơi quá đơn giản. Tôi thực sự có một số ParsedFileFrobber
, một số ParsedFileGrobber
và ParsedFileBrobber
. Đảo ngược mối quan hệ sẽ làm cho các FileParser
phụ thuộc vào tất cả 3. (Ngoài ra, ban đầu chỉ có một Frobber và một Grobber, nhưng sau đó có một nhu cầu cho một Brobber, và vẫn còn phạm vi cho uh, một Drobber và vv.) Tôi đoán rằng đó là vấn đề về việc liệu các dòng mã thực hiện đăng ký có xảy ra trong công cụ xây dựng FileParser
hoặc trong các nhà thầu ParsedFileFrobber
, ParsedFileGrobber
và ParsedFileBrobber
hay không, nhưng sở thích của tôi là cố gắng giữ cho số FileParser
trở nên độc lập nhất có thể.
2) Tại sao không di chuyển hàm tạo thành một phương thức tĩnh (và làm cho hàm tạo riêng tư)? Hans Passant
Tôi có thể xem cách làm gọn đi việc sử dụng có thể không trực quan vào các hoạt động bên trong riêng tư của lớp học, đó là lời khuyên tốt. Tuy nhiên, nó vẫn sẽ là một trong các số new
hoặc tham chiếu chỉ được gán cho giá trị trả về của hàm tạo. Vâng, nếu nó không phải là một vấn đề lớn, nó có ý nghĩa để ẩn đi các mã xấu xí. (Để tham khảo, tôi đã làm cho ParsedFileFrobber
một số IDisposable
với phương thức Dispose
hủy đăng ký khỏi các sự kiện, vì vậy, có thể chấm dứt hoạt động.)
Cảm ơn tất cả các bình luận!
Tôi không hoàn toàn chắc chắn rằng tôi hiểu thiết kế, nhưng câu hỏi đầu tiên của tôi sẽ là, tại sao không đảo ngược mối quan hệ? Hiện tại, bạn có ParsedFileFrobber phụ thuộc vào FileParser, nhưng sau đó không bao giờ sử dụng thể hiện của ParsedFileFrobber nữa. Tại sao không thay vì FileParser phụ thuộc vào ParsedFileFrobber, vì bạn (rõ ràng) vẫn giữ một tham chiếu đến đối tượng FileParser? –
Không có nhiều điều để băn khoăn, chỉ là một lời nhắc nhở tốt rằng nó sẽ frob mãi mãi miễn là đối tượng FileParser vẫn còn sống. Bạn có thể làm cho nó trông "tự nhiên" bằng cách thêm một phương thức tĩnh vào ParseFileFrobber. Đặt tên nó là erm, Frob() hoặc Observe(). Đặt hàm tạo riêng tư. –
Tôi tự hỏi tại sao bạn sẽ không cần tạo bản sao 'ParsedFileFrobber'. Rõ ràng là lớp (và người thân của nó 'ParsedFile *') đang làm điều gì đó trong các trình xử lý sự kiện tạo ra một trạng thái nhất định. Tiểu bang đó được giữ ở đâu? Từ những gì chúng ta biết, nó phải nằm trong 'ParsedFileFrobber'. Và nếu chúng ta quan tâm đến trạng thái đó (tôi đoán chúng ta đang có, nếu không, tại sao chúng ta sẽ phân tích tệp sau khi tất cả), chúng ta cũng cần phải truy cập cá thể của 'ParsedFileFrobber'. Dường như với tôi, chúng ta chỉ thấy một phần của bức tranh chứ không phải toàn bộ sự việc ở đây. –