Methoden Mehrere ähnliche Methoden zusammenfassen

Hallo zusammen,

ist es möglich diese Methoden zu einer Methode zusammenzufassen?
Java:
    private static void appendCountry(String country) {
        checkAndAppendConcatenator();
        urlString += "country="+country;
    }
    private static void appendYear(int year) {
        checkAndAppendConcatenator();
        urlString += "year="+year;
    }
    private static void appendYear(String year) {
        appendYear(Integer.parseInt(year));
    }
    private static void appendCredentials() {
        checkAndAppendConcatenator();
        urlString += "api_key=...";
    }
Da ich noch Neuling bin, würde ich gerne nur wissen, ob das überhaupt geht und wenn ja, wie würde das aussehen.

Grüße
 
Das einzige, was du machen kannst (und solltest), ist anzugucken, welches gleichartige Verhalten du aus den Methoden herausziehen und in eine Methode auslagern kannst. Z.B. geht jede Methode davon aus, dass es ein "urlString" Feld gibt und jede Methode definiert nochmal, wie man da etwas konkateniert. Das sollte man in eine separate Methode refactoren:
Java:
private static void appendCountry(String country) {
  appendKeyValue("country", country);
}
private static void appendCredentials() {
  appendKeyValue("api_key", "...");
}
private static void appendYear(String year) {
  appendKeyValue("year", year);
}

private static void appendKeyValue(String key, String value) {
  checkAndAppendConcatenator();
  urlString += key + "=" + value;
}
 
@mihe7 Es geht mir hierbei nur um das Verständnis. Ich bin der Meinung, dass was ich gepostet habe, die wahrscheinlich saubere Variante ist :D
Dennoch möchte ich gerne wissen, wie ich das evtl. zu einer Methode kürzen kann.

@httpdigest Danke für deine Antwort :)
 
Das reine appendKeyValue wäre die einzelne Methode. Eine Methode, welche nur einen weiteren Methodenaufruf enthält. ist aus meiner Sicht kein Mehrwert.

Daher wäre da die Zusammenfassung für mich einfach nur:

Java:
private static void appendKeyValue(String key, String value) {
  checkAndAppendConcatenator();
  urlString += key + "=" + value;
}
Wichtig noch als Hinweis: Ein wichtiger Punkt war für meine Entscheidung, dass die Methoden alle private sind! Ansonsten würde da dagegen sprechen, da man zum einen ein bestimmtes Interface wünscht (Da macht es dann Sinn, dass man in einer Methode einfach eine andere aufruft) und zum anderen man die Konstanten kapseln möchte. (Man setzt das Jahr und "year" wird als Konstante verwendet. Das ist evtl. etwas, das man kapseln möchte um für Veränderungen offen zu sein.)
 
Das geht mit einer Hilfs-Klasse relativ elegant:
Java:
	private static String urlString = "http://...";

	public static class HelperClazzWithFields {
		public String api_key;
		public String country;
		public int year;

		HelperClazzWithFields(String api_key, String country, int year) {
			super();
			this.api_key = api_key;
			this.country = country;
			this.year = year;
		}
	}

	public static void appendAll(HelperClazzWithFields h) throws IllegalArgumentException, IllegalAccessException {
		for (Field f : h.getClass().getFields()) {
			urlString += f.getName() + "=" + f.get(h);
		}
	}

	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
		appendAll(new HelperClazzWithFields("123", "de-DE", 2019));
		System.out.println(urlString);
	}
 
@mihe7 Ich möchte, wie du richtig vermutet hast, alles in einer Methode und das Zusammenfügen aller Teile zur URL.

Java:
    private static void appendCountry(String country) {
        checkAndAppendConcatenator();
        urlString += "country="+country;
    }
    private static void appendYear(int year) {
        checkAndAppendConcatenator();
        urlString += "year="+year;
    }
    private static void appendYear(String year) {
        appendYear(Integer.parseInt(year));
    }
    private static void appendCredentials() {
        checkAndAppendConcatenator();
        urlString += "api_key=...";
    }
    private static void checkAndAppendConcatenator() {
        if(urlString.contains("?")) {
            urlString += "&";
        }else {
            urlString += "?";
        }
    }
Tut mir leid ich habe die Methode checkAndAppendConcatenator vergessen mitzukopieren.
 
