2009-02-24 7 views
10

Z biegiem czasu mój zespół stworzył klasę centralną, która zajmuje się aglomeracją obowiązków i biegnie do ponad 8000 wierszy, a wszystko to odręcznie, a nie automatycznie.W jaki sposób zmieniasz klasę, która jest ciągle edytowana?

Mandat został odrzucony. Musimy zmienić klasę potworów. Największą częścią planu jest zdefiniowanie kategorii funkcjonalności w ich własnych klasach z powiązaniem z klasą potworów.

Oznacza to, że wiele odniesień, które obecnie odczytać tak:

var monster = new orMonster(); 
var timeToOpen = monster.OpeningTime.Subtract(DateTime.Now); 

wkrótce odczytać tak:

var monster = new Monster(); 
var timeToOpen = monster.TimeKeeper.OpeningTime.Subtract(DateTime.Now); 

Pytanie brzmi: Jak na Ziemi możemy koordynować taką zmianę ? Odniesienia do miotu "orMonster" w każdej klasie biznes. Niektóre metody są wywoływane w dosłownie tysiącach miejsc w kodzie. Gwarantujemy, że za każdym razem, gdy będziemy mieli taką szansę, ktoś inny (prawdopodobnie wielu innych elses) w zespole będzie mieć sprawdzony kod, który wywołuje właściwość .OpeningTime.

Jak koordynujesz tak dużą zmianę bez szlifowania wydajności az do zatrzymania?

+0

W Visual Studio, kliknij prawym przyciskiem myszy, "Znajdź wszystkie odniesienia ..." i zastąp. – core

Odpowiedz

27

Powinieneś sprawić, by stara metoda wywoływała nową metodę. Następnie z czasem zmień odniesienia do starej metody, aby wywołać nową metodę. Po zmianie wszystkich odniesień do klienta możesz usunąć starą metodę.

Aby uzyskać więcej informacji, zobacz Move Method w klasycznym Martin Fowler, Refactoring.

+0

To. Oznacz je jako przestarzałe lub cokolwiek, jeśli twój język ma tę funkcję. Nadal będą działać, ale w IDE pojawią się brzydkie podkreślenia/przekreślenia i wypełnią konsolę ostrzeżeniami. –

10

Jedną z rzeczy, którą można zrobić, to tymczasowe pozostawienie metod proxy w klasie potworów, które delegują do nowej metody. Po około tygodniu, gdy jesteś pewien, że cały kod używa nowej metody, możesz bezpiecznie usunąć proxy.

1

Nie zmieniaj tego.

Zacznij od nowa i przestrzegaj prawa demeter. Utwórz drugą klasę potworów i zacznij od zera. Gdy druga klasa potworów się zakończy i będzie działać, wymień wystąpienia pierwszego potwora. Wymień to. Mam nadzieję, że dzielą się interfejsem, lub możesz to zrobić.

I zamiast tego: "monster.TimeKeeper.OpeningTime.Subtract (DateTime.Now)"

Wykonaj: monster.SubtractOpeningTime (DateTime.Now). Nie zabijaj się notowaniem kropek (stąd demeter).

2

Sugerujemy użycie narzędzia, takiego jak nDepend, do zidentyfikowania wszystkich odniesień do metod klasy. Dane wyjściowe z nDepend mogą być wykorzystane do lepszego zrozumienia sposobu grupowania metod.

7

Zajmowałem się tym wcześniej, kontynuując i refaktoryzując kod, ale następnie dodając metody, które pasują do starego podpisu, który przekazuje połączenia do nowej metody. Jeśli dodasz do tych tymczasowych metod atrybut "Przestarzałe", Twój kod będzie nadal budowany zarówno ze starych wywołań metod, jak iz nowych wywołań metod. Następnie z czasem możesz wrócić i zaktualizować kod wywołujący starą metodę. Różnica polega na tym, że podczas kompilacji otrzymasz "Ostrzeżenia", które pomogą ci znaleźć cały kod, który wymaga aktualizacji.

6

Nie jestem pewien, jakiego języka używasz, ale w.Możesz utworzyć ostrzeżenia kompilatora, które pozwolą ci opuścić stare referencje na jakiś czas, aby działały zgodnie z oczekiwaniami, ale ostrzegły innych deweloperów.

http://dotnettipoftheday.org/tips/ObsoleteAttribute.aspx

+0

Niesamowita wskazówka. Chciałbym móc dwa razy głosować w górę. –

+0

Zaakceptowanie tego jako odpowiedzi to 15 punktów, prawda? Prawie tak samo dobrze! ;) –

