2010-10-08 47 views
2

我正在编写一些代码来执行某些操作,而且我非常肯定它目前没有很好的设计,但我无法考虑应该如何重构它才能使它更好...用于创建一组数据对象的设计模式

简单的总结是,我有一些代码通过目录结构中的一些文件,不同的目录包含不同的内容类型。我有这些内容类型的数量有限,而且目前我有一个内容类型的对象,我只是创造了很多添加到列表的方式,例如如下:

 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个班级,所有这些班级从来没有改变过他们的信息,而且从来没有任何一点超过一个。这对于一个班级来说并不是同样的权利(我知道关于单身人士,但是听说如果你正在使用他们,你可能会错误地把它搞错)。在ContentType

2)Func财产我想,我可以设置在ContentType委托来处理GetNewFilename功能是不同的,但它仍然那么凌乱的感觉在上述方式生成它们。

3)工厂类

我以前从来没有(据我所知)使用工厂类,但我知道他们是用于生成类。我对他们的阅读表明,这种模式被用于生成不同的子类型,而不仅仅是一组类的实例。

4)配置文件

的数据,因为我有它上面可以全部放在一个配置文件或数据库或东西,然后装起来并循环到更为很好(这只是刚刚发生在我生成它)但是它仍然不能解决变化的方法的问题。我不确定我可以轻松地将代理放置在配置文件中。 :)

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 
} 

如果你想要这个类是如何使用,那么请问,我可以将其粘贴在,但我不想淹没在代码中,我没想到类的更多细节是相关的。

这只是一个代码使用(将文件移动到适当的目录放在一个新的网站,并确保他们正确命名),所以最好的代码并不重要,但它会去bug我if我至少不知道我应该做什么。如果正确的方式看起来会花很长时间(例如从头开始重写代码),那么我不会打扰,但至少我会知道下一次。 :)

P.S.我现在也意识到,建立一个或两个构造函数来设置这些初始值并使它们只读是一个适当的修改,但它仍然不能解决我所有的问题。

回答

2

有你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 
    } 
} 
+1

这就是我最终想要结束的。感谢您的建议。 :) – Chris 2010-11-05 14:14:47

1

要考虑的另一种模式可能是接口或抽象类。是的,你有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"; 
     } 
    } 
1

对于#4,您可以使用Unity或StructureBuilder等IoC容器。那么对于第二部分提供了一个类:

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; 
    } 
} 

,那么你可以实例化无论是在配置还是在运行时你的内容类型列表。

相关问题