2011-09-22 17 views
8

Próbowałem opisać aplikację, którą buduję, w razie potrzeby, więc z góry przepraszam za esej!Dane wejściowe potrzebne dla mojej struktury programu/projektu

Jestem w trakcie projektowania i budowy dość dużej aplikacji muzycznej, wykorzystującej framework C++ Juce, która w skrócie przyjmuje komunikaty OSC i przekształca je w dane audio i MIDI. Aplikacja ma trzy "tryby", z których każdy określa, jaki rodzaj dźwięku będzie generowany przez komunikaty OSC. Użytkownik może zastosować tryb i kolejną grupę ustawień trybu, aby zdefiniować dźwięk, który uruchamia każdy komunikat OSC.

Poniżej znajduje się podstawowy przegląd schematów blokowych powiązań klas i hierarchii programów lub przynajmniej teoretycznie ich wyobrażenie. Aby wyjaśnić terminologię Juce, klasa "Component" jest w zasadzie obiektem/klasą GUI, która wyświetla rzeczy na ekranie i umożliwia interakcję z użytkownikiem.

Basic block diagram http://liamlacey.web44.net/images/Software_block_diagram.jpg

jestem doświadczony programista C, jednak jestem całkiem nowy, C++ i projektowania OOP. Rozumiem większość, jeśli wszystko jest w porządku, ale głównym problemem, jaki mam, jest struktura wszystkich klas w celu uzyskania prawidłowych relacji i hierarchii, aby wszystkie mogły się właściwie komunikować, aby aplikacja mogła wykonać to, co musi. .

Oto krótki opis tego, co robi każda klasa:

  • OscInput - ta klasa bazowa wykorzystuje bibliotekę oscpack do nasłuchiwania OSC wiadomości. Tylko klasa 1 może dziedziczyć z tej klasy bazowej, ponieważ aplikacja ulegnie awarii, jeśli na tym samym porcie UDP znajduje się wiele programów nasłuchujących.

  • Main - uruchomienie aplikacji. Dziedziczy z OscInput tak, że za każdym razem, gdy odbierany jest komunikat OSC, funkcja wywołania zwrotnego jest wywoływana w tej klasie w głównym oknie dokumentu aplikacji - domyślnie w aplikacjach Juce.

  • MainComponent - składnik główny/tła/GUI aplikacji - domyślnie aplikacje Juce.

  • Mode1Component/Mode2Component/Mode3Component - pojedyncza instancja każdej z tych klas składników nazywa i wyświetlane z MainComponent które są wykorzystywane przez użytkownika ustawienia, co robi każda wiadomość OSC.

  • SubComponent1 - pojedyncze wystąpienie tej klasy komponentów jest wywoływane i wyświetlane z MainComponent.

  • SubComponent2 - 48 wystąpień tej klasy komponentów jest wywoływanych i wyświetlanych z SubComponent1. Każda instancja służy do wyświetlania wartości innego odebranego komunikatu OSC.

  • Mode1/Mode2/Mode3 - pojedyncze wystąpienie każdej z tych klas jest wywoływane z głównego. Każda klasa jest używana do faktycznej konwersji wiadomości OSC na dane audio lub MIDI, w oparciu o wartości/zmienne w klasie Ustawienia.

  • Settings - pojedyncza instancja tej klasy używana do przechowywania ustawień sterujących dźwiękiem tworzonym z różnych komunikatów OSC.

Jestem dość szczęśliwy, że wszystkie klasy komponentów/GUI są ułożone i połączone we właściwy sposób. Mam również przychodzące wiadomości OSC działające poprawnie. Ale jest to relacja instancji klasy Settings, której nie jestem pewien, jak ją zaimplementować. Oto relacje Potrzebuję pomocy:

  • jednolitego wystąpień mode1, Mode2 i trybu 3. wszystkim trzeba pobrać wartości z instancji klasy Ustawienie
  • Pojedyncze przypadki MainComponent, Mode1Component, Mode2Component, Mode3Component wszystko trzeba wysłać wartości do instancji klasy Settings, a także pobrać wartości z instancji.
  • Wszystkie 48 przypadki SubComponent2 trzeba pobierać wiadomości OSC

