2010-03-16 47 views
5

Tôi muốn nhận được ý kiến ​​của bạn về cách đi xa với những người định cư không có tác dụng phụ.Phương pháp tiếp cận các bộ định vị không có tác dụng phụ

Hãy xem xét ví dụ sau:

Activity activity; 
activity.Start = "2010-01-01"; 
activity.Duration = "10 days"; // sets Finish property to "2010-01-10" 

Lưu ý rằng giá trị cho ngày và thời gian được hiển thị chỉ dành cho mục đích dự kiến.

Vì vậy, việc sử dụng trình thiết lập cho bất kỳ thuộc tính nào Start, FinishDuration do đó sẽ thay đổi các thuộc tính khác và do đó không thể được coi là không có tác dụng phụ. Tương tự áp dụng cho các trường hợp của lớp Rectangle, trong đó setter cho X đang thay đổi giá trị của TopBottom v.v.

Câu hỏi đặt ra là bạn sẽ vẽ một đường giữa việc sử dụng các bộ định vị, các tác dụng phụ của việc thay đổi các giá trị của thuộc tính có liên quan về mặt logic và sử dụng các phương pháp. Ví dụ: xác định phương thức có tên là SetDurationTo(Duration duration) cũng không phản ánh rằng Bắt đầu hoặc Kết thúc sẽ bị thay đổi.

Trả lời

8

Tôi nghĩ bạn hiểu nhầm cụm từ "tác dụng phụ" vì nó áp dụng cho thiết kế chương trình. Đặt thuộc tính hiệu ứng phụ, cho dù trạng thái nội bộ có thay đổi hay ít, miễn là nó thay đổi một số trạng thái. Một "setter không có tác dụng phụ" sẽ không hữu ích lắm.

Tác dụng phụ là thứ bạn muốn tránh trên thuộc tính getters. Đọc giá trị của một thuộc tính là điều mà người gọi không mong muốn thay đổi bất kỳ trạng thái nào (tức là gây ra tác dụng phụ), vì vậy nếu có, nó thường sai hoặc ít nhất là có vấn đề (có những ngoại lệ, chẳng hạn như tải lười). Tuy nhiên, getters và setters cũng chỉ là hàm bao cho các phương thức. Các tài sản Duration, như xa như CLR là có liên quan, chỉ là cú pháp đường cho một phương pháp set_Duration.

Đây chính xác là những gì trừu tượng như các lớp học có ý nghĩa - cung cấp các hoạt động hạt thô trong khi vẫn giữ trạng thái nội bộ nhất quán. Nếu bạn cố tình tránh để có nhiều tác dụng phụ trong một phép gán thuộc tính duy nhất thì các lớp của bạn sẽ không còn nhiều hơn các vùng chứa dữ liệu câm.

Vì vậy, hãy trả lời câu hỏi trực tiếp: Tôi vẽ đường ở đâu? Không nơi nào, miễn là phương pháp/tài sản thực sự làm những gì tên của nó ngụ ý. Nếu cài đặt Duration cũng thay đổi ActivityName, điều đó có thể gây ra sự cố. Nếu nó thay đổi thuộc tính Finish, điều đó phải rõ ràng; nó nên không thể thay đổi Duration và có cả hai StartFinish giữ nguyên. Tiền đề cơ bản của OOP là các đối tượng đủ thông minh để tự quản lý các hoạt động này.

Nếu điều này làm phiền bạn ở mức khái niệm thì không có đặc tính đột biến - sử dụng cấu trúc dữ liệu bất biến với thuộc tính chỉ đọc trong đó tất cả đối số cần thiết được cung cấp trong hàm tạo. Sau đó, có hai tình trạng quá tải, một quá tải mất Start/Duration và một quá trình khác mất một số Start/Finish. Hoặc chỉ làm cho một trong các thuộc tính có thể ghi - giả sử Finish để giữ cho nó phù hợp với Start - và sau đó thực hiện Duration chỉ đọc. Sử dụng sự kết hợp thích hợp của các thuộc tính có thể thay đổi và bất biến để đảm bảo rằng chỉ có một cách để thay đổi một trạng thái nhất định.

Nếu không, đừng lo lắng nhiều về điều này. Thuộc tính (và phương pháp) không được có không mong muốn hoặc không có giấy tờ tác dụng phụ, nhưng đó là hướng dẫn duy nhất tôi sẽ sử dụng.

+0

Cảm ơn, đây là những gì tôi đang tìm kiếm và nó không bao giờ xảy ra với tôi "tác dụng phụ - miễn phí setter "là trong thực tế không thể vì nó sẽ thay đổi trạng thái. Và như bạn đã chỉ ra CLR sẽ dịch sang phương pháp anyway. – Martin

