Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于创建一组数据对象的设计模式_C#_.net_Design Patterns - Fatal编程技术网

C# 用于创建一组数据对象的设计模式

C# 用于创建一组数据对象的设计模式,c#,.net,design-patterns,C#,.net,Design Patterns,我正在写一些代码来做一些事情,我很确定它目前设计得不好,但我想不出我应该如何重构它以使它更好 简单的总结是,我有一些代码,它遍历目录结构中的一些文件,不同的目录包含不同的内容类型。我有数量有限的这些内容类型,目前我有一个内容类型对象,我只是创建了很多,以如下方式添加到列表中: contentTypes.Add(new ContentType { ContentName = "2010 Call Report", FolderName = "2010 Reports", Renam

我正在写一些代码来做一些事情,我很确定它目前设计得不好,但我想不出我应该如何重构它以使它更好

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

        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) 工厂班

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

4) 配置文件

我上面的数据都可以放在配置文件、数据库或其他东西中,然后加载并循环生成它(这只是我刚刚想到的),但它仍然不能解决改变
getNewFilename
方法的问题。我不确定是否可以轻松地将委托放入配置文件中。:)

5) 在一个类上具有所有不同的getNewFileName方法

我可以让content类拥有我想要的所有不同的方法,然后使用某种select来选择正确的方法。不过,这似乎也有点偏离了重点

有人能提出一个好的方法吗

这是我的
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
}
这仅仅是一段代码(将文件移动到适当的目录,以便放在新网站上,并确保正确命名),所以最好的代码并不重要,但如果我不知道自己应该做什么,它会让我感到不安。如果正确的方法看起来会花费太长时间(如从头重写代码),那么我就不麻烦了,但至少下次我会知道的。:)


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

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

将您的
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
    }
}
对于#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;
    }
}

然后,您可以在配置或运行时实例化您的内容类型列表。

这就是我最后讨论的内容。谢谢你的建议。:)