import java.util.List;

public class MetodePabrik {
    public static void main(String[] args) {
        List<String> dataPenjualan = List.of("apel", "jeruk");
        PabrikLaporan[] daftarPabrik = { new PabrikTeks(), new PabrikCsv() };

        // Klien hanya mengenal PabrikLaporan; subclass yang memilih concrete class
        for (PabrikLaporan pabrik : daftarPabrik) {
            pabrik.tampilkan(dataPenjualan);
        }
    }
}

interface Laporan {
    String render(List<String> data);
}

abstract class PabrikLaporan {
    // Factory method (GoF): subclass yang menentukan objek apa yang diciptakan
    abstract Laporan buatLaporan();

    // Template method yang memakai hasil factory method
    final void tampilkan(List<String> data) {
        Laporan laporan = buatLaporan();
        System.out.println("[" + namaPabrik() + "] " + laporan.render(data));
    }

    abstract String namaPabrik();
}

class PabrikTeks extends PabrikLaporan {
    @Override
    Laporan buatLaporan() {
        return data -> "teks: " + String.join(", ", data);
    }

    @Override
    String namaPabrik() {
        return "PabrikTeks";
    }
}

class PabrikCsv extends PabrikLaporan {
    @Override
    Laporan buatLaporan() {
        return data -> "csv: " + String.join(";", data);
    }

    @Override
    String namaPabrik() {
        return "PabrikCsv";
    }
}
