Jika Anda memiliki sepotong logika yang perlu dibagi antara dua pengendali, di mana Anda menyimpannya?

10

Saya memiliki satu set fungsi tujuan tunggal yang saya butuhkan dalam dua pengontrol terpisah. Saat ini saya hanya memiliki kode duplikat dan saya ingin menyingkirkannya. Kode ini adalah bagian dari pengontrol dan tidak termasuk dalam lapisan layanan saya. Di mana Anda akan meletakkannya?

Erin
sumber
CakePHP menyebut mereka Komponen: book.cakephp.org/2.0/en/controllers/components.html mungkin itu beberapa inspirasi.
Luc Franken

Jawaban:

12

Anda tidak mengatakan jenis logika apa yang Anda bagikan. Singkatnya, apakah ini kontroler logika atau fungsi pembantu? Dua metode berurusan dengan ini dalam bahasa berorientasi objek adalah pewarisan dan komposisi. Warisan masuk akal jika ada aksi bersama antara dua pengendali. Komposisi masuk akal sepanjang waktu. Contoh menggunakan warisan terletak pada jawaban asli saya di bawah pembagi.

Tidak jarang memiliki kelas utilitas atau kelas pembantu tergantung pada kerangka kerja Anda. Misalnya, dalam kerangka kerja Java dan C # Anda mungkin memiliki paket / namespace untuk utilitas. Di Ruby on Rails, Anda mungkin memanfaatkan Helperkelas yang membagikan logika antara pengontrol dan tampilan. Pada dasarnya, akan terlihat seperti ini:

// NOTE: group similar functions
static class LoginUtility
{
    static bool IsLoggedIn(Request request) { /* ... */ }
}

Atau, Anda bisa menjadikannya kelas yang Anda instantiate. Kunci pola kelas statis di atas adalah untuk membuat fungsi Anda fungsi murni. Dengan kata lain, Anda lulus dalam kondisi apa pun yang perlu dilakukan tugasnya, dan fungsinya tidak merujuk keadaan statis lain di sistem.

Dalam kedua kasus, Anda akan mengaksesnya di setiap pengontrol Anda seperti ini:

void MyAction()
{
    if (LoginUtiltiy.IsLoggedIn(Request))
    {
        // Do something ...
    }
}

Jawaban Asli

Anda tidak mengatakan apa platform Anda, karena itu dapat mempengaruhi jawabannya. Dengan asumsi bahwa itu adalah bahasa berorientasi objek, pendekatan yang paling umum adalah membuat kelas dasar yang diperluas oleh kedua pengontrol. Misalnya di Ruby on Rails yang mungkin Anda miliki:

class BaseController < ApplicationController
    def my_special_function
        # ...
    end
end

class Controller1 < BaseController
    # ...
end

class Controller2 < BaseController
    # ...
end

Anda dapat menerjemahkan ide ke bahasa lain juga. Pendekatan yang sama akan bekerja untuk ASP.NET MVC, Apache Wicket, Grails, atau hampir semua kerangka kerja web berorientasi objek lainnya. Jika bahasa Anda tidak berorientasi objek, maka itu benar-benar tergantung pada bagaimana kerangka kerja dirancang sebagai pendekatan terbaik .

Berin Loritsch
sumber
3
Alternatifnya adalah untuk merangkum logika dalam kelas yang terpisah, kemudian instantiate kelas itu dan memanggil logika dari kedua pengendali.
Kramii
5
Yup, saya selalu lebih suka komposisi daripada warisan
Reno
1
Lakukan saran Kramii alih-alih menambahkan lapisan warisan tambahan. Tapi saya pikir pertanyaan aktualnya adalah kemana perginya solusi kelas itu.
Tidak seorang pun
1
Itu tergantung pada apa fungsi dan kerangka kerjanya. Di rel, itu mungkin termasuk dalam kelas Helper. Di ASP.NET atau Java, Anda mungkin memiliki kelas utilitas untuk jenis fungsi itu. Itu benar-benar tergantung pada seberapa dekat dengan controller yang dibutuhkan untuk hidup.
Berin Loritsch
Ini logika pengontrol. Saya kebetulan membutuhkannya di dua tempat. Apa yang saya miliki sekarang adalah kelas ekstensi yang saya gunakan untuk meletakkan logika di satu lokasi.
Erin