Scanner Programm



  • Guten Morgen Community.

    Ich habe in C# .NET einen Barcode Scanner programmiert. Dieser kriegt Informationen von dem Scanner, welchen den Barcode ausließt (die Artikelnummer des Produkts) und schaut, ob das Produkt im Lieferschein enthalten ist.
    Außerdem wird während der Bearbeitung des Lieferscheins eine Save Datei erstellt. Die erstelle ich, damit wenn das Programm abstürzt, oder das Programm versehentlich geschlossen wird, was auch immer, abgespeichert wird, welche Produkte schon gescannt wurden und bei erneutem Laden des Lieferscheins alle bereits gescannten Produkte immer noch gescannt sind.
    Diese Datei sieht so aus:

    84968 2
    18234 1
    38567 5
    

    Die erste Zahl ist die Artikelnummer, die 2 die gescannte Menge.
    Nun kam die Änderung rein, dass ein Artikel mehrmals in einem Lieferschein auftauchen kann. Das heißt, eine Artikelnummer kann mehr als einmal vorkommen.
    Ich benutze jedoch ein Dictionary

    public class SaveManager
    {
        public Dictionary<string, string> Products { get; private set; }
    }
    

    Da kommt jeweils die Artikelnummer und die gescannte Menge rein. Lasst euch nicht verwirren das dort 2 mal String steht, es hat einen Grund. Ich hatte vorgeschlagen einfach beide Artikel, mit der gleichen Artikelnummer, zu einem einzigen zu machen und die Liefermenge einfach zusammen zu addieren. Leider geht das nicht, weil die Produkte jeweils verschiedene Empfänger haben können, sich jedoch den gleichen Lieferschein teilen (z.B. Arbeiter in einer Firma).
    Aufjedenfall darf ein Key nicht mehr als einmal in einem Dictionary vorkommen und ich stehe jetzt hier vor einem Problem. Ich müsste wirklich das komplette Programm umschreiben, was ich nicht möchte. Ich greife in meinem Programm mehrmals auf den SaveManager zu, nicht nur zum abspeichern, benutze mehrmals Dictionary und KeyValuePairs. Ich müsste also nicht nur Änderungen in dem SaveManager vornehmen.
    Hat irgendjemand vielleicht eine elegante Lösung?

    Mit freundlichen Grüßen,
    Freaky



  • Merk dir zum Key doch nicht die Anzahl sondern eine Liste von Anzahlen.



  • Hallo,

    die Änderung auf

    List<KeyValuePair<string, string>>
    

    dürfte aber nicht so viel Arbeit machen.
    Und wenn du dein Programm von Anfang an auf Interfaces (anstatt dem direkten Datentyp Directory) getrimmt hättest, wäre es wohl noch weniger Arbeit.
    Ergo: besser also

    IList<KeyValuePair<string, string>>
    

    als Schnittstelle nach außen benutzen (den Setter hast du ja schon richtigerweise auf private gesetzt).

    Alternativ such einfach mal nach "c# MultiDictionary", da gibt es einige Implementierungen im Netz.



  • Beiß in den sauren Apfel und refactore Dein Programm. Du hast ein Implementierungsdetail einer Klasse öffentlich zugänglich gemacht und kriegst nun die Quittung dafür. (Es tut überhaupt nichts zur Sache, dass "Products" ein Property ist. Da ist nichts mehr zu retten weil die Kapselung gebrochen ist)

    Ich hatte zwar erst die Frickellösung, dass Du ein class MultiDictionary : IDictionary {} implementierst und Products zu diesem Typen änderst. Aber das hilft Dir auch nicht weiter, weil alle Zugriffe im Anwendungscode die Semantik eines gewöhnlichen Dictionaries erwarten.



  • Hallo und danke für eure Antworten.
    Ich befolge doch lieber den Rat von µ und strukturiere es lieber neu, als dirty code zu benutzen.
    Ich habe es jetzt so gelöst, dass ich auf die interne Position der Produkte zugreife und weniger mit den Artikelnummern selbst.
    Meine Save Datei sieht jetzt so aus:

    83195 2 1
    12345 6 2
    83195 3 3

    2 Produkte haben die gleiche Artikelnummer, aber nicht die gleiche interne Position.
    Dafür habe ich eine neue Klasse erstellt

    public class SaveProductInfo
    {
        public string ProductNumber { get; private set; }
        public int Position { get; private set; }
        public int Count { get; set; }
    }
    

    Davon habe ich dann eine Liste in meinem SaveManager.
    Produkte habe eine interne Position, die sie beim einlesen des Auftrags zugewiesen bekommen. Damit kann ich dann in der Liste nach dem richtigen Produkt, welche eine einzigartige Position hat, suchen und weiß somit welche Produktnummer wirklich gemeint ist.

    Mit freundlichen Grüßen,
    Freaky



  • Hi Freaky,

    wenn ich im Umgang mit Daten was gelernt habe, dann, dass es früher oder später kracht, wenn man "Positionen" als ID verwendet. Da wäre ja sogar eine GUID noch besser.

    Es scheint mir sowieso so, als würdest Du hier eine Minidatenbank nachprogrammieren. Du vertraust auch darauf, dass der Anwender die Artikel der Reihe nach scannt, oder? Was passiert wenn irgendein Komiker die Artikel in beliebier Reihenfolge einscannt?


Log in to reply