+0

Có, tác dụng phụ của setter là đặt * biến thành viên mà nó đề cập đến *.Nhưng một hiệu ứng phụ bổ sung là sửa đổi * các biến thành viên * khác. –

+0

Tôi chỉ đang suy nghĩ về cùng và tôi thậm chí sẽ nói rằng thiết lập của biến thành viên không phải là một tác dụng phụ, nhưng hiệu quả mong muốn của setter. Thay đổi các biến thành viên khác là một tác dụng phụ. – Martin

0

Tôi luôn làm việc với quy tắc chung về việc không cho phép public người định cư trên các thuộc tính không có tác dụng phụ miễn phí vì người gọi người định cư công cộng của bạn không thể chắc chắn điều gì có thể xảy ra, nhưng tất nhiên, những người sửa đổi lắp ráp chính nó nên có một ý tưởng khá tốt vì họ có thể nhìn thấy mã.

Tất nhiên, luôn có những lúc bạn phải phá quy tắc vì mục đích dễ đọc, để làm cho mô hình đối tượng của bạn hợp lý, hoặc chỉ để làm cho mọi thứ hoạt động đúng. Như bạn đã nói, thực sự là một vấn đề ưu tiên nói chung.

1

Cá nhân, tôi nghĩ có ý nghĩa để có tác dụng phụ để duy trì trạng thái nhất quán. Như bạn đã nói, có ý nghĩa khi thay đổi các giá trị liên quan đến logic. Theo một nghĩa nào đó, tác dụng phụ được mong đợi. Nhưng điều quan trọng là làm rõ điểm đó. Đó là, nó phải được hiển nhiên rằng nhiệm vụ phương pháp đang thực hiện có một số loại tác dụng phụ. Vì vậy, thay vì SetDurationTo bạn có thể gọi chức năng của mình ChangeDurationTo, ngụ ý điều gì đó khác đang diễn ra. Bạn cũng có thể thực hiện theo cách khác bằng cách có hàm/phương pháp điều chỉnh thời lượng AdjustDurationTo và chuyển giá trị delta. Nó sẽ giúp đỡ nếu bạn tài liệu chức năng như có một tác dụng phụ.

Tôi nghĩ một cách khác để xem xét đó là xem liệu tác dụng phụ có được mong đợi hay không. Trong ví dụ của bạn về Hình chữ nhật, tôi hy vọng nó sẽ thay đổi giá trị của top hoặc bottom để duy trì trạng thái nhất quán trong nội bộ. Tôi không biết đây có phải là chủ quan hay không; nó có vẻ hợp lý với tôi. Như thường lệ, tôi nghĩ tài liệu sẽ thắng. Nếu có một tác dụng phụ, hãy ghi lại nó rất tốt. Tốt hơn là tên của phương thức và thông qua tài liệu hỗ trợ.

-2

Tôi nghĩ rằng đó chủ yếu là vấn đề thông thường. Trong ví dụ cụ thể này, vấn đề của tôi không nhiều đến nỗi bạn có các thuộc tính điều chỉnh các thuộc tính "liên quan", đó là bạn đã có các thuộc tính lấy các giá trị chuỗi mà sau đó bạn phân tích nội bộ vào DateTime (hoặc bất kỳ thứ gì).

Tôi thích gặp một cái gì đó như thế này:

Activity activity; 
activity.Start = DateTime.Parse("2010-01-01"); 
activity.Duration = Duration.Parse("10 days"); 

Đó là, bạn explicity lưu ý rằng bạn đang làm phân tích các chuỗi.Cho phép lập trình viên chỉ định các đối tượng được nhập mạnh khi điều đó cũng phù hợp.

+0

Như tôi đã đề cập "Lưu ý rằng giá trị cho ngày và thời gian chỉ được hiển thị cho mục đích chỉ định". Vì vậy, bình luận của bạn thực sự không giải quyết các câu hỏi yêu cầu, nhưng cảm ơn bạn anyway ... Tôi biết ai đó sẽ điểm này ;-) – Martin

1

Một tùy chọn là làm cho lớp của bạn trở nên bất biến và có các phương thức tạo và trả lại các phiên bản mới của lớp đã thay đổi tất cả các giá trị thích hợp. Sau đó, không có tác dụng phụ hoặc chất lắng. Hãy suy nghĩ về điều gì đó giống như DateTime nơi bạn có thể gọi những thứ như AddDaysAddHours sẽ trả lại phiên bản DateTime mới với thay đổi được áp dụng.

Các vấn đề liên quan