Mam tło C i jestem newb w C++. Mam podstawowe pytanie projektowe. Mam klasa (nazwijmy go „kucharz” b/c mam problem wydaje się bardzo analogiczne do tego, zarówno pod względem złożoności i zagadnień), które w zasadzie działa takC++ Pomoc w refaktoryzacji klasy potworów
class chef
{
public:
void prep();
void cook();
void plate();
private:
char name;
char dish_responsible_for;
int shift_working;
etc...
}
w pseudo kod, to zostało zaimplementowane zgodnie z:
int main{
chef my_chef;
kitchen_class kitchen;
for (day=0; day < 365; day++)
{
kitchen.opens();
....
my_chef.prep();
my_chef.cook();
my_chef.plate();
....
kitchen.closes();
}
}
Klasa kucharska wydaje się być klasą potworów i ma potencjał, aby stać się nią. kucharz również wydaje się naruszać zasada jednej odpowiedzialności, więc zamiast tego powinniśmy mieć coś takiego:
class employee
{
protected:
char name;
int shift_working;
}
class kitchen_worker : employee
{
protected:
dish_responsible_for;
}
class cook_food : kitchen_worker
{
public:
void cook();
etc...
}
class prep_food : kitchen_worker
{
public:
void prep();
etc...
}
i
class plater : kitchen_worker
{
public:
void plate();
}
etc ...
Ja wprawdzie nadal zmaga się z jak wdrożyć go w czasie pracy, tak aby, na przykład, jeśli plater (lub "kucharz w roli plateru") zdecyduje się wrócić do domu w połowie obiadu, wtedy szef kuchni musi przeprowadzić nową zmianę.
Wydaje się, że jest to związane z szerszym pytaniem, które mam, jeśli ta sama osoba niezmiennie robi przygotowanie, gotowanie i platerowanie w tym przykładzie, jaka jest prawdziwa praktyczna korzyść z posiadania tej hierarchii klas do modelowania tego, co pojedynczy kucharz robi? Wydaje mi się, że ma to związek z "obawą przed dodaniem klasy", ale jednocześnie, teraz lub w przewidywalnej przyszłości, nie wydaje mi się, żeby utrzymywanie klasy kucharza w całości było strasznie uciążliwe. Wydaje mi się również, że dla naiwnego czytelnika kodu łatwiej jest znaleźć trzy różne metody w obiekcie szefa kuchni i przejść dalej.
Rozumiem, że może zagrozić, że stanie się nieporęczny, gdy/jeśli dodamy metody takie jak "cut_onions()", "cut_carrots()", itp. ..., być może każdy z własnymi danymi, ale wygląda na to, że można je podać przy użyciu funkcji prep(), powiedzmy, bardziej modułowej. Co więcej, wydaje się, że SRP podjęte zgodnie z logicznym wnioskiem utworzyłoby klasę "onion_cutters" "carrot_cutters" itp. ... i wciąż mam problem z dostrzeżeniem jej wartości, ponieważ w jakiś sposób program musi upewnić się, że ten sam pracownik tnie cebulę i marchewkę, co pomaga w utrzymaniu tej samej wartości w różnych metodach (np. jeśli pracownik tnie cebulę do cięcia palcem, nie jest już uprawniony do krojenia marchwi), podczas gdy w klasie potworów szef kuchni wygląda na to, że wszystko to zostaje załatwione.
Oczywiście, rozumiem, że w ten sposób staje się mniejszy o sensownym "obiektowym projekcie", ale wydaje mi się, że jeśli musimy mieć oddzielne obiekty dla każdego zadania szefa kuchni (co wydaje się nienaturalne, biorąc pod uwagę, że ta sama osoba wykonuje wszystkie trzy funkcje), która wydaje się priorytetować projektowanie oprogramowania w stosunku do modelu koncepcyjnego. Uważam, że projektowanie zorientowane obiektowo jest pomocne, jeśli chcemy mieć, powiedzmy, "meat_chef" "sous_chef" "three_star_chef", które są prawdopodobnie różnymi osobami. Co więcej, związany z problemem środowiska wykonawczego jest to, że wydaje się, że narzut na złożoność, pod ścisłym zastosowaniem zasady pojedynczej odpowiedzialności, musi zapewnić, że podstawowe dane, które składają się pracownikowi klasy podstawowej, zostaną zmienione i że ta zmiana jest odzwierciedlone w kolejnych etapach czasowych.
Jestem więc raczej kuszony, aby opuścić go mniej więcej tak jak jest. Gdyby ktoś mógł wyjaśnić, dlaczego to byłby zły pomysł (i jeśli masz sugestie, jak najlepiej postępować), byłbym najbardziej zobowiązany.
Czasami odwzorowanie rzeczywistych ról World/obowiązki/zadania do obiektów w kodzie po prostu nie działa. Może potrzebujesz jakiejś ogólnej funkcji, która wymaga osoby i działania. Ta funkcja umożliwia osobie wykonanie akcji. –
moduł na każdym interfejsie klasy może dać więcej wskazówek? jak to może zrobić plater? co może zrobić cook_food? czy muszą odziedziczyć, czy jest to tylko umiejętność (wywołanie funkcji)? – billz
Spójrz na metodę kompozycji. A może potrzebujesz tutaj wzoru stanu? –