# Dependency Inversion Principle (DIP)

#### Dependency Inversion Principle (DIP) dalam PHP:

Dalam PHP, DIP dapat diterapkan dengan memastikan bahwa kelas tingkat tinggi tidak bergantung pada kelas tingkat rendah, tetapi keduanya bergantung pada abstraksi. Ini dapat dicapai dengan menggunakan pola Dependency Injection (DI) atau melalui penyediaan interface.

Contoh PHP dengan DIP menggunakan DI:

```php
// Interface untuk Database
interface Database {
    public function connect();
}

// Implementasi Database MySQL
class MySqlConnection implements Database {
    public function connect() {
        // Logika koneksi ke MySQL
    }
}

// Implementasi Database PostgreSQL
class PostgreSqlConnection implements Database {
    public function connect() {
        // Logika koneksi ke PostgreSQL
    }
}

// Kelas tingkat tinggi yang mengonsumsi Database melalui Dependency Injection
class UserManager {
    private $database;

    public function __construct(Database $database) {
        $this->database = $database;
    }

    public function fetchData() {
        $connection = $this->database->connect();
        // Logika pengambilan data dari database
    }
}
```

Dalam contoh ini, `UserManager` bergantung pada abstraksi `Database` melalui konstruktor, dan bukan pada implementasi konkrit dari `Database`. Ini memungkinkan Anda untuk dengan mudah mengganti implementasi `Database` tanpa mengubah `UserManager`.

#### Dependency Inversion Principle (DIP) dalam JavaScript:

Dalam JavaScript, DIP dapat diterapkan dengan cara yang mirip menggunakan konsep Dependency Injection.

Contoh JavaScript (ES6) dengan DIP menggunakan Dependency Injection:

```javascript
// Interface untuk Database
class Database {
    connect() {
        throw new Error("Method 'connect()' must be implemented");
    }
}

// Implementasi Database MySQL
class MySqlConnection extends Database {
    connect() {
        // Logika koneksi ke MySQL
    }
}

// Implementasi Database PostgreSQL
class PostgreSqlConnection extends Database {
    connect() {
        // Logika koneksi ke PostgreSQL
    }
}

// Kelas tingkat tinggi yang mengonsumsi Database melalui Dependency Injection
class UserManager {
    constructor(database) {
        this.database = database;
    }

    fetchData() {
        const connection = this.database.connect();
        // Logika pengambilan data dari database
    }
}
```

Dalam contoh ini, `UserManager` menerima objek `Database` melalui konstruktor, memungkinkan Anda untuk menggunakan berbagai implementasi database tanpa memodifikasi `UserManager`.

#### Dependency Inversion Principle (DIP) dalam Golang:

Dalam Golang, DIP dapat diterapkan dengan menggunakan antarmuka dan dependensi diinisialisasi melalui parameter atau metode.

Contoh Golang dengan DIP menggunakan Dependency Injection melalui parameter:

```go
package main

import (
    "fmt"
)

type Database interface {
    Connect() string
}

type MySqlConnection struct {}

func (m MySqlConnection) Connect() string {
    return "Connected to MySQL"
}

type PostgreSqlConnection struct {}

func (p PostgreSqlConnection) Connect() string {
    return "Connected to PostgreSQL"
}

type UserManager struct {
    database Database
}

func NewUserManager(database Database) *UserManager {
    return &UserManager{database: database}
}

func (u UserManager) FetchData() {
    connection := u.database.Connect()
    // Logika pengambilan data dari database
    fmt.Println(connection)
}

func main() {
    mysql := MySqlConnection{}
    postgres := PostgreSqlConnection{}

    userManagerMySQL := NewUserManager(mysql)
    userManagerPostgres := NewUserManager(postgres)

    userManagerMySQL.FetchData()    // Output: Connected to MySQL
    userManagerPostgres.FetchData() // Output: Connected to PostgreSQL
}
```

Dalam contoh ini, `UserManager` menerima implementasi `Database` melalui parameter konstruktor. Dengan cara ini, Anda dapat mengganti implementasi database tanpa mengubah `UserManager`. Dengan cara yang sama, Anda juga dapat menggunakan Dependency Injection melalui metode jika diperlukan.
