Artykuły

A A A
Drukuj Ekportuj do PDF
Opublikowane: 2009.08.30 13:49 | rafalp11 | Aktualizacja: 2010.01.22 16:41

Tworzenie graficznego interfejsu użytkownika (GUI) zorientowanego na zakładki w ASP.NET z wykorzystaniem wzorca projektowego Budowniczego.

tagi: ASP.NET
Artykuł opisuje w jaki sposób zaprojektować uniwersalny i łatwo modyfikowalny graficzny interfejs użytkownika (GUI) złożony z zakładek poprzez zastosowanie wzorca projektowego Budowniczego. Część teoretyczna artykułu omawia pojęcie wzorca projektowego oraz przedstawia zastosowanie, strukturę oraz współpracę między obiektami występującymi we wzorcu Budowniczym. W części praktycznej autor pokazuje w jaki sposób wykorzystać ten wzorzec przy tworzeniu GUI dla przykładowej aplikacji in

Spis treści:

  1. Wstęp
  2. Wzorzec projektowy – definicja
  3. Wzorzec Budowniczy – teoria
  4. Wzorzec Budowniczy – praktyka – tworzenie interfejsu użytkownika w ASP.NET
  5. Przykłady
  6. Podsumowanie
  7. Bibliografia

 

Wstęp:

Projektując graficzny interfejs użytkownika (tzw. GUI) dla aplikacji desktopowej lub internetowej często tworzymy go w oparciu o zakładki, dzieląc dostępne w nim funkcje na części pogrupowane według określonych kategorii. Dzięki temu powstała aplikacja jest przyjazna dla użytkownika, gdyż poszczególne zakładki jej interfejsu zawierają logicznie, powiązane ze sobą elementy. Tworząc taki interfejs można posłużyć się wzorcem projektowym Budowniczy. Umożliwi nam on stworzenie uniwersalnego rozwiązania składającego się z usystematyzowanego i łatwego do analizy zbioru klas upraszczając w ten sposób programiście późniejszy proces modyfikacji i rozszerzania funkcjonalności takiego GUI.

Na początek krótko zdefiniuję pojęcie wzorca projektowego, napiszę kto po raz pierwszy go wprowadził, następnie przejdę do  omówienia wzorca Budowniczego, a w dalszej części artykułu przedstawię praktyczne przykłady zastosowania omówionego wzorca.

 

Wzorzec projektowy – definicja:

Wzorzec projektowy to uniwersalne, sprawdzone w praktyce rozwiązanie często pojawiających się, powtarzalnych problemów projektowych. Termin ten jako pierwszy wprowadził Christopher Alexander. Nie pisał on o architekturze oprogramowania, ale o wzorcach projektowania budynków. W swoich pracach stwierdza: „Każdy wzorzec określa problem, który wielokrotnie występuje w naszym środowisku, a następnie opisuje zasadniczą część rozwiązania tego problemu w taki sposób, by można było użyć tego rozwiązania milion razy, ale nigdy dwa razy tak samo”. Jego słowa są prawdziwe również w odniesieniu do projektowania obiektowego. W tym wypadku wzorcem projektowym jest „opis komunikujących się ze sobą obiektów i klas, który przerabia się w celu rozwiązania ogólnego problemu projektowego w danym kontekście”.

 

Wzorzec Budowniczy – teoria:

Wzorzec Budowniczy jest stosowany w celu oddzielenia procesu konstruowania skomplikowanych obiektów od ich reprezentacji. Dzięki temu mechanizm konstruowania może tworzyć różne reprezentacje bez modyfikowania konstruowanych obiektów.

 

Wzorca używaj, gdy:

  • tworzenie obiektu złożonego nie powinno zależeć od części składowych obiektu,
  • proces konstruowania musi uwzględniać różne reprezentacje konstruowanego obiektu.

 

Struktura:

 

Budowniczy.jpg

 

Klasy uczestniczące:

  • Kierownik – tworzy obiekt, używając interfejsu Budowniczego.
  • Budowniczy – definiuje interfejs wykorzystywany do budowy części obiektu, jego celem jest zwalnianie Kierownika z konieczności posiadania konkretnej wiedzy na temat budowanych obiektów.
  • BudowniczyKonkretny – konstruuje i łączy części produktu implementując interfejs dostarczony przez Budowniczego.
  • Produkt – reprezentuje budowany obiekt złożony.

 

