クラス設計:クラスをオブジェクトとして使用できるようにし、パブリック静的メソッドも提供します
-
21-09-2019 - |
質問
私の授業は愚かで小さなクラスです」ファイルシステムのサイズこれはオブジェクトとしても、パブリックな静的メソッド経由でも使用できます。出力は似ていますが、それぞれのケースで同一ではありません。
クラスは 最初は静的, ですが、新しい " で拡張できるように、オブジェクトとして初期化する可能性を追加しました。便利なメソッド" 将来のバージョンでは、多くのパラメーター解析を必要とせずに使用できます。たとえば、私は GetKBString(), GetMBString(), 、など...希望どおりにフォーマットされたファイル サイズを (文字列として) 便利に取得できるようにするメソッド。内部的には、クラスはファイルのバイト サイズを double として格納します。
これが本当に意味があるのかどうか、私は少し混乱しています。Microsoft が Directory と DirectoryInfo に対して行っているように、これを静的バージョンとオブジェクト バージョンに分割する必要があるようです。ただし、これをすべて 1 か所にまとめて、間違いのない名前を付けた方が簡単に思えます。FileSystemSize が何をするかは明らかです。メンテナンスに関して予期せぬ影響はありますか?あの匂いは何ですか?
var mypath = @"C:\mypath";
var filesystemsize = new FileSystemSize(mypath);
string kilobytes = filesystemsize.GetKBString();
string megabytes = filesystemsize.GetMBString();
double bytes = filesystemsize.ByteSize;
double staticbytes = FileSystemSize.GetDirectoryBytesSize(new DirectoryInfo(mypath));
double statickilobytes = FileSystemSize.ConvertSize(staticbytes, "KB");
解決
別の方法でそれを見:なぜあなたはFileSystemSize方法でメソッドをフォーマット文字列/番号/ UIを入れている。
それはファイルに関して使用することができますが、、これは私見は、よく組織、ライブラリ内の他の場所で発見されるべきであるとの機能の一般的な作品です - パス関数は、.NETのファイルまたはディレクトリクラスの一部ではないと同じように、私は文字列または数学utilsのクラスで「番号をフォーマット」メソッドをかけることになります。
あなたのオブジェクトの責任を分離し、あなたはこのようなケースでは、静的および非静的メンバを混合する必要がないかもしれません。
他のヒント
良いテスト:あなたは、それは大丈夫ですか自分自身と私たちを求めているならば、そうでない可能性がある。
クラスのユーザーがオブジェクトを経由して、クラスなどを介してアクセスいくつかのメソッドを持っているため、これは、第二は本当にクラスのインスタンスのプロパティを必要としない場合は特に、自然ではないかもしれません。チャンスは、彼らが混同され、等を参照されます:「このプログラマはそれをしたWTF?!」
。可能性のようなあなたが拡張メソッドまたはサブクラスのいずれかを介して、クラスを拡張する場合、私はすべてのインスタンスメソッドと一緒に行くことをお勧めします。
あなたはFileSystemSize状態の多くを持っていないので、これは拡張メソッドのための完璧な候補ではないでしょうか?
私は個人的にファイルサイズの文字列としてフォーマット番号に拡張を提供し、ファイルサイズをフォーマットする方法を指定するenum
を使用すると思います:
public static class FileSystemSize
{
public static long GetDirectoryBytesSize(string path);
}
public static class NumberExtensions
{
public static string FormatAsFileSize(
this long fileSize, FileSizeStringFormat format);
}
public enum FileSizeStringFormat
{
KiloByte,
MegaByte,
}
、あなたの意図は、より優れた拡張メソッドとIFormatProvidersで表現することができます。彼らはこのような何かを読んでいましたように、コードでは、これは、FileInfoオブジェクトとDirectoryInfoのToStringメソッドの拡張メソッド可能性があります:
var directorySize = myDirectory.ToString("GB");
var fileSize = myFile.ToString("MB");
上記のコードは何をしようとするため、より自然に感じます。
あなたのためにどのように、次の作品を参照してください。それのいくつかは(再帰的な方法DirectoryInfoExtender.GetDirectorySizeが頭に浮かぶ)テストする必要があります。あなたはConsole.WriteLine("{0:GB}", fileInfo)
のような文を書くことができるようにする必要がある場合は、あなたも同様にするIFormatProviderを書いて考えるかもしれません。
またノート
public static class DirectoryInfoExtender
{
public static string ToString(this DirectoryInfo d, string format, int fractionalDigits)
{
double fileSize = GetDirectorySize(d);
return FileSizeConverter.GetFileSizeString(fileSize, format, fractionalDigits);
}
public static double GetDirectorySize(DirectoryInfo d)
{
var files = d.GetFiles();
var directories = d.GetDirectories();
if(files.Length == 0 && directories.Length == 0)
{
return 0;
}
else
{
double size = 0;
foreach(var file in files)
{
size += file.Length;
}
foreach(var directory in directories)
{
size += GetDirectorySize(directory);
}
}
return size;
}
}
public static class FileInfoExtender
{
public static string ToString(this FileInfo f, string format, int fractionalDigits)
{
return FileSizeConverter.GetFileSizeString(f.Length, format, fractionalDigits);
}
}
public class FileSizeConverter
{
public static string GetFileSizeString(double fileSize, string format, int fractionalDigits)
{
long divisor;
string sizeIndicator;
switch(format.ToLower().Trim())
{
case "gb":
divisor = (long)Math.Pow(2, 30);
sizeIndicator = "gigabytes";
break;
case "mb":
divisor = (long) Math.Pow(2, 20);
sizeIndicator = "megabytes";
break;
case "kb":
divisor = (long)Math.Pow(2, 10);
sizeIndicator = "kilobytes";
break;
default:
divisor = 1;
sizeIndicator = "bytes";
break;
}
return String.Format("{0:N" + fractionalDigits +"} {1}", fileSize / divisor, sizeIndicator);
}
}
標準の香りは、静的メソッドの使用である - 。これは、それは難しいあなたがすべてのコードの上にこれらのメソッドを使用する場合に維持することができます。
は別の香りの私見である:クラス名は、それが実際に何をするかについては明らかではありません。あなたの説明から、それは私がクラス名でそれを言及と思われる場合のフォーマットのデータに意味されます。