Apa perbedaan antara Pola Strategi dan Injeksi Ketergantungan?


Jawaban:


107

DI dan Strategi bekerja dengan cara yang sama, tetapi Strategi digunakan untuk dependensi yang lebih halus dan berumur pendek.

Ketika sebuah objek dikonfigurasi dengan Strategi "tetap", misalnya ketika objek tersebut dibangun, perbedaan antara Strategi dan DI kabur. Tetapi dalam skenario DI, lebih tidak biasa bahwa ketergantungan objek berubah selama masa hidup mereka, sementara ini tidak jarang dengan Strategi.

Selain itu, Anda dapat meneruskan strategi sebagai argumen ke metode, sedangkan konsep terkait injeksi argumen metode tidak tersebar luas dan sebagian besar digunakan hanya dalam konteks pengujian otomatis.

Strategi berfokus pada niat dan mendorong Anda untuk membuat antarmuka dengan implementasi berbeda yang mematuhi kontrak perilaku yang sama. DI lebih dari sekadar menerapkan beberapa perilaku dan menyediakannya.

Dengan DI Anda dapat mendekomposisi program Anda untuk alasan lain selain hanya untuk dapat menukar bagian dari implementasi. Antarmuka yang digunakan di DI dengan hanya satu implementasi sangat umum. Sebuah "Strategi" dengan hanya satu implementasi konkret (pernah) bukanlah masalah nyata tetapi mungkin lebih dekat dengan DI.


Antarmuka yang digunakan di DI dengan hanya satu implementasi sangat umum - jadi apa DI dalam kasus khusus ini?
Kalpesh Soni

3
Kutipan ini pada dasarnya menjelaskan semuanya:in a DI scenario it is more unusual that the dependencies of objects change during their lifetimes, while this is not uncommon with Strategy
Sergey Telshevsky

Strategi: Kelas dirancang sedemikian rupa sehingga dapat dikonfigurasi dengan algoritme pada saat berjalan. DI: Kelas semacam itu mendapatkan algoritma (objek Strategi) yang dimasukkan pada waktu proses. Dari Memori Pola Desain GoF di w3sdesign.com .
GFranke

39

Perbedaannya adalah apa yang ingin mereka capai. Pola Strategi digunakan dalam situasi di mana Anda tahu bahwa Anda ingin menukar implementasi. Sebagai contoh, Anda mungkin ingin memformat data dengan cara yang berbeda - Anda dapat menggunakan pola strategi untuk menukar pemformat XML atau pemformat CSV, dll.

Dependency Injection berbeda karena pengguna tidak mencoba mengubah perilaku runtime. Mengikuti contoh di atas, kita mungkin membuat program ekspor XML yang menggunakan pemformat XML. Daripada menyusun kode seperti ini:

public class DataExporter() {
  XMLFormatter formatter = new XMLFormatter();
}

Anda akan 'menyuntikkan' pemformat di konstruktor:

public class DataExporter {
  IFormatter formatter = null;

  public DataExporter(IDataFormatter dataFormatter) {
    this.formatter = dataFormatter;
  }
}

DataExporter exporter = new DataExporter(new XMLFormatter());

Ada beberapa pembenaran untuk Injeksi Ketergantungan, tetapi yang utama adalah untuk pengujian. Anda mungkin memiliki kasus di mana Anda memiliki semacam mesin persistensi (seperti database). Namun, mungkin sulit untuk menggunakan database nyata saat Anda menjalankan pengujian berulang kali. Jadi, untuk kasus pengujian Anda, Anda akan menyuntikkan database dummy, sehingga Anda tidak menimbulkan overhead itu.

Dengan menggunakan contoh ini, Anda dapat melihat perbedaannya: kami selalu berencana menggunakan strategi penyimpanan data, dan itulah yang kami berikan (instans DB yang sebenarnya). Namun, dalam pengembangan dan pengujian, kami ingin menggunakan dependensi yang berbeda, jadi kami memasukkan konkresi yang berbeda.


28

Anda dapat menggunakan DI sebagai pola strategi, sehingga Anda dapat menukar algoritme yang diperlukan untuk setiap pelanggan, tetapi DI dapat melampaui itu karena ini adalah cara untuk hanya memisahkan bagian-bagian aplikasi, yang tidak akan menjadi bagian dari pola strategi.

