Wpis z mikrobloga

#programowanie #programista15k #csharp #obiektowka
Cześć. Mam pytanie co do dekoratorów. Nie wiem czy do końca rozumiem i mam pewien problem mam nadzieję, że uda mi się go rozwiązać.
Mam dekorator

public class HamDecorator : PizzaDecorator
{
public HamDecorator(Pizza pizza) :
base(pizza)
{
}

public override double CalculateCost()
{
return base.CalculateCost() + 4.15;
}

public override string GetName()
{
return base.GetName() + ", Ham";
}
}

I jest on klasą. Tylko w mojej aplikacji mam mnóstwo składników (składników takich jak mąka, rodzynki, słonecznik etc.; program do "piekarni" i zależy mi na swobodnym dodawaniu nowych składników) i chcę mieć możliwość tworzenia gotowych produktów(np. chleb orkiszowy) z poszczególnych składników. I stąd moje pytanie czy jeśli chcę użyć Dekoratorów to muszę definiować każdy składnik jako nową klasę np. SunflowerDecorator i trzymać się ich na sztywno bez możliwości dodawania przez użytkownika? Czy może jest możliwość "dynamicznego" przekazywania poprzez jakąś listę tak, żeby np: w GetName można było użyć stringa pobranego z kontrolki? Mam nadzieję, że dość jasno jest to przedstawione. Z góry dzięki za odpowiedź i dopiero się uczę, także nie hejtujcie za dużo :D
  • 14
@FishyGuy: to ten bazowy obiekt który dekorujesz (w tym wypadku pizza) może być interfejsem i musisz sobie stworzyć obiekty bazowe które ten interfejs implementują (np pizza, chleb itp) i dekoratory będą przyjmowały ogólny interfejs zamiast konkretnego składnica bazowego
ps: bo jak dobrze zrozumiałem twoim problemem jest to że chcesz tworzyć nie tylko pizzę z dodatkami ale też inne dania np chleb itp


@LeopoldStuff: Nieee, chodzi mi o to żeby tworzyć chlebek bądź inną bułkę tylko tutaj masz klasę HamDecorator i czy ja muszę na sztywno(w programie poprzez kod, a nie aplikację użytkownika) wprowadzać np. SunFlowerDecorator, RaisinsDecorator etc. czy mogę to robić "dynamicznie" bez potrzeby wprowadzania tylu klas?
@FishyGuy: a już wiem o co chodzi ( ͡° ͜ʖ ͡°)
Utwórz sobie ogolny dekorator z polami name i cost które będą przekazywane w konstruktorze i jak użytkownik gdzieś tam w polach sobie wpisze nazwę skladnika i cenę i zatwierdzi to wtedy utworzysz nowy obiekt tego ogólnego dekoratora z przekazanym w konstruktorze nazwa i cena. Ta nazwa i cena w konstruktorze ma być przypisana do pół w
@FishyGuy to nie jest dobry przykład żeby korzystać z dekoratora. Tak naprawdę to chcesz mieć produkt + składniki tak? Czyli jeden produkt ma listę składników, czyż nie? :)
@Yahoo_ chce miec zbudowany produkt ze składników. Jest tak jak mówisz, produkt ma miec liste skladnikow i ilosc/wage tychze skladnikow. Wlasnie sie zastanawiam czy nie masz racji. Ale jesli tak to kiedy więc uzywac dekoratorów bo myslalem na poczatku ze swietny przyklad wrecz podrecznikowy?
@FishyGuy typowy przykład dla dekoratora. Masz klasę Service: IService. Dodaje ona do koszyka produkt. Masz jakieś nowe wymaganie. Nie chcesz zmieniać klasy Service, bo masz ją dobrze przetestowaną. Piszesz nowa klasę XServiceDecorator:IService, która przyjmuje jako parametr konstruktora IService. Teraz nowa klasa robi te nowa rzecz po czym wola wykonanie metody na starej klasie (a raczej interfejsie). W ten sposób dodałeś funkcje bez modyfikacji oryginalnej klasy.
@FishyGuy: Łap kompletny przykład, klasy są poglądowe i możesz je układać tak jak chcesz ( kod też, nie kompilowalem go wiec moze miec błędy w syntaxie :P ) :

interface Food {
public double CalculateCost();
public String GetName();
public boolean IsTasty();
}

class Chicken : Food {

public double CalculateCost() {
return 4.0;
}

public string GetName() { return "Chicken"; }

public boolean IsTasty() { return true; } //Everyone loves chicken!