Frage

sagen, ich habe eine Reihe von Benutzersteuerelementen, jede Usercontrol in einem TabItem, innerhalb eines Fensters.

Nehmen wir zum Beispiel sagen, dass dies ein Lebensmittel Sammlung Anwendung. Dann haben wir Tabs Obst, Gemüse und Snacks. Jede Registerkarte wird eine Liste von Lebensmitteln diesem Thema zeigen, und ermöglichen es dem Benutzer hinzufügen, löschen, ändern Sie die Lebensmittel in jedem Abschnitt. Das Essen wird in separaten Textdateien gespeichert, das heißt Fruit.txt, Vegetable.txt, Snack.txt

Die eigentlichen Textdateien, so etwas wie diese (vegetable.txt) aussehen:

Name        Carbs    Fat
Eggplant    2        1.1
Cucumber    3        0.5
etc

Nun ist dies eine große Liste, und es gibt eine Lademethode, die alle das Gemüse aus in eine List

zieht

Die Frage, die ich habe, ist diese Methode loadVegetables in der Code-behind-Datei, und ich Wiederholung diese Lademethode ganz über den Platz am Ende, weil ich eine andere von anderen Bildschirmen wie ReviewAllFood habe, AddVegetable usw. zusammen mit all den anderen Lademethoden für Obst und Snacks.

Dies ist eher ein Design Frage, ich frage mich, wie ich das einrichten, um diesen Code nicht wiederholen. Ich könnte einen VegetableManager (oder etwas) Klasse, wo die Last-Methode ist, aber ist dies tatsächlich bedeutet weniger wiederholt Code? Dann in jedem Bildschirm habe ich Gegenstand von VegetableManager zu schaffen und seine Last Methode ohnehin nennen. Also ich denke, Effizienz weise seine nicht besser, aber ich habe ein besseres Design erreichen.

Ich denke, dass ich hier etwas fehlt bin. Es ist schon eine Weile her, seit ich studiert Zusammenhalt und Kupplung, und ich denke, dass ich mich im Moment mit diesen Konzepten bin verwirrend. Freuen, wenn jemand einen Entwurf für diese Situation könnte vermuten lassen, und erklären, warum sie es gewählt haben und warum es ist besser als wie ich es im Moment mache.

Vielen Dank für das Lesen.

War es hilfreich?

Lösung

  

Ich könnte einen VegetableManager (oder   etwas) Klasse, wo die Lademethode   ist, aber ist dies tatsächlich bedeuten weniger   wiederholt Code? Dann in jedem Bildschirm I   zum Erstellen von Objekt   VegetableManager und rufen seine Last   Verfahren trotzdem.

Der Punkt dabei ist, nicht Effizienz (das heißt Leistung). Der Punkt ist, die Details des Ladens, dass Daten in ein einziges isoliertes Objekt zu verkapseln. Sagen Sie zum Beispiel, dass Ihre Website wirklich groß wird und Sie sich entscheiden, die Datenspeicherung in einer Datenbank für Skalierbarkeit und Leistung zu bewegen. In dem vorhandenen Code, wie Sie beschrieben, werden Sie durch die einzelnen Benutzersteuerung oder Seite und ändern Sie die Logik der Load-Methode gehen. Am besten ist dies ein Schmerz, und im schlimmsten Fall einig verpassen oder copy-paste falsch. Wenn die Logik in ein eigenes Objekt gekapselt ist, deren einzige Aufgabe ist es zu wissen, wie die Daten von irgendwo zu laden, dann müssen Sie nur einmal die Änderung vornehmen.

Code-Behind der Benutzersteuerung:

protected void Page_Load(object sender, EventArgs e) {
  var veggieManager = new VegetableManager();
  VeggieListControl.DataSource = veggieManager.GetAll();
  VeggieListControl.DataBind();
}

VegetableManager.cs:

public class VegetableManager {
  private static Collection<Vegetable> _veggies;
  private static object _veggieLock;

  public ReadOnlyCollection<Vegetable> GetAll() {
    if (_veggies == null) {
      lock(_veggieLock) { //synchronize access to shared data
        if (_veggies == null) { // double-checked lock
          // logic to load the data into _veggies
        }
      }
    }

    return new ReadOnlyCollection(_veggies);
  }

  public void Add(Vegetable veggie) {
    GetAll(); // call this to ensure that the data is loaded into _veggies
    lock(_veggieLock) { //synchronize access to shared data
      _veggies.Add(veggie);
      // logic to write out the updated list of _veggies to the file
    }
  }
}

