Modyfikacja mutowalnego obiektu w metodzie.

0

Witam. Chciałbym się dowiedzieć jakie jest wasze podejście do modyfikacji obiektu wewnątrz metody. Załóżmy, że mamy klasę:

class CalcModel {
	private long timeInActiveInMillis;
	private long timeInPauseInMillis;
	private int percentInActive;
	private int percentInPause;
	// inne zmienne i gettery, settery
}

Mam też metodę, która wykonuje obliczenia na tym obiekcie modyfikując jego właściwości, jednak ta metoda nic nie zwraca.

public void calculate(CalcModel calcModel) {
	// tutaj wykonujemy różne operacje na modelu, którego go modyfikują, np.
	calcModel.setTimeInActiveInMillis(millis);
}

Czy takie podejście jest dobre czy lepiej zmodyfikować metodę aby coś zwracała?

public CalcModel calculate(CalcModel calcModel) {
	// tutaj wykonujemy różne operacje na modelu, którego go modyfikują, np.
	calcModel.setTimeInActiveInMillis(millis);
	return calcModel;
}

Może operować na kopii obiektu w metodzie a zwróconą wartość przypisać do właściwego obiektu?

public CalcModel calculate(CalcModel calcModel) {
	CalcModel modifiedCalcModel = new CalcModel(calcModel) // lub calcModel.copy();
	// tutaj wykonujemy różne operacje na modelu, którego go modyfikują, np.
	modifiedCalcModel.setTimeInActiveInMillis(millis);
	return modifiedCalcModel;
}

a potem:

calcModel = calculate(CalcModel calcModel);

Jakie jest waszym zdaniem najlepsze podejście do takiego zagadnienia? Modyfikować przekazany argument i nic nie zwracać z metody? Modyfikować przekazany argument i go następnie zwracać? Czy może operować na kopii przekazanego argumentu a dopiero zwracany wynik po obliczeniach przypisywać do właściwego obiektu?

1

Tak naprawdę nie ma to aż tak wielkiego znaczenia - najbardziej istotnym elementem tutaj jest nazewnictwo metod. Jak nazwa metody dobrze opisze co w środku robi, to wtedy może zwracać bądź nie zwracać tego obiektu.

2

Jeżeli jest tak jak myśle i obiekt początkowo ma ustawione **tylko **niektóre właściwości, a dopiero calc() ustawia pozostałe to taka klasa dowodzi wcielenia zła:

//Wcielenie zła
class CalcModel {
    private long timeInActiveInMillis;
    private long timeInPauseInMillis;
    private int percentInActive;
    private int percentInPause;
    // inne zmienne i gettery, settery
}

Powinienes raczej mieć

class Messdaten {
    private long timeInActiveInMillis;
    private long timeInPauseInMillis;
}
class Ergebnisse {
 private int percentInActive;
    private int percentInPause;
}

oraz metodę

public Ergebnisse calculate(Messdaten data) {
[...]
}

Wtedy wszystko będzie jasne.

Dodatkowo Ergebnisse może zawierać lub dziedziczyć po Messdaten.
Sorry za niemieckie nazwy- ale nie chciałem Ci narzucać nazw - nie wiem co tak naprawdę potrzebujesz( a dodatkowo kod po niemiecku ma +2 do bycia full professional.)

Ganeralnie obiekt po przejściu prze konstruktor powinien zawsze być "skonstruowany" - czyli wszystkie publiczne pola i i metody powinny być wywoływalne. Nie powinno być tak, że "puszczasz w świat" obiekt, który jest "w połowie zainicjalizowany" i niektórych metod i pól nie można używać, bo trzeba najpierw coś jeszcze wywołać. Bo ktoś o tym w końcu zapomni,
to jest po prostu kiepski/niebezpieczny kontrakt.

A poza tym polecam robienie gdzie się da niemutowalnych obiektów. To znacznie ułatwia życie.
Twój przykład idelanie do immutowalnego "ValueObjecta" pasuje.

0

Przykład jest totalnie abstrakcyjny. Ten obiekt początkowo w moim założeniu miał być zainicjalizowany a metoda calculate po prostu miała obliczać czas aktywności i w pauzie i %, ale tak jak napisałem przykład tylko na potrzeby tego posta. Chodziło mi bardziej o przekazywanie obiektu do metody, która może go modyfikować i jak najlepiej napisać taką metodę. Czy tworzenia metody, która modyfikuje oryginalny obiekt i nie zwraca nic nie jest mylące? Bo jakby nie patrzeć zmieniamy obiekt wykonujemy na nim operacje a nie zwracamy, żadnego wyniku.

1

Czy tworzenia metody, która modyfikuje oryginalny obiekt i nie zwraca nic nie jest mylące?

Jest mylące. Najlepiej void-ów unikać - tak jak mutowalności.

1 użytkowników online, w tym zalogowanych: 0, gości: 1