Odziedziczyłem bazę kodu, w której jest dużo kodu, który wygląda mniej więcej tak:
SomeDataAdapter sda = new SomeDataAdapter();
sda.UpdateData(DataTable updateData);
I wtedy sda już nigdy nie jest używane.
Czy to zapach kodu wskazujący, że te metody powinny być metodami klasy statycznej?
code-smell
static-methods
Shane Wealti
źródło
źródło
Odpowiedzi:
Uznałbym to za zapach architektury w tym, że UpdateData prawdopodobnie powinien należeć do klasy „service”.
Gdzie dane to Apple. Gdzie AppleAdapter jest usługą / klasą inteligencji biznesowej. Gdzie AppleService to odwołanie Singleton do AppleAdapter, który istnieje poza bieżącą metodą.
Nie sądzę, że to, co robisz, jest niekoniecznie złe, ale jeśli SomeDataAdapter rzeczywiście reprezentuje jakąś bezpaństwową usługę biznesową, wówczas najlepszym rozwiązaniem będzie singleton. Mam nadzieję, że to pomaga! Podany przykład jest fantazyjnym sposobem na zapewnienie braku rywalizacji _appleService, jeśli zdarzyło się, że jest ona zarówno pusta, jak i dostępna w tym samym czasie przez dwa lub więcej wątków.
Wiesz co? Jeśli SomeDataAdapter jest ADO IDbDataAdapter (którym prawie na pewno jest), zignoruj całą odpowiedź!
: P
Nie mam uprawnień, aby dodać komentarz do pierwotnego pytania, ale jeśli możesz określić, gdzie istnieje ten kod.
Jeśli ten kod reprezentuje niestandardową implementację IDbDataAdapter, a UpdateData tworzy IDbConnection, IDbCommand i łączy to wszystko za kulisami, to nie, nie uważałbym, że kod pachnie, ponieważ teraz mówimy o strumieniach i innych rzeczy, które należy usunąć, gdy skończymy ich używać.
źródło
Myślę, że ten problem sięga jeszcze głębiej. Nawet jeśli przekształcisz go w metodę statyczną, otrzymasz kod, w którym wywołujesz pojedynczą metodę statyczną w dowolnym miejscu. Który moim zdaniem sam w sobie pachnie kodem. Może to oznaczać, że brakuje Ci ważnej abstrakcji. Być może chcesz utworzyć kod, który wykona wstępne i końcowe przetwarzanie, umożliwiając jednocześnie zmianę tego, co dzieje się pomiędzy nimi. To wstępne i końcowe przetwarzanie będzie zawierać wspólne wezwania, a pomiędzy nimi będzie zależeć od konkretnego wdrożenia.
źródło
Rodzaj. Zazwyczaj oznacza to, że chcesz przekazać funkcję, a wybrany język ci na to nie pozwala. Jest to trochę niezdarne i nieeleganckie, ale jeśli utkniesz w języku bez pierwszorzędnych funkcji, niewiele możesz zrobić.
Jeśli żaden z tych obiektów nie zostanie przekazany jako argument do innych funkcji, możesz zamienić je w metody statyczne i nic by się nie zmieniło.
źródło
fn x => x + 1
inew Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }};
czy ograniczenie się do kilku funkcji zakodowane i wąsko-użytecznych.fn x => x + 1
można być cukrem syntaktycznymnew Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }}
? Ok, może masz na myśli, że ktoś utknął w języku bez tego rodzaju cukru syntaktycznego.Jeśli stan posiadania sprawia, że dana klasa jest bardziej użyteczna, funkcjonalna… wielokrotnego użytku, to nie. Z jakiegoś powodu przychodzi mi na myśl wzorzec projektowania poleceń ; z tego powodu z pewnością nie jest chęć utopienia Roberta Harveya.
źródło
Zdefiniuj „często”. Jak często tworzysz obiekt? Dużo - prawdopodobnie nie?
Prawdopodobnie w twoim systemie są większe problemy. Przejście statyczne będzie wyraźniej informować programistę, że wewnętrzny stan obiektu się nie zmienia - świetnie.
Jeśli jednak pomieszany jest stan i musisz zacząć nadawać innym statyczny charakter, aby pierwsza stała się statyczna, musisz zapytać, które części muszą być statyczne, a które nie.
Tak, to zapach kodu, tylko niewielki.
źródło
Zrób to metodą statyczną i idź dalej. Nie ma nic złego w metodach statycznych. Gdy pojawi się wzór użycia, możesz martwić się o jego abstrakcję.
źródło
Zapach jest taki, że jest to kod proceduralny zawinięty (minimalnie) w obiekty.
Musi istnieć powód, dla którego chcesz wykonać tę operację na tabeli danych, ale zamiast modelować tę operację z innymi powiązanymi operacjami, które mają wspólną semantykę (tj. Mają wspólne znaczenie), autor po prostu uruchomił nową procedurę w nowej klasa i nazwał to.
W funkcjonalnym języku tak właśnie robisz;) ale w paradygmacie OO chciałbyś modelować abstrakcję obejmującą tę operację. Następnie użyłbyś technik OO do opracowania tego modelu i zapewnienia zestawu powiązanych operacji, które zachowują pewną semantykę.
Zatem głównym zapachem jest to, że autor używa klas, prawdopodobnie dlatego, że wymaga tego kompilator, bez organizowania operacji w model koncepcyjny.
BTW uważaj za każdym razem, gdy zobaczysz modelowany program zamiast przestrzeni problemowej . To znak, że projekt może zyskać na przemyśleniu. Innymi słowy, uważaj na klasy, z których wszystkie to „xAdaptor” oraz „xHandler” i „xUtility” i zwykle są powiązane z anemicznym modelem domeny . Oznacza to, że ktoś po prostu łączy kod dla wygody, w przeciwieństwie do faktycznego modelowania pojęć, które chce wdrożyć.
źródło