Da _veggies static ist, gibt es nur eine Sammlung von Gemüse in Erinnerung, trotz der Tatsache, dass mehrere Anrufer VegetableManager instanziiert werden. Aber weil es statisch, wenn Sie eine Multi-Threaded-Anwendung haben (zum Beispiel einer Website) Sie Zugriff auf das Feld über alle Threads synchronisieren müssen (daher die locks).

Dies ist die Spitze des Eisbergs in Bezug auf gute Objektorientierung. Ich empfehle Durchlesen UncleBob SOLID Prinzipien und Domain-Driven Design ( kostenloses E-book ).

So Ja, Sie etwas wiederholen, aber alles, was Sie zu wiederholen ist ein Methodenaufruf , und die Ordnung zu wiederholen ist. DRY Mittel, um die Duplizierung von „logischen“ -Code, d.h. Entscheidungsverfahren und Algorithmen zu mildern; einfache Methode Anrufe unter dieser nicht fallen. Allerdings, wenn Sie möchten, können Sie Logik in einer Basisklasse konsolidieren tun dies, effektiv die Bedienelemente Isolierung mit etwa VegetableManager wissen, obwohl ich denke, das ist die Objektorientierung Overkill oder OOO: -)

public abstract class FoodUserControl : UserControl {
  protected List<Vegetable> GetVeggies() {
    return new VegetableManager().GetAll();
  }
}

Dann ist Ihre tatsächlichen Kontrollen daraus ziehen würden statt von Usercontrol.

Aktualisieren

Eager-Loading VegetableManager.cs:

public class VegetableManager {
  private static Collection<Vegetable> _veggies;
  private static object _veggieLock;

  static VegetableManager() {
    // logic to load veggies from file
  }

  public ReadOnlyCollection<Vegetable> GetAll() {
    return new ReadOnlyCollection(_veggies);
  }

  public void Add(Vegetable veggie) {
    lock(_veggieLock) { //synchronize access to shared data
      _veggies.Add(veggie);
      // logic to write out the updated list of _veggies to the file
    }
  }
}

Beachten Sie diese eifrig-Laden-Version muss nicht doppelt checked im Konstruktor um die Last-Code sperren. Beachten Sie auch, dass der Last-Code in einem static Konstruktor ist, da dieser Code ein static Feld initialisiert (sonst würden Sie auf jedem Bau in das gleiche gemeinsame static Feld, um die Daten aus der Datei werden Nachladen). Da Gemüse eifrig geladen sind, müssen Sie nicht in GetAll oder hinzufügen zu laden.

Andere Tipps

Ich würde vorschlagen, das Gemüse ziehen (oder was auch immer es ist, du bist Laden) aus einmal, wenn Sie die Datei lesen. Dann speichern Sie sie in einem zugrunde liegenden Datenmodell. Sie können die Liste binden, und was auch immer andere Steuerelemente, die Sie brauchen, um auf das darunter liegende Datenmodell. Die Daten werden einmal geladen, aber verschiedene Ansichten können es angezeigt werden soll.

EDIT: Hinzufügen von Code

List<T> loadObjects(File file, ILineConversionStrategy strategy) {
   // read eaqch line of the file
   // for each line
   T object = strategy.readLine(line);
   list.add(object);
   return listOfObjects;
}

EDIT 2: Datenmodell

class FoodModel {
   List<Vegetable> getVegetables();
   List<Fruit> getFruit();
   // etc
}

würde ich das Repository-Muster für diesen. Als Anfang Erstellen einer Klasse enthält Methoden, um die Objekte aus jeder Textdatei abgerufen werden:

public class FoodRepository
{
    public IList<Vegetable> GetVegetables() { ... }
    public IList<Fruit> GetFruit() { ... }
    // etc.
}

Diese Klasse sollte die einzige Klasse in der Anwendung sein, die sich bewusst ist, dass Lebensmittel in Textdateien tatsächlich gespeichert werden.

Sobald Sie, dass Sie arbeiten könnte Caching häufig verwendete Daten berücksichtigen wollen zur Verbesserung der Leistung.

    public interface IEatable {}

    class Vegitable : IEatable 
    { string Name { get; set; } }
    class Fruit : IEatable 
    { string Name { get; set; } }

    public interface IEatableManager
    {
        List<Vegitables> LoadEatables(string filePath);
    }
    public class VetabaleManager : IEatableManager
    {
        #region IEatableManagerMembers    
        public List<Vegitable> LoadVegs(string filePath)
        {
            throw new NotImplementedException();
        }    
        #endregion
    }
    .
    .
    .

Es gibt mehrere Dinge, die Sie für die Verwendung einer Konstruktion wie oben

beachten müssen

und ein Muss lesen:

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