Statis itu buruk, tetapi bagaimana dengan pola Pabrik?

13

Saya sedang mengerjakan proyek TDD, jadi saya mencoba untuk menempel sebanyak mungkin pada praktik-praktik baik yang terkait dengan pengembangan semacam itu. Salah satunya adalah menghindari sebanyak mungkin statis dan global.

Saya menghadapi masalah ini: Saya memiliki "artikel" objek yang dapat memiliki "opsi" (tambahan "artikel mikro") yang terhubung dengannya.

Saya tidak dapat menemukan cara untuk memiliki pendekatan yang baik yang tidak akan menjadi kontra-produktif atau menghasilkan terlalu banyak pertanyaan karena saya akan berada dalam situasi di mana semuanya begitu terpisah sehingga pada dasarnya saya perlu membuat 1 permintaan per objek.

Dari perspektif saya yang sebenarnya, saya melihat 3 opsi:

1) Membangun di dalam artikel:

class Article
{
    //[...]
    public function getArrOption(){
        //Build an array of Options instance.
        //return an array of Options.
    }
}

Pro: Lurus ke depan

Const: Maintenability: Objek artikel sekarang berisi logika bangunan untuk objek Opsi. Ini mungkin akan menyebabkan duplikasi kode.

2) Menggunakan optionFactory

class Article
{
    //[...]
    public function getArrOption(){
        return OptionFactory::buildFromArticleId($this->getId());
    }
}

Pro: Membangun logika tidak keluar dari kelas Artikel

Const: Saya melanggar aturan "statis sulit untuk dipermainkan", membuat kelas Pasal saya sulit untuk diuji.

3) Pisahkan semua logika.

//Build the array of Option instance in a controller somewhere, using a Factory:
$arrOption = OptionFactory::buildFromArticleId($article->getId());

Pro: Artikel hanya menangani tanggung jawabnya sendiri, dan tidak peduli dengan tautan "ayahnya" ke opsi. Segala sesuatunya benar-benar terpisah

Const: Akan membutuhkan lebih banyak kode di dalam Controller setiap kali saya harus mengakses Options. Itu berarti bahwa saya seharusnya tidak pernah menggunakan Pabrik di dalam suatu objek, dan itu semacam utopis bagi saya ...

Apa cara terbaik untuk pergi? (Apakah saya melewatkan sesuatu?) Terima kasih.

Edit:

Belum lagi jika saya tidak dapat memanggil pabrik di dalam kelas, pada dasarnya saya tidak akan pernah menggunakan pola inisialisasi malas juga ...

FMaz008
sumber
Saya tidak yakin apakah itu relevan, tapi saya sedang coding di PHP, jadi "aplikasi" -nya kurang. Kami harus memuat ulang semua data di antara setiap halaman jika tidak disimpan dalam cookie sesi. Itu berarti bahwa kami tidak dapat memuat semuanya seperti dalam bahasa aplikasi.
FMaz008
@job: Yah itu karena panggilan statis di dalam metode sebagian besar tidak mungkin untuk diganti ketika pengujian unit. Tujuannya adalah menggunakan injeksi ketergantungan. Tapi pabrik biasanya statis, jadi tidak bisa disuntikkan.
FMaz008

Jawaban:

12
  1. Statis bukan "buruk", itu tidak dapat digerakkan. Anda masih dapat menggunakannya di mana mengejek tidak masuk akal.

  2. Itu bukan pola Pabrik, sepertinya pola Repositori, meskipun mungkin tidak. Factory adalah tempat Anda memiliki banyak kelas dengan antarmuka / kelas dasar yang sama dan Anda ingin memisahkan logika yang memutuskan kelas mana yang akan dikembalikan. Repositori mendapatkan data dari repositori-nya, mengabstraksi implementasi repositori tersebut (Artikel tidak perlu tahu apakah opsinya disimpan dalam DB yang sama, satu lagi, file XML, file CSV, apa pun).

  3. Anda telah mengabaikan kemungkinan memberi objek kelas ObjectFactory (atau Repositori, atau apa pun) pada kelas Artikel di mana ia dapat memanggil metode buildFromArticle.

PHP saya berkarat, tapi saya pikir tampilannya seperti ini:

class Article
{
    private $_option_repository;

    public function __construct($option_repository) {
        $_option_repository = $option_repository;
    }

    //[...]

    public function getArrOption(){
        return $_option_repository->buildFromArticleId($this->getId());
    }
}

Saya pikir ini memenuhi semua pro Anda di atas.

pdr
sumber
Jadi tidak masalah untuk membuat instance dari Factory / Repository / Mapper? Saya memerlukan wadah ketergantungan atau sesuatu karena jika kita perlu menyuntikkan semua pabrik / repositori / mapper untuk semua objek yang mungkin dapat dikembalikan oleh suatu objek, itu dengan cepat menghasilkan banyak. (Artikel -> OptionGroup -> Opsi -> Artikel, dll.)
FMaz008
1
Lebih dari ok, lebih disukai. Saya biasanya menggunakan statis untuk menghapus kode berulang, di mana itu cukup kecil untuk diuji di beberapa kelas. Dan ya, IOC / DI Container akan membuat hidup Anda jauh lebih mudah. Gunakan satu.
pdr
1

Berikut adalah kutipan dari makalah yang berpendapat bahwa Anda tidak perlu metode statis, bahwa pabrik abstrak telah terbukti membingungkan, dan menyarankan sedikit perubahan bahasa menuju injeksi ketergantungan sebagai solusinya.

Kopling ketat antara instance dan kelasnya merusak enkapsulasi, dan, bersama dengan visibilitas global metode statis, mempersulit pengujian. Dengan membuat injeksi ketergantungan sebagai fitur dari bahasa pemrograman, kita dapat menyingkirkan metode statis sama sekali. Kami menggunakan perubahan semantik berikut:

(1) Ganti setiap kemunculan global dengan akses ke variabel instan;

(2) Biarkan variabel instans tersebut secara otomatis disuntikkan ke objek ketika instantiated.

"Seuss: Memisahkan tanggung jawab dari metode statis untuk konfigurasi yang lebih baik"

Link Mesin Wayback

nes1983
sumber
3
Meskipun tautan ini dapat menjawab pertanyaan, lebih baik untuk memasukkan bagian-bagian penting dari jawaban di sini dan memberikan tautan untuk referensi. Jawaban hanya tautan dapat menjadi tidak valid jika halaman tertaut berubah.
nyamuk