Ich würde das alles nicht zu einer einzigen Methode zusammenfassen.
Eine Methode, welche nur einen weiteren Methodenaufruf enthält. ist aus meiner Sicht kein Mehrwert.
Eine Methode ergibt nicht nur durch ihren Body/Inhalt Sinn, sondern auch durch ihren Namen. `appendCountry("DasLand")` finde ich sprechender als nur `appendKeyValue("country", "DasLand")`.
Außerdem erlaubt eine `appendCountry` Methode keine Verwendung eines falschen Keys, z.B. wie in `appendKeyValue("land", "DasLand")`.
 
Vielleicht sollte man tatsächlich mal zeigen, wie hässlich der Code aussehen würde... Im Prinzip verklausulierst Du jeden möglichen Methodenaufruf als boolean. Hier mal der Super-GAU: (Achtung, liebe Kinder: nicht Zuhause nachmachen :p)
Java:
public static void appendAll(boolean includeCountry, String country, 
        boolean includeCredentials, 
        boolean includeYearStr, String yearStr,
        boolean includeYearNo, int yearNo) {
    if (country != null) {
        url += "country=" + country; 
    }
    if (includeCredentials) {
         url += "api_key=...";
    }
    if (includeYearStr) {
         url += "year=" + yearStr;
    }
    if (includeYearNo) {
         url += "year=" + yearNo;
    }
}
 
Wenn es noch mehr Parameter sind, fühlt sich das wie ein Builder an. Nehmen wir an, am Ende kommt der Typ Url raus, dann würde ich eine API schaffen, die vielleicht so was macht:

Java:
Url url = new Url.Builder().country(county).year(year).creditials().build();
 
Ich würde das alles nicht zu einer einzigen Methode zusammenfassen.

Eine Methode ergibt nicht nur durch ihren Body/Inhalt Sinn, sondern auch durch ihren Namen. `appendCountry("DasLand")` finde ich sprechender als nur `appendKeyValue("country", "DasLand")`.
Außerdem erlaubt eine `appendCountry` Methode keine Verwendung eines falschen Keys, z.B. wie in `appendKeyValue("land", "DasLand")`.
Dem kann ich folgen, aber ich sehe halt, dass es hier um reine private Methode geht:
- Ich habe keine Kapselung, daher eben auch generell die Möglichkeit, falsche Keys zu verwenden.
- Anstatt hier solche zusätzlichen Funktionen einzubauen, würde ich eher das Design überdenken. (Das ist wohl auch etwas, worauf mihe7 hinaus wollte und wo @Ullenboom einen konkreten Vorschlag unterbreitet hat.)

Das Erste, was ich auf jeden Fall machen würde: Die String-Konstanten als Konstanten hinterlegen (Egal ob als String Konstanten oder in Form einer Enumeration). Dadurch hat man die Gefahr des Verschreibens nicht mehr. Und bezüglich Verständnis, was ein Code macht, sehe ich nicht wirklich einen großen Unterschied außer eben der Länge:
Code:
appendCountry("germany");
appendParameter(API_KEY_COUNTRY, "germany");
Klar gibt es Feinheiten - Ist einem bei appendCountry klar, dass es um einen Parameter geht, der gesetzt wird? Der Kontext ist halt nicht gegeben, daher ist es schwer, das als Ganzes zu bewerten.

Und so bleibt es dann wohl Ansichtssache, was wer bevorzugt.
 
Du solltest die Methoden getrennt lassen. Ihr Name gibt ihnen den Sinn - du bist dabei "clean code" zu verschenken, wenn du das anders machst.

Du kannst für diese Methoden viel einfacher Tests schreiben, als wenn du es in einer großen Methode machst. Denk mal daran, was passieren würde, wenn du noch 10 so appends in einer Methode machst... das wird schnell unübersichtlich
 
Du kannst für diese Methoden viel einfacher Tests schreiben, als wenn du es in einer großen Methode machst. Denk mal daran, was passieren würde, wenn du noch 10 so appends in einer Methode machst... das wird schnell unübersichtlich
Also man sollte den gemeinsamen Code schon heraus ziehen - also so wie in #3 bei @httpdiggest.
Damit habe ich eine Methode, für die ich Tests schreiben muss. Daher kann ich das Argument mit den einfacheren Tests nicht wirklich nachvollziehen. Durch zusätzliche Methoden, die diese Methode nutzen, entfällt ja nicht die Verpflichtung, diese Methode ordentlich zu testen.

