Laden...

Forenbeiträge von dani_m Ingesamt 13 Beiträge

03.09.2010 - 11:27 Uhr

Singleton sollte man nicht mehr verwenden dafür gibt es das Monostate Pattern

Singleton vs Monostate

Außerdem sollte man wenn man Equals überschreibt auch GetHashCode überschreiben.
Richtlinien für das Überschreiben von Equals und ==

Außerdem bei ValueTypes sollte man immer die Equals Methode überschreiben...

If you are implementing a value type, you should consider overriding the Equals method to gain increased performance over the default implementation of the Equals method on ValueType. If you override Equals and the language supports operator overloading, you should overload the equality operator for your value type.

02.09.2010 - 11:26 Uhr

Ja und warum nimmst du dann hier eine statische Methode wenn du selbst sagst das es nicht gut ist. Du wiedersprichst dich damit selbst.

Ich unterstelle nichts ich sag nur was geht und was nicht geht. Außerdem befinden wir uns hier in einem C# Forum also denke ich in C# weil das hier ein C# Forum ist 😉

02.09.2010 - 11:15 Uhr

Das ist nicht Test-Driven. Wenn es TestDriven wäre würdest du wissen das ne statische Factory nicht Testbar ist. Du kannst ne statische Methode nur Testen was geht rein und was kommt raus. Das Verhalten was du mittels Mock machen würdest kannst du bei einer statischen Methode nicht testen.

Mit mir kann man sachlich diskutieren. Nur wenn ich schon höre ich hab das schnell hingehackt ist das nicht sachlich.

Was ist wenn einer deiner asserts fehlschlägt (wenn du jemand bist der in einer TestMethode mehrere Asserts schreibt)? Wie findest du raus welcher es ist?

02.09.2010 - 10:53 Uhr

So und wie testest du ohne Datenbank???

Zwei Asserts in einer TestMethode ist nicht gut. Wenn herbivore schon meckert wegen inderektion warum nehmt ihr dann eine Factory her. Statische Factory - lieber herr gesangsverein da schreib mal deinen Test dazu.

Kommt jetzt der Ansatz das man statische Methoden testen kann?

Außerdem ist das nicht Testgetrieben entwickelt.

Das was du da als einen Testfall beschreibst sind mehere Testfälle.

List beinhaltet mehrere Länder -> 1. Testfall
List beinhaltet nur ein Land -> 2. Testfall
List beinhaltet eine leere Liste -> 3. Testfall

Außerdem zwei listen kannst du mittels SequenceEqual vergleichen.

Außerdem einfach hin gehackt wenn ich sowas schon höre...

02.09.2010 - 09:08 Uhr

