2015-12-11 53 views
0

我做了一個類來生成2個類似但卻非常不同的報表。爲此,我使用了我在此處找到的模式:https://stackoverflow.com/a/29907649/3410196 它使用抽象基類,它包含帶有公共構造函數的私有派生類,所以其他代碼實際上不會訪問派生類的構造函數,並且只能使用static Create()方法創建對象。具有私人派生類的抽象類:實現一些方法

現在我面臨一個問題: 一切工作正常,我可以導出報告等,但現在我已經能夠出口的報告一個以不同的格式。有沒有什麼辦法可以讓這個方法通過基類只爲那個派生類訪問?否則,我將不得不throw new NotImplementedException()或強迫我的用戶使用這樣的事情:

//Is actually multiReport (multireport:report) 
Report report = Report.Create(...); 
MemoryStream stream = (report as multireport).ExportOtherFormat(); 

我懷疑這是可能的,但也許有辦法!

+3

創建一個類,其職責是導出報告。例如,你可以有一個CSV導出器,一個XML導出器等。該類將把你的報表基類作爲參數。報告的創建和導出可能是兩個獨立的責任,所以他們應該分屬不同的類別。 –

+0

事實上,我應該從一開始就這樣實施它,那會更好。但是現在已經太晚了,因爲太多的應用程序已經在使用我的庫了。獲得的經驗我猜 –

+0

難道你不能只是添加另一種方法到你的庫,需要一個IExporter作爲參數?然後,您可以創建一些出口商,然後您的圖書館的用戶可以通過傳遞相應的出口商實施說明他們希望如何導出?例如,公共無效出口(IExporter出口商) –

回答

0

所有我去一個解決方案之後(也許不是最好的),使一個的類公共和揭露這樣的方法,但又不希望它在其他子類:

abstract class Report 
{ 
private Report() {} 

public abstract MemoryStream ExportPDF() { ... } 

public class ReportA : Report 
{ 
    public ReportA() { ... } 
    public override MemoryStream ExportPDF() {...} 
    public MemoryStream ExportCSV() {...} 
} 

private class ReportB : Report 
{ 
    public ReportB() { ... } 
    public override MemoryStream ExportPDF() {...} 
} 

public static Report Create() { ... } 
} 

現在只有一個子類有方法ExportCSV()並顯示它。現在人們可以調用構造函數來創建一個sublcass A,但是,我不太喜歡

1

由於外部用戶創建基類的實例(即basereport,而不是multireport),因此無法爲其中一個子類提供可見的方法。他們將無法致電ExportOtherFormat,除非他們知道他們正在查看multireport的實例,而不是basereport

解決此問題的一種方法是隱藏用戶的格式決定。製作格式的enum,使ExportWithFormat方法,它有它:

[Flags] 
enum ReportFormat { 
    Simple = 1 
, Extended = 2 
, Special = 4 
, Multifile = 8 
} 

這些屬性和方法添加到基類:

public ReportFormat AvailableExportFormats { get {... } } 

public MemoryStream ExportWithFormat(ReportFormat format); 

現在你Multireport可以返回的特殊標誌的額外格式它在AvailableExportFormats中支持,並且在ExportWithFormat方法中將該標誌傳回給它時產生正確的導出。

+0

這將工作,但我有其他的報告類也實現我的PDF和Excel界面,所以它會變得不一致。我想我沒有別的選擇。 Darren的工廠理念是我應該從一開始就實施的,但現在有點太遲了。 –

0

如果我理解正確的話,你需要類似的東西,使ReportB將提供新的實現導出方法:

abstract class Report 
{ 
    private Report() {} 

    public virtual MemoryStream Export() { ... } 

    private class ReportA : Report 
    { 
     public ReportA() { ... } 
    } 

    private class ReportB : Report 
    { 
     public ReportB() { ... } 
     new public virtual MemoryStream Export() { ... } 
    } 

    public static Report Create() { ... } 
} 
+0

如果我這樣做,如果我創建一個這樣的報告,即使它是一個ReportA它仍然會顯示方法 –

+1

我認爲你只需要另一個方法導出的實現。如果你需要一個單獨的方法 - 我認爲@DarrenYoung提出的建議將是最好的選擇。 –

+0

是的,當我開始這個項目時應該多想一想 –

相關問題