2010-08-03 14 views
8

Mam klasę podstawową (reprezentującą pojemnik na świecie wypełniony małymi sferami) i kilka klas pochodnych. Działa to dobrze.
Mój problem polega na tym, jak wykonać wizualizację. Mam UserControl wizualizujący klasę podstawową. Czy najlepszym rozwiązaniem jest wyprowadzenie UserControl dla każdej z klas pochodnych? Czy może lepiej dla każdego z nich pracować?
Edytuj:
Najwyraźniej nie byłem wystarczająco konkretny. Zawsze jest ten sam podstawowy wygląd: prostokąt z dużą ilością kół w środku. Różnica między klasami polega na tym, że pojemnik jest wypełniony. Jeden typ umieszcza ziarno pośrodku i tworzy inne sfery w strukturze drzewa - w tym przypadku należy narysować linie łączące rodziców i ich dzieci.
Generalnie powinien być spójny wygląd wizualizacji klas z kilkoma specjalnościami dla każdego typu pochodnego.Wizualizacja klas pochodnych w języku C#

+5

Czy starasz się wygrać konkurs liczenia galaretki Bean? –

+1

Myślę, że jest to bardzo ważne pytanie w inżynierii oprogramowania; Wpadłem na podobne sytuacje i nigdy tak naprawdę nie wiem, jak rozwiązać to poprawnie. Szkoda, że ​​wszystkie dotychczasowe odpowiedzi pominęły punkt. – Timwi

+2

@ James Curran: Sortuj. Tylko że nie ma zawodników, a żelki zastąpiono pustymi szklanymi mikrokulkami. – Lukas

Odpowiedz

0

Podejrzewam, że tylko ty możesz odpowiedzieć na to pytanie w sposób definitywny. Interfejs użytkownika dla danej podklasy jest prawdopodobnie tym, czego potrzebujesz, ale jeśli podklasy różnią się tylko nieznacznie, możesz łatwiej dodać logikę warunkową w mniejszej liczbie elementów sterujących użytkownika. Nie sądzę, że istnieje jedna odpowiednia odpowiedź na tę.

0

Trudno powiedzieć z powodu tylko niejasnego opisu. Musielibyśmy przynajmniej wiedzieć, jakie są różnice między klasami pochodnymi.

Generalnie, o ograniczonej wiedzy, bym przejść z jednego UserControl pochodzi jednej klasie pochodnej

0

Jeśli pochodzą Klasy Wizualizacja nie różnią się od siebie, a następnie, za pomocą wszelkich środków, użyj jednego UserControl. Głównym punktem tutaj jest DRY.

1

To naprawdę bardzo zależy od tego, jak podobne będą ekrany. Jeśli wyświetlacze klas pochodnych są bardzo podobne do klas bazowych, potrzebujesz tylko jednego UserControl do przeprowadzenia wizualizacji. OTOH, jeśli każda klasa pochodna musi wyświetlać unikalne rzeczy, lepiej będzie mieć oddzielną funkcję UserControl do wizualizacji każdej klasy pochodnej. Naprawdę nie mogę być bardziej konkretny bez bardziej szczegółowych informacji na temat twoich zajęć.

EDYTOWANIE: Z twoich dodatkowych informacji powiedziałbym, że powinieneś mieć podstawową klasę wyświetlacza, która rysuje prostokątny kontener commom, a następnie wyprowadził UserControls, które obsługują rysowanie zawartości każdego określonego typu.

+0

Zgadzam się ze zmienioną odpowiedzią. Niech klasa bazowa wykona cały rysunek i wywiąże klasę i zastąpi te, które zmieniają się między typami. Możesz mieć ogólną pętlę w klasie bazowej, która wywołuje metodę "narysuj następną", którą zastępujesz w podklasach. –

0

Jedno podejście do problemu byłoby rozkładając go po perspektywy MVVC:

Będziesz potrzebował jednego UserControl jako widok.

Jedna podstawowa Malarz, który obsługuje obraz twojego "pudełka z kółkami" jako ViewModel. Firma Derived Painters implementuje różną logikę pozycjonowania obiektów i ich wzajemnych połączeń.

