Bagaimana mengelola tanggung jawab tunggal ketika tanggung jawab dibagikan?


10

Saya punya dua kelas dasar, Operationdan Trigger. Masing-masing memiliki sejumlah subclass yang berspesialisasi dalam jenis operasi atau pemicu tertentu. A Triggerdapat memicu spesifik Operation. Sementara Operationdapat dipicu oleh spesifik Trigger.

Saya perlu menulis kode yang memetakan diberikan Operationke yang diberikan Trigger(atau sebaliknya), tapi saya tidak yakin di mana harus meletakkannya.

Dalam hal ini kode tidak jelas milik satu kelas atau kelas lain. Jadi dalam hal prinsip tanggung jawab tunggal, saya tidak yakin di mana kode itu seharusnya berada.

Saya dapat melihat tiga opsi yang semuanya akan berfungsi. Sementara 1 & 2 tampaknya hanya menjadi pilihan semantik, 3 mewakili pendekatan yang sama sekali berbeda.

  1. Pada pemicunya, misalnya bool Triggers(Operation o).
  2. Pada operasi, mis bool TriggeredBy(Trigger t).
  3. Di kelas yang sama sekali baru yang mengelola pemetaan, misalnya bool MappingExists(Trigger t, Operation o).

Bagaimana saya harus memutuskan di mana menempatkan kode pemetaan bersama sehubungan dengan prinsip tanggung jawab tunggal?

Bagaimana mengelola tanggung jawab tunggal ketika tanggung jawab dibagikan?


Edit 1.

Jadi kode aktualnya terlihat seperti ini. Semua properti, yang baik string, Guid, collection<string>, atau enum. Mereka pada dasarnya hanya mewakili potongan kecil data.

masukkan deskripsi gambar di sini

Edit 2.

Alasan kembalinya tipe bool. Kelas lain akan mengkonsumsi koleksi Triggerdan koleksi Operation. Perlu tahu di mana pemetaan ada antara a Trigger, dan a Operation. Itu akan menggunakan informasi itu untuk membuat laporan.


Mengapa tipe bool?
Tulains Córdova

@ user61852 untuk mengembalikan hasil ke kode panggilan
James Wood

1
Apa yang dilakukan kode panggilan dengan boolean? Tergantung dari apa yang Anda jawab untuk pertanyaan ini saya mungkin punya solusinya.
Tulains Córdova

@ user61852, silakan lihat suntingan saya.
James Wood

1
Jadi tidak ada hubungannya dengan benar-benar mengeksekusi pemicu operasi?
Tulains Córdova

Jawaban:


4

Saya akan memikirkannya seperti ini: bagaimana cara menentukan Operasi mana yang memicu Pemicu. Itu harus menjadi algoritma yang dapat berubah dari waktu ke waktu, atau berkembang menjadi beberapa algoritma. Menempatkannya di kelas Pemicu atau Operasi menyiratkan bahwa kelas-kelas tersebut akan dapat menangani skenario seperti itu di masa depan. Perhatikan, saya tidak melihatnya sesederhana pemetaan karena mungkin ada lebih dari itu.

Pilihan saya adalah membuat kelas dengan metode yang sesuai, seperti GetOperationForTrigger (Trigger t). Ini memungkinkan kode untuk berevolusi menjadi satu set kelas-kelas seperti pilihan yang dapat bergantung pada runtime atau variabel lain (misalnya pola strategi).

Perhatikan bahwa asumsi utama dalam pemikiran ini adalah untuk menulis kode minimal (yaitu tiga kelas hari ini) tetapi untuk menghindari refactoring utama jika fungsionalitas perlu diperluas di masa depan dengan tidak membuat asumsi bahwa akan selalu ada satu cara yang tepat untuk menentukan Pemicu mana yang menyebabkan Operasi.

Semoga ini membantu. Meskipun responsnya mirip dengan user61852, alasannya berbeda. Akibatnya, implementasi akan berbeda (yaitu memiliki metode eksplisit dan bukan mengesampingkan sama, sehingga jumlah metode dapat berkembang dari waktu ke waktu berdasarkan kebutuhan).


5

Pernah ke sana, melakukan itu.

Opsi # 3.

Saya tidak tahu bahasa apa yang akan Anda gunakan tetapi saya akan menggunakan pseudo-code yang sangat mirip dengan Java. Jika bahasa Anda adalah C # Anda mungkin memiliki antarmuka dan struktur yang serupa.

Memiliki kelas atau antarmuka Pemetaan:

public interface Mapping {
    public void setObject1(Object o);
    public void setObject2(Object o);
    public Object getObjecto1();
    public Object getObjecto2();
}
  • Mengganti equals()metode Mappingkoleksi sehingga Mappingdapat ditanyakan apakah mereka berisi pemetaan yang diberikan.
  • Objek khusus harus memiliki equals()metode yang memadai juga.
  • Juga terapkan antarmuka Comparable, sehingga Anda dapat mengurutkan laporan.

Mereka hanya dapat menempatkan pemetaan ke dalam koleksi

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

Nanti Anda bisa bertanya:

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

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

0
  1. Pecah kode Anda menjadi bit yang lebih kecil.

Saat ini Anda memiliki kelas A yang mengetahui tentang kelas B dan kelas B yang mengetahui tentang kelas A. Thats banyak kopling terjadi.

Menurut definisi A melakukan setidaknya operasinya sendiri DAN memeriksa apakah B harus dijalankan. Kebalikannya adalah benar dengan B. Kelas mana pun yang pertama kali dipanggil harus dapat melihat hasilnya dan melihat apakah hal-hal selanjutnya perlu dijalankan.

Coba dan pecahkan kopling itu dengan memecah kelas Anda menjadi komponen yang lebih kecil. Saya suka memberikan komentar di bagian atas setiap kelas menjelaskan dalam bahasa Inggris apa yang dilakukannya. Jika Anda perlu menggunakan kata-kata seperti DAN atau melewati satu atau dua kalimat maka Anda perlu mempertimbangkan untuk memecahnya. Sebagai aturan umum apa pun setelah "dan" harus di kelasnya sendiri

Lihat juga apakah Anda dapat menentukan antarmuka yang mencakup fungsi Pemicu dan Pengoperasian. Jika Anda tidak bisa itu indikasi lain bahwa kelas Anda terlalu besar. Ini juga akan merusak sambungan antara kelas Anda.


1
Dalam semua kejujuran saya tidak yakin saya dapat memecah kode saya lebih jauh. Saya telah memperbarui pertanyaan saya dengan tanda tangan kelas sehingga Anda dapat melihat, tetapi pada dasarnya mereka adalah objek data yang cukup ringan masing-masing menyimpan beberapa properti. Dalam hal penggandengan, ya itu sedikit bermasalah, karena secara efektif a Triggerakan digabungkan ke a Operation. Tapi seperti itulah data dunia nyata itu. Mereka digabungkan, karena ada pemetaan, misalnya mereka harus tahu tentang satu sama lain untuk memiliki makna.
James Wood
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.