簡體   English   中英

用於創建一組數據對象的設計模式

[英]Design Pattern for creating a set of data objects

我正在寫一些代碼來做一些事情,我很確定目前它的設計還不錯,但是我不認為我應該如何重構它以使其更好。

簡單的摘要是,我有一些代碼遍歷目錄結構中的某些文件,並且不同的目錄包含不同的內容類型。 這些內容類型數量有限,目前,我正在創建一個內容類型對象,該對象將以如下方式添加到列表中:

        contentTypes.Add(new ContentType { ContentName = "2010 Call Report", FolderName = "2010 Reports", RenameFile = false });
        contentTypes.Add(new ContentType { ContentName = "2010 Email Report", FolderName = "2010 Reports", RenameFile = false });
        contentTypes.Add(new ContentType { ContentName = "Above Average Call Recording", FolderName = "Call Recordings", RenameFile = true, HasMultiple = true });
        contentTypes.Add(new ContentType { ContentName = "Below Average Call Recording", FolderName = "Call Recordings", RenameFile = true, HasMultiple = true });

這確實感覺不對(總共11行幾乎完全相同的代碼),但是我無法想到我還應該做什么。

ContentType類包含一些可以在上面看到的屬性以及一個名為GetNewFilename公共方法。 當前, GetNewFilename方法非常簡單,並由所有內容類型共享。 但是,我現在想讓一些ContentType對象擁有自己的此方法版本。

我考慮過的事情是:

1)子類ContentType為每種內容類型創建一個類

這對我來說似乎不對,因為我有11個班級,所有這些班級都永遠不會改變他們的信息,並且擁有一個以上的班級從來沒有任何意義。 這對於一堂課來說是不對的(我了解單身人士,但聽說如果您使用單身人士,那肯定是錯的)。

2) ContentType上的Func屬性

我認為我可以在ContentType上設置一個委托以處理與GetNewFilename函數不同的問題,但是以上述方式生成它們仍然感到混亂。

3)工廠課程

據我所知,我以前從未使用過Factory類,但是我知道它們用於生成類。 我對它們的閱讀表明,此模式用於生成不同的子類型,而不僅僅是一組類的實例。

4)配置文件

我上面擁有的數據都可以放入配置文件或數據庫之類的東西中,然后加載並循環遍歷以更好地生成它(這只是在我身上發生),但仍不能解決問題變化的getNewFilename方法。 我不確定是否可以輕松地將委托放入配置文件中。 :)

5)在一個類上具有所有不同的getNewFileName方法

我可以讓內容類擁有我想要的所有不同方法,並使用某種選擇來選擇正確的方法。 不過,這似乎似乎也遺漏了一點。

那么,有人可以建議一個很好的方法嗎?

這是我的ContentType類的當前簽名(已刪除邏輯-詢問您是否認為其相關)。

public class ContentType
{
    public string ContentName { get; set; }
    public string FolderName { get; set; }
    public bool RenameFile { get; set; }
    public bool HasMultiple { get; set; }

    public string GetNewFilename(string originalFilename, int fileIndex)
    {...} // This method needs to do diffent things for different contenttypes
}

如果您想了解有關如何使用此類的更多詳細信息,請詢問,我可以將其粘貼進去,但我不想用我認為不相關的代碼來淹沒該類。

這僅用於一次使用的代碼(將文件移動到適當的目錄以放置在新網站上並確保正確命名),因此,可能的最佳代碼不是至關重要的,但如果我不這樣做,它將給我帶來麻煩至少知道我應該怎么做。 如果正確的方法看起來會花費太長時間(例如,從頭開始重寫代碼),那么我不會打擾,但至少下次我會知道的。 :)

PS我現在也意識到,一個或兩個構造函數來設置這些初始值並將它們設置為只讀將是一個適當的更改,以使其更加整潔,但仍然不能解決我的所有問題。

讓您的ContentType類為基類,並使GetNewFilename方法為虛擬方法。 ContentType類派生每個可能需要在GetNewFilename方法中進行特殊處理的文件類型,並覆蓋虛擬實現。 然后,當在目錄搜索中找到需要特殊處理的文件類型時,只需根據需要創建那些繼承類的實例,否則只需創建ContentType類的實例即可。

public class ContentType
{
    public virtual string GetNewFilename(string originalFilename, int fileIndex)
    {
        // get file name here
    }
}

public sealed class SpecialContentType : ContentType
{
    // Inherrits all the properties of ContentType

    public override string GetNewFilename(string originalFilename, int fileIndex)
    {
        // get special file name here
    }
}

要考慮的另一種模式可能是接口或抽象類。 是的,您將有11個班級,但這不一定是一件壞事。 它可以使您的關注點清晰地分開,同時仍提供一個通用框架。

如果GetFileName在幾種情況下以相同的方式工作,則可以使用虛擬GetFileName方法實現抽象類。 這將限制您必須編寫的新代碼量,僅在必要時覆蓋:

public abstract class ContentType
    {
        public string ContentName { get; set; }
        public string FolderName { get; set; }
        public bool RenameFile { get; set; }
        public bool HasMultiple { get; set; }

        public virtual string GetFileName()
        { 
            //Base GetFileName implementation
            return "filename";
        }
    }

對於#4,您可以使用IoC容器,例如Unity或StructureBuilder。 然后為第二部分提供一個類:

public interface INewFilenameService {
  string FileName {get;set;}
}

public class ContentType {
    private INewFilenameService newFilenameService;

    public ContentType(INewFilenameService service) {
        this.newFilenameService = service;
    }

    public string ContentName { get; set; }
    public string FolderName { get; set; }
    public bool RenameFile { get; set; }
    public bool HasMultiple { get; set; }

    public string GetNewFilename() {
      return service.Filename;
    }
}

那么您可以在配置中或在運行時實例化內容類型列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM