这个API可以改进吗?

Cha*_*ion 3 c# api refactoring

在我们的CORE库中,我们将此类作为20,000行抽象提供.你能看出它的设计方式有什么问题吗?

注1:此类具有SharpZipLib支持.

注2:SharpZipLib约为20K线.

public static class Compression
{
    public static Byte[] CompressBytes(Byte[] input);
    public static Byte[] CompressBytes(Byte[] input, Format format);
    public static Byte[] CompressBytes(Byte[] input, Format format, Level level);

    public static Byte[] DecompressBytes(Byte[] input);
    public static Byte[] DecompressBytes(Byte[] input, Format format);

    public static String CompressString(String input);
    public static String CompressString(String input, Format format);
    public static String CompressString(String input, Format format, Level level);

    public static String DecompressString(String input);
    public static String DecompressString(String input, Format format);

    public static void CompressFile(String input_file_path, String output_file_path);
    public static void CompressFile(String input_file_path, String output_file_path, Format format);
    public static void CompressFile(String input_file_path, String output_file_path, Format format, Level level);

    public static void DecompressFile(String input_file_path, String output_file_path);
    public static void DecompressFile(String input_file_path, String output_file_path, Format format);

    public static void CompressFolder(String input_folder_path, String output_file_path);
    public static void CompressFolder(String input_folder_path, String output_file_path, Format format);
    public static void CompressFolder(String input_folder_path, String output_file_path, Format format, Level level);

    public static void DecompressFolder(String input_file_path, String output_file_path);
    public static void DecompressFolder(String input_file_path, String output_file_path, Format format);
}
Run Code Online (Sandbox Code Playgroud)

jri*_*sta 11

我建议将这个单独的类分成几个类.一般来说,静态实用程序类会破坏很多规则,其中最重要的是分离关注点.虽然是,但是这个类中的所有方法都处理压缩,它们关注的是压缩不同的东西.一些压缩字节数组,一些压缩字符串,一些压缩文件.我会将这个单一实用程序分解为多个实用程序

public static class ByteCompression
{
    public static Byte[] Compress(Byte[] input);
    public static Byte[] Compress(Byte[] input, Format format);
    public static Byte[] Compress(Byte[] input, Format format, Level level);

    public static Byte[] Decompress(Byte[] input);
    public static Byte[] Decompress(Byte[] input, Format format);
}

public static class StringCompression

    public static String Compress(String input);
    public static String Compress(String input, Format format);
    public static String Compress(String input, Format format, Level level);

    public static String Decompress(String input);
    public static String Decompress(String input, Format format);
}

public static class FileCompression
{
    public static void Compress(String input_file_path, String output_file_path);
    public static void Compress(String input_file_path, String output_file_path, Format format);
    public static void Compress(String input_file_path, String output_file_path, Format format, Level level);

    public static void Decompress(String input_file_path, String output_file_path);
    public static void Decompress(String input_file_path, String output_file_path, Format format);
}

public static FolderCompression
{
    public static void Compress(String input_folder_path, String output_file_path);
    public static void Compress(String input_folder_path, String output_file_path, Format format);
    public static void Compress(String input_folder_path, String output_file_path, Format format, Level level);

    public static void Decompress(String input_file_path, String output_file_path);
    public static void Decompress(String input_file_path, String output_file_path, Format format);
}
Run Code Online (Sandbox Code Playgroud)

上述实用程序类减少了重复,更好的封装目的,与其成员方法更具凝聚力,并且意图更清晰.您确实有四种静态实用程序类型而不是一种,但您并没有以这种方式破坏尽可能多的规则/最佳实践.尽量避免单片,do-everything实用程序类.如果可以的话,找到一种方法来使它们成为实例类而不是静态类,特别是如果在每个压缩/解压缩方法中使用的类级别存在任何共享数据.这将提高线程安全性.

编辑:

正如andy评论的那样,更理想的实现将使用扩展方法.文件和文件夹压缩作为扩展实现起来有点困难,但我已经尝试过了.以下示例更好地实现了我的目标:将名词(或主题)与动词(或操作)分离,提供更清晰的API,最终重复次数更少,保持关注点分离,并且被正确封装.

public static class ByteCompressionExtensions
{
    public static byte[] Compress(this byte[] input);
    public static byte[] Compress(this byte[] input, Format format);
    public static byte[] Compress(this byte[] input, Format format, Level level);

    public static byte[] Decompress(this byte[] input);
    public static byte[] Decompress(this byte[] input, Format format);
}

// In use:
byte[] myArray = new byte[] { ... };
byte[] compArray = myArray.Compress();
// Subject (noun) -----^      ^----- Operation (verb)


public static class StringCompressionExtensions
{
    public static byte[] Compress(this string input);
    public static byte[] Compress(this string input, Format format);
    public static byte[] Compress(this string input, Format format, Level level);

    // Extension method fail!! :( :( This conflicts with Decompress from the class above!
    public static string Decompress(this byte[] input);
    public static string Decompress(this byte[] input, Format format);
}

// In use:
string myStr = "A string!";
byte[] compArray = myStr.Compress();
// Subject (noun) ---^      ^----- Operation (verb)
myStr = compArray.Decompress(); // Fail! :(


public static class FileCompressionExtensions
{
    public static void Compress(this FileInfo input, FileInfo output);
    public static void Compress(this FileInfo input, FileInfo output, Format format);
    public static void Compress(this FileInfo input, FileInfo output, Format format, Level level);

    public static void Decompress(this FileInfo input, FileInfo output);
    public static void Decompress(this FileInfo input, FileInfo output, Format format);
}

// In use:
FileInfo myFile = new FileInfo(input_file_path);
FileInfo myCompFile = new FileInfo(output_file_path);
                 myFile.Compress(myCompFile);
// Subject (noun) --^      ^----- Operation (verb)
                 myCompFile.Decompress(myFile);


public static class FolderCompressionExtensions
{
    public static void Compress(this DirectoryInfo input, DirectoryInfo output);
    public static void Compress(this DirectoryInfo input, DirectoryInfo output, Format format);
    public static void Compress(this DirectoryInfo input, DirectoryInfo output, Format format, Level level);

    public static void Decompress(this DirectoryInfo input, DirectoryInfo output);
    public static void Decompress(this DirectoryInfo input, DirectoryInfo output, Format format);
}

// In use:
DirectoryInfo myDir = new DirectoryInfo(input_folder_path);
DirectoryInfo myCompDir = new DirectoryInfo(output_folder_path);
                 myDir.Compress(myCompDir);
// Subject (noun) --^      ^----- Operation (verb)
                 myCompDir.Decompress(myDir);
Run Code Online (Sandbox Code Playgroud)

  • 如果您打算按类型拆分它,我会完全放弃API并通过Extension方法实现所有功能,所以SomeString.Compress(),SomeBytes.Compress()等. (4认同)
  • @ChaosPandion:我认为你仍然会误解我试图提出的观点.您将关注分类为"压缩".这是一个非常广泛的问题,您可以将大量功能集中到该标签下的单个静态类中.尝试从更精细的粒度看它:字节数组压缩,字符串压缩,文件和文件夹压缩.许多架构归结为如何分类事物.你的分类不能过于宽泛,但正如你所指出的那样,你也不能太精细.找到合适的平衡点,您将获得收益. (2认同)

Jam*_*ack 5

VS2010有一个明显的改进,你可以在这里有可选参数.

另一件可能有用的事情是提供扩展方法,以便我可以这样做:input_folder_path.CompressFolder(output_file_path).DecompressFolder(outputfile);

这将允许我压缩,然后解压缩压缩的内容以验证压缩.

如果我想压缩文件夹并将其放在与输入文件路径相同的级别,为什么我必须指定输出文件呢?

因此,如果我执行CompressFolder(@"C:\ input_folder")并保留它,那么它将使用C:作为输出路径.