Akan berisiko untuk mengatakan bahwa DI hanyalah pola strategi yang diubah namanya karena itu mulai mengurangi untuk apa pola strategi sebenarnya, IMO.


2
Saya rasa saya memahami inti Anda, tetapi saya tidak dapat menempatkannya dalam kata-kata dengan benar ... Jadi ucapan Anda DI lebih merupakan pola implementasi sedangkan strategi lebih merupakan pola desain, dan salah satu cara untuk mengimplementasikan strategi adalah melalui DI?
Robert Gould

1
Kedengarannya itu cara yang bagus untuk menjelaskannya. DI lebih dari sekedar pola strategi. Saya menemukan kebingungan yang sama dengan AOP, di mana orang menganggapnya sebagai pola pabrik. Saya pikir DI dapat menerapkan pola strategi, jadi penulisan ulang Anda akan tampak fantastis. :)
James Black

15

Bung, injeksi ketergantungan adalah pola yang lebih umum, dan ini tentang ketergantungan pada abstraksi bukan konkresi dan ini adalah bagian dari setiap pola, tetapi pola strategi adalah solusi untuk masalah yang lebih spesifik

ini definisi dari wikipedia:

DI:

Dependency injection (DI) dalam pemrograman komputer berorientasi objek adalah pola desain dengan prinsip inti memisahkan perilaku dari resolusi ketergantungan. Dengan kata lain: teknik untuk memisahkan komponen perangkat lunak yang sangat bergantung.

Pola Strategi:

Dalam pemrograman komputer, pola strategi (juga dikenal sebagai pola kebijakan) adalah pola desain perangkat lunak tertentu, di mana algoritme dapat dipilih saat runtime.

Pola strategi dimaksudkan untuk menyediakan sarana untuk mendefinisikan keluarga algoritme, merangkum masing-masing algoritme sebagai objek, dan membuatnya dapat dipertukarkan. Pola strategi memungkinkan algoritme bervariasi secara independen dari klien yang menggunakannya.


3
Saya terutama menyukai bagian "Bung" dalam penjelasan Anda. :-)
johey

7

Strategi adalah hal-hal tingkat tinggi yang digunakan untuk mengubah cara menghitung sesuatu. Dengan injeksi ketergantungan, Anda tidak hanya dapat mengubah cara penghitungan tetapi juga mengubah apa yang ada.

Bagi saya, menjadi jelas saat menggunakan pengujian unit. Untuk eksekusi kode produksi, Anda menyembunyikan semua data (yaitu pribadi atau dilindungi); sedangkan, dengan pengujian unit, sebagian besar datanya bersifat publik sehingga saya dapat melihatnya dengan Asserts.


Contoh strategi:

public class Cosine {
  private CalcStrategy strat;

  // Constructor - strategy passed in as a type of DI
  public Cosine(CalcStrategy s) {
    strat = s;
  }
}

public abstract class CalcStrategy {
  public double goFigure(double angle);
}

public class RadianStrategy extends CalcStrategy {
  public double goFigure(double angle) {
    return (...);
  }
}
public class DegreeStrategy extends CalcStrategy {
  public double goFigure(double angle) {
    return (...);
  }
}

Perhatikan bahwa tidak ada data publik yang berbeda antar strategi. Juga tidak ada metode yang berbeda. Kedua strategi memiliki fungsi dan tanda tangan yang sama.


Sekarang untuk injeksi ketergantungan:

public class Cosine {
  private Calc strat;

  // Constructor - Dependency Injection.
  public Cosine(Calc s) {
    strat = s;
  }
}

public class Calc {
  private int numPasses = 0;
  private double total = 0;
  private double intermediate = 0;