Genau das macht man aber bei Pair Programming. Man achtet gegenseitig auf guten qualitativ hochwertigen code. Das die Regeln eingehalten werden usw. das ist der Sinn von Pair Programming. Hier würde ich dir mal das Buch von Uncle Bob (Robert C. Martin) empfehlen (Agile Principles, Patterns and Practices in C#). Hier wird eine Beispielaufgabe mitttels Pair Programming gelöst und da stellen sich die Entwickler gegenseitig immer die Frage ist das Sinnvoll was du da implemtierst. Denk an die Verantwortlichkeiten usw...

Qualitativ hochwertiger Code wird nicht mehr mittels Lines of Code gemessen sondern mittels Codemetriken, Abhängigkeiten usw. Wie würdest du zu den anderen Versionen einen Test schreiben? Das würde mich brennend interessieren.

Ich habe in meiner Version die Redundanzen beseitigt. Das war die Aufgabe und die hab ich gelöst.

Ich weiß wie Test First funktioniert. Ich arbeite mit diesem Ansatz. Kannst du das Verhalten einer Methode da Testen mittels Mocken also ich find in den anderen Versionen keinen Ansatz das zu testen.

Wenn du mir eine brauchbare TestMethode zeigst für die anderen Versionen dann bin ich ruhig.

@herbivore zu deinem Statement

Abstraktion hat unbestreitbare Vorteile, aber sie bringt eben fast immer auch zusätzliche Indirektion. Indirektion kostet uns Menschen leider zusätzlichen Aufwand, wenn man verstehen will, wie die Abläufe sind

Ja es hat Vorteile und die hab ich hier aufgezeigt. Die Abläufe lassen sich durch aussagekräftige Namen der Methoden leichter verstehen. Die Methoden sind bzgl Verantwortlichkeiten getrennt. Also alles in allem leichter Verständlich. Diesen Code kann jeder Entwickler lesen. Er weiß sofort was passiert hier, durch aussagekräftige Namen. Wie du auch sagtest hab ich in der Version die Redundanzen beseitigt. Das war auch die Aufgabe. Wie ich oben schon sagte wird die Qualität von Code nicht mittels Lines of Code gemessen.

01.09.2010 - 17:20 Uhr

Sind das jetzt deine Argumente? Mein Code beseitigt die Redundanz wie du selbst schon sagtest. Er ist Simple. Jeder Entickler kann ihn lesen. Da es kleine Methoden sind mit prägnanten Namen die jeder auf Anhieb lesen kann. Ich weiß echt nicht was daran bitte schlecht ist. Performance ist auch besser, da der Compiler hier inline Methoden draus macht wie ich weiter oben schon erklärt habe. Ich kann an einer Stelle z.B. ändern das ich die Daten jetzt in einer DataGridView anzeigen will oder in einem TreeView.

01.09.2010 - 16:37 Uhr

Wenn ihr nur die zwei Prinzipien befolgen wollt na gut. Ich halt mich an ein bisschen mehr und ja mein code ist länger aber sagen nicht auch die Jungs von GoF das der Code durch Design Patterns länger wird dafür umso besser, lesbar, wartbar, erweiterbar...

Es gibt leider mehr als nur 2 Prinzipien die man beachten sollte auch wenn man nicht XP macht. Wenn einer hier aber schon auf Prinzipien herumhacken will na gut dann mach ich das auch. Test First Ansatz und da fängt man unweigerlich mit kleinen prägnanten Methoden an. So und was ist daran bitte nicht Simple? Methoden die mehr als 5 Zeilen Code haben ist schon zuviel. Das kann keiner mehr auf einen Blick erfassen. Oder schreibt ihr Methoden die Länger sind? Dann brauch ich gar ned mit Prinzipien zu diskutieren anfangen.

Uncle Bob (ObjectMentor) sorry ich hab geglaubt deine Prinzipien sind wichtig und sollten beachtet werden. Hier habe ich erfahren es gibt nur 2 Prinzipien die ich befolgen soll...

01.09.2010 - 15:50 Uhr

Wie würdest du denn dieses Entwickeln? Test First? Somit müsstest du kleine Methoden schreiben. Testbare kleine Methoden. Wenn du schon mit KISS und YAGNI arbeitetst dann ist das sicherlich XP. XP setzt Tests vorraus. Kleine prägnante Methoden...

Single Responsibility bezieht sich in der Definition auf Klassen ja aber trotzdem sollte ich nicht in einer Methode zwei Grundlegende Verantwortlichkeiten mischen.

Open/Closed Principle besagt nur das ein System geschlossen vor Veränderungen sein muss und offen für Erweiterungen. Des heißt nicht das des nur mit Ableitung geht --> Favour Composition over Inheritance.

01.09.2010 - 13:30 Uhr

Und gegen was verstößt dein Ansatz?

Single Responsibility Principle
Open/Closed Principle

Klar hast du nur eine Änderung an der Methode weil du nur eine Methode hast.
Diskutieren ist ja wohl erlaubt. Ich lass mich auch eines besseren beleheren.

Aber Keep it Simple bedeutet nicht das ich nur eine Methode habe in der ich mehrere Verantwortlichkeiten habe.

01.09.2010 - 13:13 Uhr

@FZelle

Man sollte sein aktuelles Design niemals auf dem basieren was evtl mal alles kommen könnte, sondern nur auf dass was kommen wird --> Erweiterbarkeit??? Ist die Erweiterbarkeit nicht der Grundsatz der Objektorientierten Programmierung? In alten Prozedualen Sprachen hätte ich mir das erwartet aber nicht in einer Objektorientierten.

Was ist daran bitte nicht Simple? Ich brechs lediglich in Methoden auf. Somit bin ich erweiterbar was in den anderen Version nicht möglich ist.

In software design, change is constant...

01.09.2010 - 11:58 Uhr

Hallo Herbivore,

zu 1. Die Testbarkeit ist hier zwar gegeben solang sich nix ändert ob ich alles anzeigen will oder nicht.

zu 2. Laufzeit-Unterschiede spielen natürlich eine Rolle. Bei der Entwicklung muss man schon aufpassen was guter Code und was schlechter Code ist.
Switch-Anweisungen werden beispielsweise niemals Inline vom Compiler gemacht. If-Else schon solange die Methode nicht größer als 32 bytes beträgt.

zu 3. Klar aber bei mir ist die Änderung nur in der Methode

private static void FillCountries(FirebirdEmbedded fb) {
            List<Country> g = fb.getCountries(true);
            
            SelectOnlyCountriesWithStartName("A",g);
            
            AddItemsToListBox(g);


}

zu 4. Ich habe hier nur die DataSource verwendet da Sie vom Ersteller vorgegeben war. Ich würds niemals verwenden weil ich weiß wie oft sich ein Kunde umentscheidet das er das oder das jetzt angezeigt haben will.

Deine 10 Zeilen sind hier solang wartbarer solang sich nix ändert aber wehe der Kunde will was anderes dann musst unweigerlich in Methoden aufbrechen.

01.09.2010 - 11:32 Uhr

Hallo Herbivore,

Klar ist das Möglich aber ich würde hier definitiv mit ausgelagerten Methoden arbeiten. Erstens sind die Methoden Testbar, was in deiner Version nicht zu machen ist, zweitens der Compiler arbeitet später mit Inline Methoden somit spar ich mir unnötigen Code zur Laufzeit.
Drittens was ist wenn du später etwas nicht anzeigen willst was mir z.B. von fb.getCountries zurückkommt?

Viertens würd ich definitiv nicht über eine DataSource arbeiten. Wer sagt mir den das ich immer alle Felder anzeige die von der DB zurückkommen. Nichts ist so sicher wie die Veränderung in der Softwareentwicklung.

01.09.2010 - 11:06 Uhr

Also ich würde hier mit Methoden arbeiten. Rein deswegen um die Lesbarkeit des Codes zu verbessern und dient auch der Wartbarkeit.

 
using (FirebirdEmbedded fb = new FirebirdEmbedded())
{
                if (comboBox1.SelectedIndex == 0)
                {
                    FillCategories(fb);
                }
                else if (comboBox1.SelectedIndex == 1)
                {
                    FillCountries(fb);
                }
                else if (comboBox1.SelectedIndex == 2)
                {
                    FillLanguages(fb);
                }
}

private static void FillLanguages(FirebirdEmbedded fb) {
            List<Language> g = fb.getLanguages(true);
            AddItemsToListBox(g);
          
}

private static void FillCountries(FirebirdEmbedded fb) {
            List<Country> g = fb.getCountries(true);
            AddItemsToListBox(g);
            
}

private static void FillCategories(FirebirdEmbedded fb) {
            List<Category> g = fb.getCategories(true);
            AddItemsToListBox(g);
          
}

private static void AddItemsToListBox(List<Object> g) {
           
           if(g!=null){
            listBox1.DataSource = null;
            listBox1.Items.Clear();

            listBox1.DataSource = g;
            }
}

Anstelle von List<Object> g (Parameter AddItemsToListBox) wäre hier ein BaseTyp für alle möglichen sicherlich besser.