Opis współpracy:

  1. Klient (programista) tworzy obiekt Kierownik, przekazując do jego konstruktora obiekt BudowniczyKonkretny.
  2. Klient (programista) wywołuje metodę Konstruuj należącą do klasy Kierownik.
  3. Kierownik wydaje polecenie budowy części obiektu Budowniczemu.
  4. BudowniczyKonkretny konstruuje poszczególne części produktu i łączy je.
  5. Klient (programista) otrzymuje gotowy produkt.

 

Konsekwencje zastosowania:

  • Możliwość zmiany wewnętrznej reprezentacji produktu poprzez zdefiniowanie nowego rodzaju BodowniczegoKonkretnego.
  • Ukrycie reprezentacji, wewnętrznej struktury oraz sposobu montowania produktu.
  • Oddzielenie kodu służącego do konstruowania od reprezentacji. Dzięki temu kod niezbędny do budowy i składania konkretnego produktu może być wywoływany przez różnych Kierowników.
  • Większa kontrola procesu konstruowania, ponieważ odbywa się on krok po kroku pod nadzorem Kierownika.

 

Wzorzec budowniczy – praktyka – tworzenie interfejsu użytkownika w ASP.NET

 

ASP.NET zakłada budowanie aplikacji według określonego schematu polegającego na oddzieleniu warstwy prezentacji (wyglądu) zawartej w plikach *.aspx (strony WWW) lub *.ascx (kontrolki użytkownika)od warstwy logicznej zawartej w plikach *.cs. Podejście takie sprawdza się jednak głównie przy tworzeniu prostych i nierozbudowanych aplikacji. W przypadku kiedy pracujemy nad skomplikowanym projektem, takie podejście nie jest optymalną metodą. Pełną kontrolę nad tworzeniem aplikacji otrzymamy wówczas, kiedy będziemy projektować interfejs użytkownika oraz pozostałe elementy aplikacji zgodnie z zasadami programowania obiektowego (zorientowanie na obiekty). Wszystkie elementy aplikacji dzielimy na funkcjonalne części, które definiujemy w osobnych klasach. Tak zorganizowany kod aplikacji jest bardzo czytelny. Warunkiem tego jest jednak stosowanie odpowiednich nazw klas, które będą wiązać się z określonym zakresem funkcjonalności definiowanym w danej klasie. Każda taka klasa zawiera w sobie kod odpowiedzialny za wygląd oraz logikę pewnego fragmentu interfejsu użytkownika (panelu), definiując w ten sposób jego zakres odpowiedzialności. Takie rozwiązanie ma jeszcze jedną zaletę. Umożliwia zastosowanie wzorca Budowniczego w celu stworzenia złożonego interfejsu użytkownika zawierającego zakładki, umożliwiającego wybranie interesującego widoku. Każda zakładka powiązana jest z jednym panelem, który aktywuje się po jej kliknięciu. Odpowiednie zastosowanie wzorca Budowniczego umożliwia szybkie wprowadzanie zmian w wyglądzie budowanej w ten sposób aplikacji. Przykładowo programista może dodawać nieograniczoną liczbę nowych paneli oraz je usuwać. Taka funkcjonalność możliwa jest jedynie wtedy kiedy poszczególne panele są definiowane w osobnych klasach implementujących wspólny interfejs. Odpowiedzialność za tworzenie obiektu złożonego (zbioru paneli) przyjmuje klasa „Kierownik”. Wykorzystuje ona parametry przekazane w konstruktorze (m.in. tablica elementów implementujących interfejs abstrakcyjny) do budowy poszczególnych widoków interfejsu użytkownika i umieszcza je w kontrolce MultiView, pozwalającej na przełączanie się pomiędzy nimi (metoda SetActiveView). Każdy widok budowany jest z dwóch elementów. Pierwszym z nich jest zbiór zakładek, drugim natomiast panel zawierający pozostałe elementy wchodzące w skład interfejsu użytkownika (tekst, grafika, przyciski, listy wyboru, pola tekstowe itp.). Zakładki wyświetlane są w jednej z dwóch form:

  • element aktywny (wybrany przez użytkownika) – wykorzystując kontrolkę Literal,
  • element nieaktywny (możliwy do wybrania przez użytkownika) –wykorzystując kontrolkę LinkButton.