Dlatego mam następujące pytania:

  • Gdzie należy instancja Settings klasa nazwać od tak, że wszystkie odnośne instancje klas wymienionych powyżej może się z nim komunikować? Chcę tylko jednej instancji tej klasy, która musi być dostępna dla wielu innych klas, więc czy powinna to być klasa globalna, Singleton, czy statyczna? Studiowałem wzorzec projektowania Singleton, który wydaje się być tym, czego szukam, ale mam wrażenie, że powinienem go unikać, jeśli mogę i rozważyć alternatywne metody.

  • Czy powinna to być klasa Main, która nasłuchuje komunikatów OSC? W jaki sposób mogę uzyskać SubComponent2 do odbierania komunikatów OSC, a także instancji klasy Mode1, Mode2 i Mode3?

  • Czy klasy funkcjonalności (Mode1, Mode2 i Mode3) powinny być wywoływane z Main? Próbuję zachować wszystkie funkcje i kod GUI osobno, ponieważ mam kogoś, kto zajmuje się programowaniem GUI, podczas gdy mam do czynienia z programowaniem funkcjonalności aplikacji.

  • Czy ktoś może wykryć jakiekolwiek poważne usterki we wzorcu projektowym mojego programu?

Każda pomoc będzie bardzo ceniona!

Dzięki

+5

Potrzebujemy witryny LiamLacey.StackExchange.Com, aby odpowiedzieć na tego potwora. –

+2

Życzymy powodzenia w uzyskaniu odpowiedzi - być może zawęzimy pytanie do czegoś, z czym ktoś może poradzić sobie na ochotnika. –

+0

Tak, przepraszam za długotrwałe pytanie - zawsze lepiej napisać eseje o krótkich, zwięzłych opisach! –

Odpowiedz

1

Odnośnie pytania na temat „main”: nie należy mieszać „Uruchomienie aplikacji” z odpowiedzialnością za przetwarzanie wiadomości w tej samej klasie/składnika („separation of concerns”). Co ty opisujesz pachnie zastosowaniu wzoru wydawca/abonenta

http://en.wikipedia.org/wiki/Publish/subscribe

A jeśli chcesz zrobić swoją architekturę naprawdę wiadomość zorientowanych, gdzie nie wszystko zależy od „main” i „Main” Czy nie zależą od wszystkiego, sugeruję, żebyś spojrzał na "Flow Design". Spójrz tutaj

http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/flow-design-cheat-sheet-ndash-part-i-notation.aspx

http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/20/flow-design-cheat-sheet-ndash-part-ii-translation.aspx

Wdrożenie instancję klasy ustawienia jako pojedyncza jest ok, gdy trzeba te ustawienia niemal wszędzie w swoim programie. Przynajmniej jest lepiej sprawdzalny niż klasa statyczna.Ale powinieneś unikać umieszczania zbyt wielu rzeczy, ponieważ wiele rzeczy może zależeć od ustawień, które mogą mieć negatywny wpływ na późniejszą konserwację.

+0

Zatem klasa inna niż główna powinna być klasą "słuchacza OSC"? Czy powinienem się zastanawiać nad wykorzystaniem wzorca projektowego Observer do wysyłania komunikatów OSC do właściwych miejsc w programie? –

+0

@Liam: albo "Main" jest detektorem OSC, a inna klasa uruchamia się, albo "Main" służy do uruchamiania, a druga do słuchania. "Observer" jest podzbiorem wydawcy/subskrybenta, może mieć tutaj zastosowanie. To twoja decyzja, czy to jest właściwe narzędzie, znasz szczegóły najlepiej. –