Czy lepiej jest wywołać funkcję, która w tym momencie nie działa, JEŚLI poprawia to przejrzystość kodu?

60

Mam trzy widoki w moim programie (aplikacja na iOS). Tylko jeden z nich jest zawsze aktywny w tym samym czasie, więc dla dwóch z nich wyłączam widoczność i zmieniam widoczność, gdy użytkownik naciska przyciski. Widoki są inicjowane jako widoczne, więc wyłączam widoczność w kodzie, zanim wyświetli się widok główny.

potrafię

[view1 setAlpha:0.0f];
[view2 setAlpha:0.0f];

dla dwóch widoków, ale teraz trzeci (ten, który powinien być widoczny na początku aplikacji) nie jest adresowany. Kładę

[view3 setAlpha:1.0f];

po pierwszych dwóch, ponieważ myślę, że jasne jest, że w rzeczywistości istnieją trzy widoki, a nie dwa, jak mogłoby się wydawać, widząc kod. Jak robią to inni programiści? Czy to czysta preferencja, czy są jakieś konwencje?

Jeśli połączenie jest bardzo ciężkie, oczywiście lepiej nie dzwonić, gdy nie jest to konieczne, ale zastanawiałem się nad małymi rzeczami, takimi jak mój przykład.

Kevin
źródło

Odpowiedzi:

134

Masz niezmiennik:

Tylko jeden widok (spośród 3) jest zawsze aktywny (i widoczny).

Następnie sugeruję, aby zapewnić funkcję przełączania aktywności i widoczności WSZYSTKICH widoków jednocześnie:

[setActiveView viewID:2]

Ta funkcja:

  • sprawdź, czy widok jest już aktywny, unikając niepotrzebnej pracy
  • ustaw widok jako aktywny i widoczny
  • ustaw pozostałe 2 widoki jako nieaktywne i niewidoczne

Ma wiele zalet surowego połączenia z setVisibility:

  • przyjazne: wywoływanie go niepotrzebnie nie powoduje problemów z wydajnością
  • defensywny: jego pojedynczy parametr jest o wiele trudniejszy do skrobania, podczas setVisibilitygdy trudniej jest pamiętać, że zakres wartości jest 0.0f - 1.0fi że tylko jeden musi być ustawiony na1.0f
  • sprężysty: następny facet nie może przypadkowo zapomnieć jednego z widoków
  • adaptowalny: dodawanie / usuwanie widoku nie wymaga sprawdzania całego kodu aplikacji w celu ustalenia, gdzie znajdują się przełączniki, jedna funkcja (ta) musi zostać zaktualizowana

Idealnie, aby pomóc wymusić niezmiennik, żadna inna funkcja nie powinna być w stanie zepsuć się z tym ustawieniem ...

Matthieu M.
źródło
Świetna sugestia. Zrobię to na obecnym przykładzie. Ale co, gdy taki projekt nie jest możliwy / pożądany? A może decydujesz na miejscu, jak najlepiej sobie z tym poradzić?
Kevin,
4
@Kevin: To zależy naprawdę. Czasami możesz rozwiązać problem, iterując kolekcję, czasem nie, ale podstawową zasadą jest unikanie powielania i ułatwianie zachowania niezmienników. Im więcej „ręcznych” działań należy pamiętać, aby rzeczy działały poprawnie, tym mniejsze są szanse, że coś będzie działało poprawnie. Nienawidzę być tutaj niejasny, ale istnieje tak wiele różnych sytuacji, że obawiam się, że „ogólna” zasada doprowadziłaby cię na manowce.
Matthieu M.,
23
„Ułatwienie zachowania niezmienników” to ogólna zasada, o której warto pamiętać.
Gusdor,
1
@Tonny: Nie wiem, czy zachęcanie do używania zmiennej globalnej oznacza „robienie tego dobrze”, ale jeśli wiesz dokładnie, która była wcześniej aktywna, potrzebujesz tylko dwóch widoków. Innym rozwiązaniem jest zapamiętywanie widoczności dla każdego widoku i setVisibilitynie robienie niczego, jeśli widoczność jest już wymagana, co obniża odpowiedzialność.
Matthieu M.,
1
@MatthieuM. Pisałem w pośpiechu, ale tak naprawdę to też miałem na myśli. Jeśli znasz poprzedni stan, musisz tylko zaktualizować 2 widok. Jak zapamiętać ten stan to inna sprawa ;-). Jeśli chodzi o przeniesienie odpowiedzialności w dół: jeśli klasa widoku tego nie przewiduje, należałoby owinąć klasę w inny obiekt, aby dodać tę właściwość. To czyste rozwiązanie, ale może trochę przesada.
Tonny,
12