Każdy z linków powiązany jest z określonym widokiem, dzięki czemu jego kliknięcie powoduje wyświetlenie określonej zawartości.

 

Przykłady:

Poniższe fragmenty kodów źródłowych są częścią stworzonej przeze mnie aplikacji będącej systemem zarządzania treścią (ang. ContentManagementSystem) dla przykładowej witryny internetowej. Fragmenty kodów źródłowych dotyczą wyłącznie warstwy prezentacji (GUI) w/w aplikacji.

 

Przykład 1:

Pierwszym przykładem będzie widok panelu odpowiedzialnego za wyświetlanie artykułu na stronie WWW. Panel ten składa się z 3 zakładek: Treść, Załączniki oraz Komentarze.

Funkcje „Kierownika” odgrywa tutaj klasa: DetailsPanel. To obiekt tej klasy decyduje o tym jak będzie wyglądał panel zawierający szczegóły dotyczące wybranego artykułu. Wykorzystano tutaj kontrolkę MultiView, która służy do definiowania różnych widoków strony wyświetlanych w zależności od potrzeby (np. po kliknięciu wybranego linku). Klasa DetailsPanel zawiera konstruktor ogólny, który wywoływany jest z parametrem będącym tablicą elementów typu IDetailsPart, czyli obiektów klas implementujących ten interfejs. Wywołując konstruktor klasy DetailsPanel podajemy jako parametr tablicę obiektów z których będzie składał się panel artykułów. Drugi konstruktor występujący w tej klasie wykorzystano do przywrócenia ostatnio wybranego widoku w przypadku przeładowania strony np. po dodaniu nowego komentarza. W tym celu dodano do konstruktora dodatkowo parametr typu int: activeView. Zmiana widoku następuje po kliknięciu na jeden ze stworzonych odnośników (LinkButton).

 

W klasie DetailsPanel znajduje się również metoda:   private void CreateView(string[] viewsNames, int activeView) , która odpowiada za zautomatyzowanie procesu tworzenia poszczególnych widoków oraz zbioru linków potrzebnych do nawigowania po nich. Poniższy listing przedstawia kod źródłowy klasy DetailsPanel.

 

