สำหรับฉันวิธีที่จะไปคืออินเทอร์เฟซและโรงงาน หนึ่งที่ส่งกลับการอ้างอิงไปยังอินเทอร์เฟซซึ่งคลาสต่าง ๆ สามารถซ่อน คลาสที่ทำงานเสี้ยงฮึดฮัดทำจริงทั้งหมดต้องลงทะเบียนกับ Factory เพื่อที่จะได้รู้ว่าคลาสใดที่จะสร้างอินสแตนซ์ให้กับชุดของพารามิเตอร์
หมายเหตุ: แทนที่จะใช้อินเทอร์เฟซคุณสามารถใช้คลาสพื้นฐานที่เป็นนามธรรมได้ แต่ข้อเสียเปรียบคือสำหรับภาษาที่สืบทอดเดี่ยวจะ จำกัด คุณไว้ที่คลาสฐานเดียว
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) เนื่องจากเป็นภาษาที่ฉันคุ้นเคยมากที่สุด
หลังจากลงทะเบียนคลาสที่ใช้งานทั้งหมดกับโรงงานแล้วคุณควรจะสามารถร้องขอการอ้างอิงส่วนต่อประสานกับอินสแตนซ์ของคลาสดังกล่าวได้ ตัวอย่างเช่น:
Factory.GetReader('SomeFileName.xml');
Factory.GetWriter('SomeExportFileName.ppt');
Factory.GetRepresentation(rtTable, 'html');
ควรส่งคืนการอ้างอิง IReader ไปยังอินสแตนซ์ของ TXMLReader การอ้างอิง IWriter ไปยังอินสแตนซ์ของ TPowerPointWriter และการอ้างอิง IRPresentation กับอินสแตนซ์ของ THTMLTable
ตอนนี้ทุกเอ็นจิ้นการเรนเดอร์ต้องทำคือผูกทุกอย่างเข้าด้วยกัน:
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 ควรจัดเตรียมวิธีการในการอ่านข้อมูลที่ต้องการโดยผู้พัฒนา IRPresentation เพื่อสร้างการแสดงข้อมูล 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 เพื่อเข้ารหัสค่าตารางและไบต์ภาพ / กราฟตามที่เป้าหมายการส่งออกต้องการ