  public double goFigure(double angle) {
    return(...);
}

public class CalcTestDouble extends Calc {
  // NOTICE THE PUBLIC DATA.
  public int numPasses = 0;
  public double total = 0;
  public double intermediate = 0;
  public double goFigure(double angle) {
    return (...);
  }
}

Menggunakan:

public CosineTest {

  @Test
  public void testGoFigure() {
    // Setup
    CalcTestDouble calc = new CalcTestDouble();
    Cosine instance = new Cosine(calc);

    // Exercise
    double actualAnswer = instance.goFigure(0.0);

    // Verify
    double tolerance = ...;
    double expectedAnswer = ...;
    assertEquals("GoFigure didn't work!", expectedAnswer,
         actualAnswer, tolerance);

    int expectedNumPasses = ...;
    assertEquals("GoFigure had wrong number passes!",
        expectedNumPasses, calc.numPasses);

    double expectedIntermediate = ...;
    assertEquals("GoFigure had wrong intermediate values!",
        expectedIntermediate, calc.intermediate, tolerance);
  }
}

Perhatikan 2 pemeriksaan terakhir. Mereka menggunakan data publik di tes ganda yang disuntikkan ke kelas yang diuji. Saya tidak dapat melakukan ini dengan kode produksi karena prinsip penyembunyian data. Saya tidak ingin kode pengujian tujuan khusus dimasukkan ke dalam kode produksi. Data publik harus berada di kelas yang berbeda.

Tes ganda disuntikkan. Itu berbeda dari sekedar strategi karena itu mempengaruhi data dan bukan hanya fungsi.


4

Dependency injection merupakan penyempurnaan dari pola strategi yang akan saya jelaskan secara singkat. Seringkali perlu memilih di antara beberapa modul alternatif saat runtime. Semua modul ini menerapkan antarmuka yang sama sehingga dapat digunakan secara bergantian. Tujuan dari pola strategi adalah untuk menghilangkan beban dalam memutuskan modul mana yang akan digunakan (yaitu "strategi konkrit" atau ketergantungan) dengan merangkum proses pengambilan keputusan ke dalam objek terpisah yang akan saya sebut sebagai objek strategi.

Injeksi ketergantungan menyempurnakan pola strategi dengan tidak hanya memutuskan strategi konkret mana yang akan digunakan, tetapi juga membuat instance dari strategi konkret dan "memasukkannya" kembali ke modul pemanggil. Ini berguna bahkan jika hanya ada satu ketergantungan karena pengetahuan tentang bagaimana mengelola (menginisialisasi dll) contoh strategi konkret juga dapat disembunyikan di dalam objek strategi.


1

Sebenarnya dependency injection juga terlihat sangat mirip dengan pola Bridge. Bagi saya (dan menurut definisi), pola Jembatan adalah untuk mengakomodasi versi implementasi yang berbeda, sedangkan pola Strategi adalah untuk logika yang sama sekali berbeda. Tetapi kode contoh sepertinya menggunakan DI. Jadi mungkin DI hanyalah teknik atau implementasi?


0

Strategi adalah arena untuk menggunakan keterampilan injeksi ketergantungan Anda. Cara nyata untuk menerapkan injeksi ketergantungan adalah sebagai berikut: -

  1. Acara
  2. File konfigurasi peta kesatuan / struktur (atau secara terprogram) dll.
  3. Metode Ekstensi
  4. Abstrak Pola pabrik
  5. Pembalikan pola kontrol (digunakan oleh kedua strategi dan Pabrik Abstrak)

Namun ada satu hal yang membuat strategi berbeda. Seperti yang Anda ketahui di Unity saat aplikasi dijalankan, semua dependensi disetel dan kami tidak dapat mengubahnya lebih lanjut. Namun strategi mendukung perubahan ketergantungan waktu proses. Tapi KAMI harus mengelola / menyuntikkan ketergantungan, bukan tanggung jawab Strategi!

Sebenarnya strategi tidak berbicara tentang ketergantungan injeksi. Jika diperlukan dapat dilakukan melalui Pabrik Abstrak dalam pola Strategi. Strategi hanya berbicara tentang membuat keluarga kelas dengan antarmuka dan 'bermain' dengannya. Saat bermain, jika kami menemukan kelas berada di tingkat yang berbeda maka kami harus menyuntikkannya sendiri tetapi bukan tugas Strategi.


0

Jika kita mempertimbangkan prinsip SOLID - Kita menggunakan Pola Strategi untuk Prinsip Tertutup Terbuka dan Injeksi Ketergantungan untuk Prinsip Pembalikan Ketergantungan


1
Saya tidak yakin saya ikuti, bisakah Anda menjelaskan bagaimana Strategi berkaitan dengan prinsip Terbuka / Tertutup dan bagaimana DI terkait dengan DIP?
Adam Parkin
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.