Bagi saya, cara untuk pergi adalah antarmuka dan Pabrik. Salah satu yang mengembalikan referensi ke antarmuka di mana berbagai kelas dapat disembunyikan. Kelas-kelas yang melakukan pekerjaan kasar yang sebenarnya semua harus terdaftar dengan Pabrik sehingga tahu kelas mana yang akan dipakai memberikan satu set parameter.
Catatan: alih-alih antarmuka Anda juga bisa menggunakan kelas basis abstrak, tetapi kekurangannya adalah bahwa untuk bahasa pewarisan tunggal itu membatasi Anda ke kelas basis tunggal.
TRepresentationType = (rtImage, rtTable, rtGraph, ...);
Factory.RegisterReader(TJSONReader, 'json');
Factory.RegisterReader(TXMLReader, 'xml');
Factory.RegisterWriter(TPDFWriter, 'pdf');
Factory.RegisterWriter(TPowerPointWriter, 'ppt');
Factory.RegisterWriter(TWordWriter, 'doc');
Factory.RegisterWriter(TWordWriter, 'docx');
Factory.RegisterRepresentation(TPNGImage, rtImage, 'png');
Factory.RegisterRepresentation(TGIFImage, rtImage, 'gif');
Factory.RegisterRepresentation(TJPGImage, rtImage, 'jpg');
Factory.RegisterRepresentation(TCsvTable, rtTable, 'csv');
Factory.RegisterRepresentation(THTMLTable, rtTable, 'html');
Factory.RegisterRepresentation(TBarChart, rtTGraph, 'bar');
Factory.RegisterRepresentation(TPieChart, rtTGraph, 'pie');
Kode dalam sintaksis Delphi (Pascal) karena itu adalah bahasa yang paling saya kenal.
Setelah semua kelas implementasi terdaftar di pabrik, Anda harus dapat meminta referensi antarmuka ke turunan kelas semacam itu. Sebagai contoh:
Factory.GetReader('SomeFileName.xml');
Factory.GetWriter('SomeExportFileName.ppt');
Factory.GetRepresentation(rtTable, 'html');
harus mengembalikan referensi IReader ke instance TXMLReader; referensi IWriter ke instance TPowerPointWriter dan referensi IRepresentation ke instance THTMLTable.
Sekarang semua mesin rendering perlu lakukan, adalah mengikat semuanya:
procedure Render(
aDataFile: string;
aExportFile: string;
aRepresentationType: TRepresentationType;
aFormat: string;
);
var
Reader: IReader;
Writer: IWriter;
Representation: IRepresentation;
begin
Reader := Factory.GetReaderFor(aDataFile);
Writer := Factory.GetWriterFor(aExportFile);
Representation := Factory.GetRepresentationFor(aRepresentationType, aFormat);
Representation.ConstructFrom(Reader);
Writer.SaveToFile(Representation);
end;
Antarmuka IReader harus menyediakan metode untuk membaca data yang dibutuhkan oleh pelaksana IRepresentation untuk membangun representasi data. Demikian pula, perwakilan IRC harus menyediakan metode yang perlu diterapkan oleh pelaksana IWriter untuk mengekspor representasi data ke format file ekspor yang diminta.
Dengan asumsi data dalam file Anda bersifat tabular, IReader dan antarmuka pendukungnya dapat terlihat seperti:
IReader = interface(IInterface)
function MoveNext: Boolean;
function GetCurrent: IRow;
end;
IRow = interface(IInterface)
function MoveNext: Boolean;
function GetCurrent: ICol;
end;
ICol = interface(IInterface)
function GetName: string;
function GetValue: Variant;
end;
Iterasi di atas meja akan menjadi masalah
while Reader.MoveNext do
begin
Row := Reader.GetCurrent;
while Row.MoveNext do
begin
Col := Row.GetCurrent;
// Do something with the column's name or value
end;
end;
Karena representasi dapat berupa gambar, grafik, dan tekstual, presentasi IR mungkin akan memiliki metode yang mirip dengan IReader untuk melintasi tabel yang dikonstruksi dan akan memiliki metode untuk mendapatkan gambar dan grafik, misalnya sebagai aliran byte. Terserah pelaksana IWriter untuk menyandikan nilai tabel dan byte gambar / grafik seperti yang dipersyaratkan oleh target ekspor.