Frage

Ich habe eine dumme, kleine Klasse "Dateisystem"Das kann sowohl als Objekt als auch über öffentliche, statische Methoden verwendet werden. Die Ausgabe ist ähnlich, aber jeweils nicht identisch.

Die Klasse war intensiv statisch, aber ich habe die Möglichkeit hinzugefügt, es als Objekt zu initialisieren, um sich mit neu zu verlängern. "Komfortmethoden"In zukünftigen Versionen, ohne dass eine Menge Parameter analysiert werden muss. Zum Beispiel habe ich Getkbstring (), Getmbstring (), etc ... Methoden, mit denen die Dateigröße so formatiert wird, wie ich sie möchte (als Zeichenfolge). Intern speichert die Klasse die Datei -Byte -Größe als Doppel.

Ich bin ein bisschen verwirrt, wenn dies überhaupt sinnvoll ist. Es scheint, als sollte ich dies vielleicht in eine statische Version und eine Objektversion wie Microsoft für Verzeichnis und Verzeichnis und DirectoryInfo teilen. Es scheint mir jedoch einfacher zu sein, alles an einem Ort mit einem Namen zu haben, der nicht falsch ist - es sollte klar sein, was Dateisysteme tut? Gibt es Auswirkungen auf die Wartung, die ich nicht erwarte? Was ist das für ein Geruch?

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");
War es hilfreich?

Lösung

Schauen Sie es sich anders an: Warum setzen Sie String/Nummer/UI -Formatierungsmethoden in Ihre Dateisystem -Methode ein?

Während es in Bezug auf Dateien verwendet werden kann, ist dies ein allgemeines Stück Funktionalität, das IMHO an anderer Stelle in einer gut organisierten Bibliothek gefunden werden sollte. Genau wie die Pfadfunktionen nicht Teil der Datei- oder Verzeichnisklassen in .NET sind, würde ich das setzen Methoden "eine Nummer formatieren" in einer String- oder Maths -Utils -Klasse.

Trennen Sie die Verantwortlichkeiten Ihrer Objekte und Sie können feststellen, dass in solchen Fällen keine statischen und nicht statischen Mitglieder gemischt werden müssen.

Andere Tipps

Ein guter Test: Wenn Sie sich und uns fragen, ob es in Ordnung ist, besteht die Möglichkeit, dass dies nicht der Fall ist.

Für Benutzer der Klasse ist es möglicherweise nicht selbstverständlich, einige Methoden über die Klasse und andere über Objekt zugänglich zu machen, insbesondere wenn die zweite die Instanzeigenschaften der Klasse nicht wirklich benötigt. Wahrscheinlich werden sie verwirrt sein und sich auf wie: "WTF dieser Programmierer hat das getan?!".

Ich schlage vor, mit allen Instanzmethoden zu gehen, wenn Ihnen die Möglichkeit gefällt, die Klasse entweder mit Erweiterungsmethoden oder durch Subklassierung zu erweitern.

Ist dies nicht der perfekte Kandidat für Erweiterungsmethoden?

Ich würde persönlich Erweiterungen zur Formatnummern als Dateigröße bereitstellen und eine verwenden enum Um anzugeben, wie die Dateigrößen formatiert werden:

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

Wenn Sie C# 3.0 verwenden, werden Ihre Absichten möglicherweise besser mit Erweiterungsmethoden und AFORMATPROVIDER ausgedrückt. In Code könnte dies eine Erweiterungsmethode für die Methoden "Dateiinfo-" und DirectoryInfo -ToString -Methoden sein, sodass sie so etwas lesen würden:

var directorySize = myDirectory.ToString("GB");
var fileSize = myFile.ToString("MB");

Der obige Code fühlt sich für das, was Sie versuchen, natürlicher an.

Sehen Sie, wie das Folgende für Sie funktioniert. Einige davon müssen getestet werden (die rekursive Methode DirectoryInfoextender.getDirectorySize fällt in den Sinn). Wenn Sie in der Lage sein müssen, Aussagen wie zu schreiben wie Console.WriteLine("{0:GB}", fileInfo), Sie können auch in Betracht ziehen, einen AFORMATPROVIDER zu schreiben.

Beachten Sie auch, dass ich absichtlich Nullprüfungen und Ausnahmebehandlung für diese öffentlich zugänglichen Methoden überzogen habe.

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

Standardgeruch ist die Verwendung statischer Methoden - dies macht es schwierig, beizubehalten, falls Sie diese Methoden in Ihrem gesamten Code anwenden.

Ein weiterer Geruch imho ist: Klassenname ist nicht klar, was er tatsächlich tut. Aus Ihrer Beschreibung soll es Daten formatieren. In diesem Fall würde ich sie im Klassennamen erwähnen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top