Właśnie zacząłem pisać nową klasę i przyszło mi do głowy, że dodałem wiele argumentów metod, które nie są ściśle potrzebne. Jest to zgodne z nawykiem unikania posiadania stanu w klasach, który jest specyficzny dla niektórych wywołań metod, a nie ogólnej konfiguracji lub zależności klasy.
Takie postępowanie oznacza, że wiele metod, które nie mogą mieć argumentów, kończy się na jednym, dwóch lub trzech.
Chciałbym usłyszeć twoje opinie na temat tego, co myślisz o tym kompromisie i jak decydujesz, które podejście wybrać w jakiej sytuacji?
Ponieważ opis kodu jest często łatwiejszy do zrozumienia niż angielski, stworzyłem małą treść, która zawiera oba warianty: https://gist.github.com/JeroenDeDauw/6525656
class-design
complexity
methods
parameters
cohesion
Jeroen De Dauw
źródło
źródło
Odpowiedzi:
Ponieważ jedyną widoczną z zewnątrz metodą w twoim przykładzie jest
updateTable
, myślę, że dobrze jest używać pól zamiast parametrów metody.Jeśli jest to część bardziej ogólnej klasy (np.
TableTools
), Przenosiłbym metody pomocnicze, które potrzebują stanu, do ukrytej klasy wewnętrznej.Przykład pseudokodu:
W ten sposób unikniesz pól używanych tylko przez jedną metodę publiczną. Ponadto kod jest bezpieczny dla wątków w tym sensie, że każde wywołanie updateTable używa własnej kopii TableUpdater, a zatem zmiennych instancji TableUpdater.
źródło
Korzystanie z pól pozwala na korzystanie z wielowątkowości dla metod wykorzystujących te pola.
Używanie takich pól jest tylko nieznacznie lepsze niż używanie globałów z punktu widzenia wielokrotnego użytku i konserwacji, kluczowym punktem tutaj jest to, że złożone konfiguracje wymagają starannej i aktualnej dokumentacji na temat tego, które metody używają i / lub zamykają, które pola; coś, czego nie musisz robić, używając argumentów.
źródło
Słowami laika:
Ponownie, moim skromnym zdaniem, niespójne metody należą do klasy użyteczności, a nie do klasy o nazwie domeny.
źródło
Nie używaj pól w bieżącym przypadku! Dwa „wątki”, które jednocześnie używają obiektu, poważnie się pomieszają. Nie muszą też być rzeczywistymi, oddzielnymi wątkami (stąd cytaty). Jeśli skonfigurujesz obiekt dla jednej tabeli, a następnie wywołaj metodę, która używa go dla innej tabeli, a następnie spróbuj użyć oryginalnej konfiguracji, masz problem. Na razie trzymaj się parametrów.
To, co chcesz tutaj zrobić, to utworzyć nową klasę aktualizacji, która będzie używana tylko w jednym przypadku. Oryginalna klasa może mieć metodę tworzenia instancji w razie potrzeby. Nowa klasa miałaby pola. Masz to, co najlepsze z obu światów. Czasami łatwiej jest trzymać się parametrów, ale w twoim przykładzie już docierasz do miejsca, w którym oddzielna klasa byłaby lepsza.
źródło
Myślę, że wybór powinien być zgodny z rzeczywistą sytuacją, tak jak ją widzisz. Jeśli element należy do instancji, powinien być postrzegany jako jego pole. Jeśli element jest zewnętrzny względem instancji, powinien zostać przekazany jako parametr metody.
W tym przypadku powinniśmy się kierować nie efektywnością (różnica i tak jest nieznaczna), czy (Boże chroń!) Łatwością pisania, ale zrozumiałością i naturalnością kodu.
źródło
Moim zdaniem, jeśli piszesz kod, który coś robi, to powinien on przyjmować parametry, które określają, do czego powinien to robić, a jego nazwa powinna określać, na ile to możliwe, co ma z tym zrobić.
Jeśli piszesz kod, który pakuje akcję do wykonania na czymś , powinieneś owinąć rzeczy, które powinny zostać wykonane w obiekcie i przekazać je swojej rzeczy, która coś robi .
Ta akcja staje się następnie rodzajem meta-opisu wywołań metod pierwszego, które możesz następnie wykonać później, ustawiając w kolejce, a nawet z jakiegoś powodu zrezygnować.
Twoje pytanie przekłada się więc na działanie lub funkcję ? Akcja może być przełożone lub odwołane, a zatem należy ująć to, co działa na. Funkcja dzieje się natychmiast, więc nie ma potrzeby top zachować swoje parametry.
Możesz cofnąć i wykonać akcję, ale nie funkcję .
źródło