Làm thế nào để quản lý trách nhiệm duy nhất khi trách nhiệm được chia sẻ?


10

Tôi có hai lớp cơ sở, OperationTrigger. Mỗi lớp có một số lớp con chuyên về một số loại hoạt động hoặc kích hoạt nhất định. A Triggercó thể kích hoạt một cụ thể Operation. Trong khi một Operationcó thể được kích hoạt bởi một cụ thể Trigger.

Tôi cần phải viết mã ánh xạ một mã Operationcho trước Trigger(hoặc ngược lại), nhưng tôi không chắc chắn nên đặt mã đó ở đâu.

Trong trường hợp này, mã không rõ ràng thuộc về một lớp hoặc lớp khác. Vì vậy, theo nguyên tắc một trách nhiệm duy nhất, tôi không chắc mã nên thuộc về đâu.

Tôi có thể thấy ba tùy chọn sẽ làm việc tất cả. Trong khi 1 & 2 dường như chỉ là một sự lựa chọn về ngữ nghĩa, thì 3 đại diện cho một cách tiếp cận hoàn toàn khác.

  1. Trên kích hoạt, ví dụ bool Triggers(Operation o).
  2. Về hoạt động, ví dụ bool TriggeredBy(Trigger t).
  3. Trong một lớp hoàn toàn mới quản lý ánh xạ, ví dụ bool MappingExists(Trigger t, Operation o).

Làm thế nào tôi nên quyết định nơi đặt mã ánh xạ được chia sẻ theo nguyên tắc trách nhiệm duy nhất?

Làm thế nào để quản lý trách nhiệm duy nhất khi trách nhiệm được chia sẻ?


Chỉnh sửa 1.

Vì vậy, mã thực tế trông như thế này. Tất cả các tài sản, hoặc là một string, Guid, collection<string>, hoặc enum. Chúng cơ bản chỉ là đại diện cho những mẩu dữ liệu nhỏ.

nhập mô tả hình ảnh ở đây

Chỉnh sửa 2.

Lý do cho kiểu trả về của bool. Một lớp khác sẽ tiêu thụ một bộ sưu tập Triggervà một bộ sưu tập Operation. Nó cần biết nơi ánh xạ tồn tại giữa a Triggervà an Operation. Nó sẽ sử dụng thông tin đó để tạo một báo cáo.


Tại sao các loại bool?
Tulains Córdova 16/2/2016

@ user61852 để trả lại kết quả cho mã cuộc gọi
James Wood

1
Mã gọi làm gì với boolean? Tùy thuộc vào những gì bạn trả lời cho câu hỏi này, tôi có thể có giải pháp.
Tulains Córdova 16/2/2016

@ user61852, vui lòng xem các chỉnh sửa của tôi.
James Wood

1
Vì vậy, nó có liên quan gì đến việc thực sự kích hoạt hoạt động không?
Tulains Córdova 16/2/2016

Câu trả lời:


4

Tôi sẽ nghĩ về nó theo cách này: làm thế nào để xác định Hoạt động nào gây ra Kích hoạt nào được kích hoạt. Nó phải là một thuật toán có thể thay đổi theo thời gian hoặc phát triển thành nhiều thuật toán. Đặt nó trong các lớp Kích hoạt hoặc Hoạt động ngụ ý rằng các lớp đó sẽ có thể xử lý các tình huống như vậy trong tương lai. Lưu ý rằng tôi không thấy nó đơn giản như ánh xạ vì có thể có nhiều thứ hơn.

Lựa chọn của tôi sẽ là tạo một lớp với các phương thức thích hợp, chẳng hạn như GetOperationForTrigger (Trigger t). Điều này cho phép mã phát triển thành một tập hợp các lớp như vậy sự lựa chọn có thể phụ thuộc vào thời gian chạy hoặc các biến khác (ví dụ mẫu chiến lược).

