Benim için, gidilecek yol arayüzler ve bir fabrika olurdu. Arkasında çeşitli sınıfların gizlenebileceği arabirimlere referanslar döndürülür. Gerçek homurdanma işi yapan sınıfların hepsinin Fabrikaya kayıtlı olması gerekir, böylece bir dizi parametre verildiğinde hangi sınıfın örnekleneceğini bilir.
Not: arayüzler yerine soyut temel sınıfları da kullanabilirsiniz, ancak dezavantajı tek miras dilleri için sizi tek bir temel sınıfla sınırlandırmasıdır.
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');
Delphi (Pascal) sözdiziminde kod olduğu için en tanıdığım dildir.
Tüm uygulayıcı sınıflar fabrikaya kaydedildikten sonra, böyle bir sınıfın örneğine bir arabirim referansı talep edebilmelisiniz. Örneğin:
Factory.GetReader('SomeFileName.xml');
Factory.GetWriter('SomeExportFileName.ppt');
Factory.GetRepresentation(rtTable, 'html');
bir TXMLReader örneğine bir IReader başvurusu döndürmelidir; TPowerPointWriter örneğine bir IWriter başvurusu ve THTMLTable örneğine IRepresentation başvurusu.
Şimdi tüm render motorunun yapması gereken her şeyi birbirine bağlamak:
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;
IReader arabirimi, verilerin temsilini oluşturmak için IRepresentation uygulayıcılarının ihtiyaç duyduğu verileri okumak için yöntemler sağlamalıdır. Benzer şekilde IRepresentation, IWriter uygulayıcılarının veri sunumunu istenen dışa aktarma dosya biçimine vermek için ihtiyaç duydukları yöntemleri sağlamalıdır.
Dosyalarınızdaki verilerin tablo halinde olduğunu varsayarsak, IReader ve destekleyici arayüzleri şöyle görünebilir:
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;
Bir masanın üzerinde tekrarlamak
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;
Temsiller görüntü, grafik ve metinsel nitelikte olabileceğinden, IRepresentation muhtemelen inşa edilmiş bir tablodan geçmek için IReader'a benzer yöntemlere sahip olacak ve örneğin bayt akışı gibi görüntü ve grafikleri elde etmek için yöntemlere sahip olacaktır. Dışa aktarma hedefinin gerektirdiği şekilde tablo değerlerini ve görüntü / grafik baytlarını kodlamak IWriter uygulayıcılarına bağlıdır.