3

Przechowywać w miejscu starej metody i przekazania do nowej metody (jak mówili inni), ale również wysłać wiadomość dziennika w sposobie przekazania do przypomnienia sobie, aby ją usunąć.

Możesz dodać komentarz, ale zbyt łatwo go przegapić.

1

Kilka osób dostarczyło dobrych odpowiedzi dotyczących organizacji samego reaktora. To jest kluczowe. Ale zapytałeś także o koordynację zmian między wieloma osobami (co moim zdaniem było sedno twojego pytania). Z jakiej kontroli źródła korzystasz? Wszystko, co CVS, SVN, itp. Może obsłużyć zmiany przychodzące od wielu programistów na raz. Kluczem do tego, by wszystko przebiegło sprawnie, jest to, że każda osoba musi popełniać swoje granice i być atomistami, a każdy programista powinien często przyciągać innych.

2
var monster = new Monster(); 
var timeToOpen = monster.TimeKeeper.OpeningTime.Subtract(DateTime.Now); 

Nie jestem pewien, czy podzielenie go i udostępnienie publicznie dostępnych części jest lepsze. To łamie prawo demeter i może prowadzić do bólu NullReference.

Proponuję wystawić chronometrażystę na ludzi bez angażowania potwora.

Jeśli cokolwiek byś nie zrobił dobrze analizując API i widząc, co możesz wyciąć i zamknąć w potworze. Z pewnością dawanie zabawek z potworami do zabawy, w przeciwieństwie do robienia potworów, to sama dobra robota. Głównym wysiłkiem jest zdefiniowanie, że potwór z zabawkami musi uprościć swoją pracę.

+0

Z drugiej strony może to być punkt wyjścia - podziel go na funkcjonalne, a następnie usuń klasę potworów w późniejszym terminie. – TofuBeer

+0

Tak, ale wszyscy wiemy, że "późniejszy termin" zwykle oznacza, że ​​nigdy lub ponad rok później. Lepiej wziąć sugestię Chrisa Holme'a, stworzyć zestaw testów jednostkowych i zacząć od nowa i skopiować kawałek po kawałku do nowej struktury. – Quibblesome

4

Rozwiń zmiany w oddziale. Podziel podzbiór kodu na nową klasę, dokonaj zmian w bazie klientów, dokładnie przetestuj, a następnie połącz ponownie.

To koncentruje złamanie do momentu połączenia - nie cały cykl rozwoju.

Połączyć to z propozycją Patricka na have the monster call the small monsters. Pozwoli to łatwo powrócić, jeśli scalony kod klienta zepsuje zmiany do tego klienta. Jak mówi Patrick, będziesz w stanie usunąć metody potwora (teraz kody pośrednie), gdy tylko okaże się, że nikt ich nie używa.

Ja również powtarzam kilka rad, że plakaty mogą bezpośrednio ujawnić wyodrębnione klasy - nie przez potwora. Dlaczego stosować tylko pół lekarstwa? Z tym samym wysiłkiem możesz zastosować pełne wyleczenie.

Wreszcie: zapisz testy jednostkowe. Napisz wiele testów jednostkowych. Och, chłopcze, potrzebujesz testów jednostkowych, żeby bezpiecznie wyciągnąć to. Czy wspominałem, że potrzebujesz testów jednostkowych?

+0

+1 Moje myśli dokładnie. – si618

-2

Tak duża klasa to naprawdę problem. Ponieważ stało się tak duże i nikt nie czuł się nieswojo, musi być coś nie tak z polityką projektu. Powiedziałbym, że powinieneś podzielić się na pary i sparować programowanie. Utwórz oddział dla każdej pary programistów. Pracuj przez 1-2 dni przy refaktoryzacji. Porównaj swoje wyniki. Pomoże to uniknąć sytuacji, w której refaktoryzacja przebiegałaby od początku w niewłaściwym kierunku, co ostatecznie doprowadziłoby do konieczności przepisania klasy potworów od zera.

1

Przyjrzę się najpierw za pomocą klasy częściowej, aby podzielić klasę pojedynczego potwora na wiele plików, grupując metody na kategorie.

Będziesz musiał zatrzymać każdego edytującego klasę potworów podczas podziału na pliki.

Odtąd będzie mniej konfliktów scalających, ponieważ będzie mniej zmian dla każdego pliku. Następnie możesz zmienić każdą metodę w klasie potworów (jedna metoda na checkin), aby wywołać nowe zajęcia.

Powiązane problemy