Alternatywny pomysł: jeśli Twoim celem jest zapobieganie występowaniu błędów, ponieważ ludzie zapominają o trzech widokach i robią coś z tylko dwoma z nich, co naprawdę powinni zrobić ze wszystkimi, a następnie włącz funkcję, która uniemożliwia zapomnienie:

setViewVisibilities(0.0f, 0.0f, 1.0f)

Teraz masz coś znacznie potężniejszego - czas kompilacji gwarantuje, że nie zapomniałeś . Jeśli zapomnisz parametru, kompilator będzie na ciebie krzyczał. Jest to o wiele bardziej przydatne niż komentarze lub niepotrzebny kod, ponieważ tworzy ściśle nazwany protokół, który wymusza właściwość, na której Ci zależy.

Dla przypadku, gdy view3nie wymaga to widoczność zmianie, można dodać trochę zachowanie gdzie przechodząc szczególną wartość jak -1.0lub nilczy coś w tym kierunku oznacza „nie zmieniaj widoczności widok na wszystko”. To omija problem niepotrzebnego ustawiania widoczności.

Jacek
źródło
9
Jeśli OP uzyska ponad 10 widoków, parametr-per-view stanie się niemożliwy do utrzymania. Twoje zdanie na temat błędów czasu kompilacji jest poprawne, ale niestety jest to bardzo niemożliwe do utrzymania rozwiązanie.
Chris Cirefice,
3
@ChrisCirefice: Jeśli liczba widoków rośnie, możesz utworzyć pewnego rodzaju obiekt / klasę „ViewState”, która wymusza to niezmiennik. Następnie użyj go do przełączania itp. Przy tak wielu widokach jakiś obiekt menedżera prawdopodobnie i tak ma sens.
śleske,
8

Uważam, że najlepiej jest dodać komentarz wyjaśniający, że połączenie nie jest potrzebne (i dlaczego).

(być może fakt, że połączenie nie jest potrzebne lub potrzebujesz komentarza, może być zapachem kodu)

Basile Starynkevitch
źródło
1
@Niall Jeśli to możliwe, twierdzenie byłoby nawet lepsze niż komentarz.
200_success
9
Komentarze nie są rozwiązaniem nieusuwalnego i nieczytelnego kodu
dj18,
2
@Kevin lub możesz napisać kod, który jest doskonale czytelny bez komentarzy.
Jan
1
@Jan Komentarze to coś więcej niż tylko wyjaśnienie, co robi kod .......
Kevin
2
@Kevin Powiedziałbym, że komentarze nigdy nie powinny istnieć, aby wyjaśnić, co robi kod, ale raczej wyjaśnić, dlaczego to robi. I w takich sytuacjach często refaktor przejdzie cel bez potrzeby komentowania (co brzmi jak punkt widzenia Jana).
RJFalconer,
4

W tym konkretnym przypadku @Mattieu M. ma właściwe rozwiązanie.

W bardziej ogólnym przypadku, gdzie nie ma podobnych przekształcać, trzeba zadać sobie pytanie: Czy istnieje jakikolwiek szansa przyszła bałagan to programista moc w górę?

Odpowiedź jest zwykle tak. Co oznacza, że ​​tak, powinieneś dodać połączenie. Być może niektóre przyszłe wersje frameworku zaczynają się od WYŁĄCZENIA wszystkich widoków zamiast WŁĄCZENIA.

Stig Hemmer
źródło