[Kod C#]

public class DetailsPanel

    {

        private MultiView multiView = null;

 

        private View[] viewParts = null;

        private IDetailsPanelPart[] articlePanelParts = null;

 

        public MultiView MultiView

        {

            get { return multiView; }

        }

 

        public DetailsPanel(IDetailsPanelPart[] articlePanelParts)

        {

            multiView = newMultiView();

            multiView.ActiveViewIndex = 0;

 

            string[] viewsNames = newstring[articlePanelParts.Length];

            for (int i = 0; i < articlePanelParts.Length; i++)

            {

                viewsNames[i] = articlePanelParts[i].PartName;

            }

 

            this.articlePanelParts = newIDetailsPanelPart[articlePanelParts.Length];

            viewParts = newView[articlePanelParts.Length];

            for (int i = 0; i < articlePanelParts.Length; i++)

            {

                this.articlePanelParts[i] = articlePanelParts[i];

                CreateView(viewsNames, i);

 

                //ustaw numer widoku komentarzy

                if (articlePanelParts[i] isArticleComments) (articlePanelParts[i] asArticleComments).CommentViewIndex = i;

                //ustaw numer widoku załączników

                if (articlePanelParts[i] isArticleMedia) (articlePanelParts[i] asArticleMedia).MediaViewIndex = i;

            }

        }

 

        public DetailsPanel(IDetailsPanelPart[] articlePanelParts, int activeView)

        {

            multiView = newMultiView();

            multiView.ActiveViewIndex = activeView;

 

            string[] viewsNames = newstring[articlePanelParts.Length];

            for (int i = 0; i < articlePanelParts.Length; i++)

            {

                viewsNames[i] = articlePanelParts[i].PartName;

            }

 

            this.articlePanelParts = newIDetailsPanelPart[articlePanelParts.Length];

            viewParts = newView[articlePanelParts.Length];

            for (int i = 0; i < articlePanelParts.Length; i++)

            {

                this.articlePanelParts[i] = articlePanelParts[i];

                CreateView(viewsNames, i);

            }

        }

 

        private void CreateView(string[] viewsNames, int activeView)

        {

            Panel panel = newPanel();

            panel.CssClass = "ArticleViewContainer";

 

            for (int i = 0; i < viewsNames.Length; i++)

            {

                if (i == activeView)

                {

                    Label label = newLabel();

                    label.Text = viewsNames[i];

                    label.CssClass = "ArticleViewItemActive";

                    panel.Controls.Add(label);

                }

                else

                {

                     LinkButton linkButton = newLinkButton();

                    linkButton.Text = viewsNames[i];

                    linkButton.CommandName = i.ToString();

                    linkButton.Command += newCommandEventHandler(linkButton_Command);

                    linkButton.CssClass = "ArticleViewItemInactive";

                    panel.Controls.Add(linkButton);

                }

            }

 

            viewParts[activeView] = newView();

            multiView.Views.Add(viewParts[activeView]);

 

            viewParts[activeView].Controls.Add(panel);

            viewParts[activeView].Controls.Add(articlePanelParts[activeView].PanelMain);

        }

 

        private void linkButton_Command(object sender, CommandEventArgs e)

        {

            multiView.SetActiveView(viewParts[int.Parse(e.CommandName)]);

            //jeśli przełączono widok i parametr sesji o nazwie view istnieje to go usuń

            if (HttpContext.Current.Session["view"] != null) HttpContext.Current.Session.Remove("view");

        }

     }

 

Za definicje poszczególnych części interfejsu użytkownika (GUI) odpowiedzialne są klasy: ArticleContents (Treść), ArticleMedia (Załączniki) oraz ArticleComments (Komentarze). Wszystkie te klasy implementują wspólny interfejs IDetailsPanelPart. Poniższy rysunek prezentuje strukturę klas występującą w opisanym rozwiązaniu.

Budowniczy1.jpg

W celu dodania do witryny panelu zawierającego widok składający się z określonych zakładek należy dodać w ciele metody:   protected void Page_Load(object sender, EventArgs e) następujący fragment kodu:

[Kod C#]

DetailsPanel articleParts = newDetailsPanel(newIDetailsPanelPart[] { newArticleContents("Treść", article), newArticleMedia("Załączniki", article, controlParams), newArticleComments("Komentarze", article, controlParams) });

panel.Controls.Add(articleParts.MultiView);

Powyższy kod tworzy obiekt klasy DetailsPanel przy użyciu konstruktora przyjmującego jako parametr tablicę obiektów implementujących interfejs IDetailsPanelPart. Tablicę tą inicjujemy odpowiednimi obiektami w zależności od tego z jakich elementów ma składać się produkt końcowy. W przedstawionym powyżej przykładzie panel Artykuły będzie zawierał trzy zakładki o nazwach: Treść (obiekt klasy ArticleContents), Załączniki (obiekt klasy ArticleMedia) oraz Komentarze (obiekt klasy ArticleComments).

Następnie należy dodać do zbioru kontrolek (this.Controls) obiekt klasy MultiView zawierający zbiór widoków artykułu.

 

Przykład 2:

Tworzenie graficznego interfejsu użytkownika w oparciu o wzorzec Budowniczy wykorzystałem również w edytorze mapy Google. Interfejs tego edytora składa się z czterech zakładek. Są to w kolejności: Opis, Ustawienia, Markery oraz Polilinie.

Rolę „Kierownika” odgrywa tutaj klasa MapEditor. Zasada działania jest podobna do opisanej w przykładzie pierwszym. Kod źródłowy klasy MapEditor został przedstawiony na poniższym listingu.

[Kod C#]

public class MapEditor

    {

        private Panel panelMain = null;

       

        private MultiView multiView = null;

        private View[] viewParts = null;

        private IEditorPart[] editorsParts = null;

 

        public Panel PanelMain

        {

            get { return panelMain; }

        }

 

        public MapEditor(IEditorPart[] editorsParts)

        {

            panelMain = newPanel();

 

           

 

            UpdatePanel updatePanel = newUpdatePanel();

            panelMain.Controls.Add(updatePanel);

 

            multiView = newMultiView();

            multiView.ActiveViewIndex = 0;

            updatePanel.ContentTemplateContainer.Controls.Add(multiView);

 

            string[] viewsNames = newstring[editorsParts.Length];

            for (int i = 0; i < editorsParts.Length; i++)

            {

                viewsNames[i] = editorsParts[i].EditorName;

            }

 

            this.editorsParts = newIEditorPart[editorsParts.Length];

            viewParts = newView[editorsParts.Length];

            for (int i = 0; i < editorsParts.Length; i++)

            {

                this.editorsParts[i] = editorsParts[i];

                CreateView(viewsNames, i);

            }

 

           

        }

 

        private void CreateView(string[] viewsNames, int activeView)

        {

            Panel panel = newPanel();

            panel.CssClass = "TabContainer";

 

            for (int i = 0; i < viewsNames.Length; i++)

            {

                if (i == activeView)

                {

                    Label label = newLabel();

                    label.Text = viewsNames[i];

                    label.CssClass = "TabItemActive";

                    panel.Controls.Add(label);

                }

                else

                {

                    LinkButton linkButton = newLinkButton();

                    linkButton.ID = activeView.ToString() + i.ToString();

                    linkButton.Text = viewsNames[i];

                    linkButton.CommandName = i.ToString();

                    linkButton.Command += newCommandEventHandler(linkButton_Command);

                    linkButton.CssClass = "TabItemInactive";

                    panel.Controls.Add(linkButton);

                }

            }

 

            viewParts[activeView] = newView();

            multiView.Views.Add(viewParts[activeView]);

 

            viewParts[activeView].Controls.Add(panel);

            viewParts[activeView].Controls.Add(editorsParts[activeView].PanelMain);

        }

 

        private void linkButton_Command(object sender, CommandEventArgs e)

        {

            multiView.SetActiveView(viewParts[int.Parse(e.CommandName)]);

        }

    }


Poszczególne zakładki są reprezentowane przez obiekty następujących klas: DescriptionEditor, SettingsEditor, MarkersEditor, Polilines Editor. Struktura klas komunikujących się ze sobą w celu realizacji funkcji edytora zastała przedstawiona na poniższym diagramie.

Budowniczy3.jpg

Podobnie jak miało to miejsce w przykładzie pierwszym, w celu dodania do strony panelu zawierającego edytor wewnątrz metody   protected void Page_Load(object sender, EventArgs e) należy wstawić następujący fragment kodu:
[Kod C#]

//wyświetl edytor mapy

MapEditor mapEditor = newMapEditor(newIEditorPart[] { newDescriptionEditor("Opis", filePath), newSettingsEditor("Ustawienia", filePath, newExtendedSettingsEditor()), newMarkersEditor("Markery", filePath), newPolylinesEditor("Polilinie", filePath) });

this .Controls.Add(mapEditor.PanelMain);

Kod ten jest odpowiedzialny za stworzenie obiektu klasy MapEditor wykorzystując jej jedyny konstruktor przyjmujący parametr będący tablicą obiektów klas implementujących interfejs IEditorPart. W powyższym przykładzie inicjujemy tablicę obiektami klas: DescriptionEditor, SettingsEditor, PolylinesEditor, MarkersEditor).

Następnie należy dodać do zbioru kontrolek (this.Controls) obiekt klasy Panel zawierający edytor mapy.

 

Przykład 3:

Zmodyfikowaną wersję wzorca Budowniczego wykorzystałem przy tworzeniu rozwiązania służącego do automatycznego budowania menu (jedno lub kilkupoziomowego). Menu takie można następnie umieścić w dowolnym miejscu witryny Web.

Modyfikacja wzorca budowniczy polega na pominięciu definiowania interfejsu, ponieważ wszystkie elementy menu są obiektami jednego typu (klasa NavigationItem). Główną klasą (tzw. „Kierownikiem”) odpowiedzialną za tworzenie struktury menu jest NavigationPanel. Klasa ta zawiera jeden konstruktor ogólny posiadający następujący zbiór parametrów:

  • tablica obiektów klasy NavigationItem – elementy menu,
  • parentNavigationPanel – podajemy tutaj nadrzędny panel nawigacyjny (menu), w przypadku kiedy chcemy umieścić na stronie Web menu główne (menu pierwszego poziomu) parametrowi temu przypisujemy wartość null,
  • name – nazwa parametru URL identyfikowana z danym panelem nawigacyjnym (definiowany dla jednego poziomu menu).

 

Klasa NavigationPanel zawiera również metodę public NavigationPanel(NavigationItem[] navigationItems, NavigationPanel parentNavigationPanel, string paramName) odpowiedzialną za tworzenie elementów menu. Poniższy listing przedstawia implementację klasy NavigationPanel.
[Kod C#]

public class NavigationPanel

    {

        private Panel panelMain = null;

 

        string paramName = null;

        string value = null;

        string currentUrlParameters = null;

 

        public Panel PanelMain

        {

            get { return panelMain; }

        }

 

        public string CssClass

        {

            get { return panelMain.CssClass; }

            set { panelMain.CssClass = value; }

        }

 

        public string ParamName

        {

            get { return paramName; }

        }

 

        public string Value

        {

            get { return value; }

        }

 

        public string CurrentUrlParameters

        {

            get { return currentUrlParameters; }

        }

 

        public NavigationPanel(NavigationItem[] navigationItems, NavigationPanel parentNavigationPanel, string paramName)

        {

            panelMain = newPanel();

 

            this.paramName = paramName;

            value = HttpContext.Current.Request.Params[paramName];

 

            if (parentNavigationPanel == null)

            {

                CreateNavigationPanel(navigationItems, "", paramName, (value == null) ? 0 : int.Parse(value));

            }

            else if (HttpContext.Current.Request.Params[parentNavigationPanel.paramName] != null)

            {

                currentUrlParameters = parentNavigationPanel.currentUrlParameters + parentNavigationPanel.paramName + "=" + parentNavigationPanel.value + "&";

                CreateNavigationPanel(navigationItems, currentUrlParameters, paramName, (value == null) ? 0 : int.Parse(value));

            }

        }

 

        private void CreateNavigationPanel(NavigationItem[] navigationItems, string currentUrlParameters, string paramName, int activeLinkParamValue)

        {

            for (int i = 0; i < navigationItems.Length; i++)

            {

                if (navigationItems[i].ParamValue == activeLinkParamValue)

                {

                    Label label = newLabel();

                    label.CssClass = "NavigationItemActive";

                    label.Text = navigationItems[i].ItemName;

                    panelMain.Controls.Add(label);

                }

                else

                {

                    HyperLink linkCategory = newHyperLink();

                    linkCategory.CssClass = "NavigationItemInactive";

                    linkCategory.Text = navigationItems[i].ItemName;

                    linkCategory.NavigateUrl = HttpContext.Current.Request.FilePath + "?" + currentUrlParameters + paramName + "=" + navigationItems[i].ParamValue;

                    panelMain.Controls.Add(linkCategory);

                }

            }

        }

    }
Każdy element menu jest obiektem klasy NavigationItem. Na poniższym diagramie przedstawione zostały wszystkie klasy uczestniczące w tworzeniu menu.

Budowniczy2.jpg

Zdefiniowanie i dodanie do witryny przykładowego menu wiąże się z umieszczeniem wewnątrz metody :  protected void Page_Load(object sender, EventArgs e) następującego fragment kodu :
[Kod C#]

string navigationParamName = "nav";

//menu

NavigationPanel navigationPanel = newNavigationPanel(newNavigationItem[] { newNavigationItem("Strona główna", 0), newNavigationItem("Artykuły 1", 1), newNavigationItem("Artykuły 2", 2), newNavigationItem("Artykuły 3", 3), newNavigationItem("Artykuły 4", 4), newNavigationItem("GoogleMapsAPI", 5) }, null, navigationParamName);

navigationPanel.CssClass = "Demonstration_Menu";

form1.Controls.Add(navigationPanel.PanelMain);

Powyższy kod tworzy nowy obiekt klasy NavigationPanel przy pomocy konstruktora ogólnego. Pierwszym parametrem konstruktora jest tablica obiektów klasy NavigationItem. Przykład pokazuje w jaki sposób utworzyć menu składające się z następujących pozycji: Strona główna, Artykuły 1, Artykuły 2, Artykuły 3, Artykuły 4 oraz GoogleMapsAPI. Każdej pozycji należy ponadto przypisać numer, który będzie jednoznacznie identyfikował ten element (liczba typu int).

Kolejny parametr przyjmuje wartość null, ponieważ tworzone menu jest elementem głównym (stanowi pierwszy poziom). Ostatni parametr to nazwa parametru URL niezbędna do określenia, który element menu został wybrany przez użytkownika serwisu Web.

 

Podsumowanie

Wzorzec Budowniczy zakłada stworzenie jednej głównej klasy (tzw. „Kierownika”). Obiekt tej klasy decyduje o tym jak będzie wyglądał produkt ostateczny. Programista wywołuje jedynie konstruktor klasy „Kierownik” z odpowiednimi parametrami tj. tablicą obiektów klas dziedziczących po wspólnym interfejsie. Obiekty te reprezentują poszczególne części graficznego interfejsu użytkownika (zakładki). Każda taka część GUI musi zostać zdefiniowana jako osobna klasa implementująca określony interfejs. W klasie tej definiujemy wygląd zakładki oraz operacje możliwe do zrealizowania (wykonywane w przypadku zarejestrowania zdarzenia np. kliknięcie przycisku itp.)

W części teoretycznej opisano metodę Konstruuj, znajdującą się w klasie „Kierownik”, dzięki której można tworzyć obiekt złożone. W przykładach praktycznych metoda ta została pominięta, aby uprościć tworzenie obiektów (w celu stworzenia obiektu złożonego wystarczy tylko wywołać konstruktor klasy „Kierownik”).

 

Zastosowanie wzorca budowniczy w projekcie GUI zorientowanego na zakładki daje nam możliwość elastycznego wprowadzania zmian w wyglądzie poszczególnych zakładek. Możemy również modyfikować wygląd całego panelu: np. usuwać wybrane zakładki, dodawać nowe, zmieniać kolejność wyświetlania. W tym celu modyfikujemy jedynie fragment kodu tworzący obiekt klasy „Kierownik” (modyfikujemy wywołanie konstruktora klasy „Kierownik”).

Ponadto nic nie stoi na przeszkodzie, aby zmodyfikować istniejące zakładki definiując nową klasę obiektów dziedziczącą po wybranej zakładce (zdefiniowaną w klasie bazowej).

 

Bibliografia

  1. R. Connolly – ASP.NET 2.0. Projektowanie aplikacji internetowych , Helion, Gliwice, 2008.
  2. E. Gamma, R. Helm, R. Johnson, J. Vlissides – Wzorce projektowe , Wydawnictwa Naukowo-Techniczne, Warszawa, 2008.
  3. A. Holub – Wzorce projektowe. Analiza kodu sposobem na ich poznanie , Helion, Gliwice, 2005.
  4. R. Miller – Język UML w praktyce: wprowadzenie dla programistów , http://www.borland.pl/tech/poradnik_uml.shtml.
  5. K. Rychlicki-Kicior – ASP.NET 3.5 dla programistów PHP , Helion, Gliwice, 2009.
  6. Wikipedia: Wolna encyklopedia – Wzorzec projektowy (Informatyka) , http://pl.wikipedia.org/wiki/Wzorzec_projektowy_(informatyka).
  7. R. Wirfs-Brock, A. McKean – Projektowanie obiektowe. Role, odpowiedzialność i współpraca, Helion, Gliwice, 2005.

<!--[if !vml]-->


Podobne artykuły

23 listopada 2005 GridView w ASP.NET 2.0 cz.1

Komentarze 0 Masz uwagi do tej strony? Napisz

Dodaj komentarz

avatar

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.

Autor rafalp11
avatar
 

Załóż konto
CodeGuru to miejsce dla każdego programisty. Przez lata portal rozwijany był siłami społeczności i to właśnie społeczność programistów jest tutaj najważniejsza. CG od wielu lat gromadzi wokół siebie coraz większą grupę pasjonatów. Warto być jej częścią!

Dowiedz się więcej o CodeGuru