Lưu ý rằng giả định chính trong dòng suy nghĩ này là viết mã tối thiểu (tức là ba lớp ngày nay) nhưng để tránh tái cấu trúc lớn nếu chức năng cần được mở rộng trong tương lai bằng cách không đưa ra giả định rằng sẽ luôn có một cách chính xác xác định kích hoạt nào gây ra hoạt động.

Hi vọng điêu nay co ich. Mặc dù phản hồi tương tự như user61852, nhưng lý do thì khác. Do đó, việc triển khai sẽ khác nhau (tức là có các phương thức rõ ràng thay vì ghi đè bằng, do đó số lượng phương thức có thể phát triển theo thời gian dựa trên nhu cầu).


5

Đã từng trải qua rồi.

Lựa chọn số 3.

Tôi không biết bạn sẽ sử dụng ngôn ngữ nào nhưng tôi sẽ sử dụng mã giả rất giống với Java. Nếu ngôn ngữ của bạn là C #, bạn có thể có các giao diện và cấu trúc tương tự.

Có lớp hoặc giao diện Ánh xạ:

public interface Mapping {
    public void setObject1(Object o);
    public void setObject2(Object o);
    public Object getObjecto1();
    public Object getObjecto2();
}
  • Ghi đè equals()phương thức Mappingđể các bộ sưu tập Mappingcó thể được hỏi xem chúng có chứa ánh xạ đã cho không.
  • Các đối tượng đặc biệt cũng nên có equals()các phương thức thích nghi.
  • Cũng thực hiện giao diện Comparable, vì vậy bạn có thể sắp xếp các báo cáo.

Chúng bạn có thể chỉ cần đặt một ánh xạ vào một bộ sưu tập

List<Mapping> list = new ArrayList<Mapping>();
Hat hat = new Hat();
Bag bag = new Bag();
list.add(new Mapping(hat,bag));

Sau này bạn có thể hỏi:

// let's say you have a variable named x which is of type Mapping

if ( list.contains(x) ){
    // do some thing
}

0
  1. Chia mã của bạn thành các bit nhỏ hơn.

Hiện tại bạn có lớp A biết về lớp B và lớp B biết về lớp A. Đó là rất nhiều khớp nối đang diễn ra.

Theo định nghĩa A đang thực hiện ít nhất là hoạt động của chính nó kiểm tra xem B có nên chạy không. Điều ngược lại là đúng với B. Bất kỳ lớp nào được gọi đầu tiên, nó sẽ có thể nhìn vào kết quả và xem liệu nó có cần chạy thêm không.

Hãy thử và phá vỡ khớp nối đó bằng cách chia các lớp của bạn thành các thành phần nhỏ hơn. Tôi muốn đặt một nhận xét ở đầu mỗi lớp giải thích bằng tiếng Anh đơn giản những gì nó làm. Nếu bạn cần sử dụng các từ như AND hoặc nó đi qua một hoặc hai câu thì bạn cần xem xét phá vỡ nó. Như một quy tắc chung, bất cứ điều gì sau một "và" nên nằm trong lớp riêng của nó

Đồng thời xem bạn có thể xác định giao diện bao gồm chức năng của Kích hoạt và Vận hành không. Nếu bạn không thể đó là một dấu hiệu khác cho thấy lớp học của bạn đang trở nên quá lớn. Nó cũng sẽ phá vỡ khớp nối giữa các lớp của bạn.


1
Thành thật mà nói tôi không chắc mình có thể phá vỡ mã của mình hơn nữa. Tôi đã cập nhật câu hỏi của mình với các chữ ký lớp để bạn có thể thấy, nhưng về cơ bản chúng là các đối tượng dữ liệu khá nhẹ lưu trữ một vài thuộc tính. Về mặt khớp nối, vâng, điều đó hơi có vấn đề, vì thực tế, a Triggersẽ được ghép với a Operation. Nhưng đó là loại dữ liệu trong thế giới thực. Chúng được ghép nối, bởi vì có một ánh xạ, ví dụ chúng phải biết về nhau để có ý nghĩa.
James Wood
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.