Und wenn noch viel mehr so Parameter kommen, dann ist das in meinen Augen noch viel mehr ein Argument dafür, das Design zu überdenken und spricht noch viel mehr, gegen eben diese Lösung mit vielen Methoden. Wie sehr wird denn dann die eigene Klasse aufgebläht? Die Klasse wird ja noch irgendwas sinnvolles nach Außen machen und somit nicht nur private Elemente umfassen?

Und dieses Design zu diskutieren macht auch relativ wenig Sinn: Ein Design mit "private static void" Methoden, die einen static Kontext (urlString wird ja ein private static Variable des Klasse sein) verändern? Das bitte im Kopf behalten. Ich habe bereits in meinem ersten Post darauf hingewiesen, dass so eine zusätzliche Methode Sinn machen kann - aber doch bitte nicht so in diesem Umfeld.

Ein Builder Pattern wäre quasi die gleiche Version wie die des TEs, nur halt in schön. :D
Nein, ist sie nicht. Du hast die Version vom TE nicht korrekt verstanden. Siehe meinen Hinweis zu dem private static void Methoden und dem veränderten statischen Kontext.
 
Nein, ist sie nicht. Du hast die Version vom TE nicht korrekt verstanden. Siehe meinen Hinweis zu dem private static void Methoden und dem veränderten statischen Kontext.
Ja und Du hast die Grundlagen der SE noch nicht verstanden... Du hast zu diesem Thema genau 0 beigetragen.

Noch als Nachtrag: Er hat nicht danach gefragt, ob es sinnvoll wäre den statischen Kontext zu verändern. Von daher ist das eine reine Offtopic-Diskussion.
 
Zuletzt bearbeitet:
Ja und Du hast die Grundlagen der SE noch nicht verstanden... Du hast zu diesem Thema genau 0 beigetragen. Lies doch mal ein Buch (gern auch das von @Ullenboom ) und in einem Jahr können wir diese Diskussion dann erneut führen. :)
Lieber Tobias,

Man kann bezüglich Clean Code gerne unterschiedlicher Meinung sein. Wenn man sich ernsthaft damit beschäftigt, dann findet man auch oft viele Unterschiede. Ich würde hier aber oft nicht zwingend eine Bewertung vornehmen. Und ich befürchte, dass Du auch in einem Jahr nicht in der Lage sein wirst, eine Diskussion zu führen. Du bist doch offensichtlich nicht in der Lage, sachlich zu bleiben.

Aber zurück zur Sache:
Du bist also wirklich der Meinung, dass ein Builder prinzipiell gleich zu setzen ist mit dieser "private static" Lösung die der TE gebracht hat? Dann bau mal mit der Lösung des TE parallel zwei URLs auf. Bei @Ullenboom wäre dies möglich.
Aber evtl. kann @Ullenboom ja dazu etwas schreiben? Vielleicht liege ich ja komplett falsch....
 
Also deine Frage kann ich klar beantworten: Ja, ich kann lesen.

Aber ich finde es lustig, dass Du diese Aussage wiederholst. Vielleicht solltest Du einmal schauen, ob das wirklich "quasi die gleiche Version" ist.

Also zumindest die Builder Pattern, die ich so kenne und wie ich diese einsetze lassen es zu, dass man mehrere Builder parallel nutzt. Kann man auch bei @Ullenboom recht schön erkennen:
new Url.Builder()
Es werden Instanzen von einer Builder Klasse gebaut.
Wenn man sich dem gegenüber nun die "static" Lösung des TE anschaut ....

Hier nun klar: Dir geht es offensichtlich nicht um eine sachliche Auseinandersetzung.
 
Wow Leute, ich wollte hier keine Streitereien auslösen :D

Ich versuche mich lediglich im Programmieren zu verbessern und wollte eure Meinung hören, was denn die sauberste Lösung wäre. Das jeder seinen eigenen Programmierstil besitzt, ist mir durchaus klar :)
Ich habe die Methoden zuerst getrennt gehalten alleine wegen der meiner Meinung nach besseren Übersicht und wie eingangs schon erwähnt bin ich noch lange nicht (wenn überhaupt) so gut wie ihr was programmieren/entwickeln angeht.

Ich werde einfach mal eure Vorschläge versuchen und schauen was dabei rauskommt ;)
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben