Mam algorytm, który tworzy kolekcję obiektów. Obiekty te można modyfikować podczas tworzenia, ponieważ zaczynają od bardzo małej liczby, ale następnie zapełniane są danymi w różnych miejscach algorytmu.
Po zakończeniu algorytmu obiekty nie powinny być nigdy zmieniane - jednak są one zużywane przez inne części oprogramowania.
Czy w tych scenariuszach dobrą praktyką jest posiadanie dwóch wersji klasy, jak opisano poniżej?
- Zmienny jest zatem tworzony przez algorytm
- Po zakończeniu algorytmu dane są kopiowane do niezmiennych obiektów, które są zwracane.
Odpowiedzi:
Być może możesz użyć wzorca konstruktora . Wykorzystuje oddzielny obiekt „konstruktora” w celu zebrania niezbędnych danych, a po zebraniu wszystkich danych tworzy rzeczywisty obiekt. Utworzony obiekt może być niezmienny.
źródło
Prostym sposobem na osiągnięcie tego byłoby posiadanie interfejsu, który pozwala czytać właściwości i wywoływać metody tylko do odczytu oraz klasę, która implementuje ten interfejs, co pozwala również na pisanie tej klasy.
Twoja metoda, która go tworzy, zajmuje się tym pierwszym, a następnie zwraca ten drugi, zapewniając tylko interfejs tylko do odczytu do interakcji. Nie wymagałoby to kopiowania i pozwala łatwo dostroić zachowania, które mają być dostępne dla dzwoniącego, a nie dla twórcy.
Weź ten przykład:
Jedyną wadą tego podejścia jest to, że można go po prostu rzucić na klasę wdrażającą. Gdyby to była kwestia bezpieczeństwa, samo zastosowanie tego podejścia jest niewystarczające. Obejściem tego problemu jest to, że można utworzyć klasę elewacji, aby owinąć klasę zmienną, która po prostu przedstawia interfejs, z którym program wywołujący współpracuje i nie może mieć dostępu do obiektu wewnętrznego.
W ten sposób nawet casting nie pomoże. Oba mogą wywodzić się z tego samego interfejsu tylko do odczytu, ale rzutowanie zwróconego obiektu da ci tylko klasę Fasada, która jest niezmienna, ponieważ nie zmienia stanu podstawowego opakowanej klasy zmiennej.
Warto wspomnieć, że nie jest to zgodne z typowym trendem, w którym niezmienny obiekt jest budowany raz na zawsze za pośrednictwem jego konstruktora. Zrozumiałe, że możesz mieć do czynienia z wieloma parametrami, ale powinieneś zadać sobie pytanie, czy wszystkie te parametry muszą zostać zdefiniowane z góry, czy też niektóre mogą zostać wprowadzone później. W takim przypadku należy zastosować prosty konstruktor z tylko wymaganymi parametrami. Innymi słowy, nie używaj tego wzorca, jeśli ukrywa on inny problem w twoim programie.
źródło
Możesz użyć wzorca Konstruktora, jak mówi @JacquesB, lub alternatywnie zastanów się, dlaczego tak naprawdę twoje obiekty muszą być modyfikowalne podczas tworzenia?
Innymi słowy, dlaczego proces ich tworzenia musi być rozłożony w czasie, w przeciwieństwie do przekazywania wszystkich wymaganych wartości do konstruktora i tworzenia instancji za jednym razem?
Ponieważ Konstruktor może być dobrym rozwiązaniem niewłaściwego problemu.
Jeśli problem polega na tym, że otrzymujesz konstruktor o długości około 10 parametrów i chcesz go złagodzić, budując obiekt stopniowo, może to oznaczać, że projekt jest pomieszany, a te 10 wartości powinno mieć wartość „ spakowane "/ pogrupowane w kilka obiektów ... lub główny obiekt podzielony na kilka mniejszych ...
W takim przypadku - trzymaj się niezmienności przez cały czas, po prostu popraw projekt.
źródło