저에게는 갈 길은 인터페이스와 팩토리입니다. 하나는 다양한 클래스가 숨길 수있는 인터페이스에 대한 참조를 반환합니다. 실제 grunt 작업을 수행하는 클래스는 모두 팩토리에 등록해야하므로 주어진 매개 변수 세트를 인스턴스화 할 클래스를 알 수 있습니다.
참고 : 인터페이스 대신 추상 기본 클래스를 사용할 수도 있지만 단일 상속 언어의 경우 단일 기본 클래스로 제한한다는 단점이 있습니다.
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 (파스칼) 구문으로되어 있습니다.
모든 구현 클래스가 팩토리에 등록되면 해당 클래스의 인스턴스에 대한 인터페이스 참조를 요청할 수 있어야합니다. 예를 들면 다음과 같습니다.
Factory.GetReader('SomeFileName.xml');
Factory.GetWriter('SomeExportFileName.ppt');
Factory.GetRepresentation(rtTable, 'html');
TXMLReader 인스턴스에 대한 IReader 참조를 리턴해야합니다. TPowerPointWriter 인스턴스에 대한 IWriter 참조 및 THTMLTable 인스턴스에 대한 IRepresentation 참조
이제 모든 렌더링 엔진은 모든 것을 하나로 묶습니다.
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 인터페이스는 IRepresentation 구현자가 데이터 표현을 구성하는 데 필요한 데이터를 읽는 메소드를 제공해야합니다. 마찬가지로 IRepresentation은 IWriter 구현자가 데이터 표현을 요청 된 내보내기 파일 형식으로 내보내는 데 필요한 메소드를 제공해야합니다.
파일의 데이터가 본질적으로 테이블 형식이라고 가정하면 IReader 및 지원 인터페이스는 다음과 같습니다.
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;
그런 다음 테이블을 반복하면 문제가됩니다.
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;
표현은 본질적으로 이미지, 그래프 및 텍스트 일 수 있으므로 IRepresentation은 아마도 구성된 테이블을 탐색하기 위해 IReader와 유사한 메소드를 가지고 있으며 이미지 및 그래프를 예를 들어 바이트 스트림으로 가져 오는 메소드를 가지고 있습니다. 내보내기 대상에 필요한대로 테이블 값과 이미지 / 그래프 바이트를 인코딩하는 것은 IWriter 구현 자에 달려 있습니다.