Jeśli wygląd obiektów może się różnić, sami powinni zostać przekazani malarzowi jako ViewModel, prawdopodobnie za pośrednictwem wzoru adaptera.

Na koniec Twoje kręgi, prostokąty i elementy z nimi powiązane to Model.

Generalnie:

View (UserControl) -> ViewModel (Painter + Malarze pochodzące + object ViewModels) -> model (koło, prostokąt, itp)

0

nie w pełni zrozumieć swoją domenę problemu ale myślę, że musisz to jeszcze przerwać. dekomponuj swój model na części i zapisz widoki dla każdej części, a następnie po prostu połącz je z powrotem.

chciałbym napisać View dla swoich sfer, widok na linii między swoimi sfer i widokiem na prostokąt trzyma wszystko to każdy z modeli będzie odpowiedzialny za zorganizowanie tych i tworzenia odpowiednich SphereModels i LineModels (i cokolwiek innego potrzebujesz), wtedy twój główny widok musi być odpowiedzialny za umieszczenie ich w pudełku.

Pamiętaj zawsze wolą kompozycji Dziedziczenie! Skoncentruj się na podziale problemu na mniejsze części.

powodzenia

0

myślę pójdę z klasy bazowej Visualizer że miał kilka chronionych metod do rysowania okręgów i linie, a może niektóre nieruchomości na powierzchni kreślarskiej (Canvas?), Więc każda realizacja może obliczyć pomiar pozycje opartych itp

podstawa klasa realizuje wszystkie niezbędne metody interfejsu/podpory, aby to wizualizacji.

Użyj wzorca strategii w metodzie zwanej przez IDE, gdy wizualizer ma zwrócić się ... że realizacja metoda może wyczyścić płótnie, utworzone pędzle i inne rzeczy, które mają być wspólne dla każdego wdrożenia - wtedy wywołaj abstrakcyjną metodę klasy bazowej, która faktycznie umieszcza okręgi/pola/linie/etc w obszarze roboczym.

W ten sposób każda konkretna implementacja musi tylko martwić się logiką, aby poprawnie pozycjonować elementy zgodnie z zestawem reguł - wszystkie "rysunki na płótnie" są przechowywane w klasie bazowej.

HTH

EDIT: Poprawione literówki, które mogą powodować dezorientację, gdzie użyłem słowa „kontrola”, gdy miałem na myśli „wizualizera.”

0

To brzmi jak sytuacja z wieloma rozwiązaniami.

Jednym ze sposobów byłoby skonfigurować UserControl wywołać metodę wirtualną w klasie bazowej, a następnie zastąpić go w klasach pochodnych. W klasach pochodnych można po prostu wywołać podstawową implementację, aby wstępnie ustawić ramkę.

Można również ustawić go do renderowania w warstw (warstwy podstawowej, warstwy kuli, warstwy linii, etc.), i klasa dziecko czyni żadnych unikalnych warstw i określić kolejność. Może to być kosztowne, ale może wygładzić efekty wizualne, jeśli większość obrazu pozostanie taka sama.

Innym jest użycie delegatów w przeciwieństwie do dziedziczenia, ale to wydaje się bałagan. Generalnie nie jest to dobry pomysł ze względu na kary za wyniki. Ma jednak zaletę elastyczności czasu pracy. W zależności od reszty kodu możliwe jest przełączanie stylów wzrostu w połowie tego modelu. Jeśli nie widzisz możliwości skorzystania z tej elastyczności, polecam użycie innego modelu.

Niezależnie od używanej metody, polecam, że klasa bazowa zapewnienie wspólnych procedur rysowania w celu zapewnienia spójności.Procedury w klasie bazowej powinny być używane przez większość klas potomnych, ale niekoniecznie wszystkie. Zwykle skutkuje to łatwiejszym do opanowania kodem (chyba, że ​​skończysz z plikiem 10000 linii), mniejszą ilością błędów i mniejszym nakładem pracy.

Powiązane problemy