Nazwa modelu zawierającego pełny obiekt

0

Mam następujący model:
Car {
string engineId;
}

W pewnych sytuacjach zwracany jest Car z id silnika (string), ale są sytuacje gdzie chcę zwrócić Car z pełnym obiektem silnika (żeby wszystko co potrzebne było od razu dostępne i nie było potrzeby wielokrotnego odpytywania endpointu), tj.

Car {
Engine engine;
}

Pytanie jak nazwać ten drugi model? FullCar? Totalnie bezsensu. CarWithEngine? Też wydaje mi się słabe. Potem będę chciał model z skrzynią biegów i zawieszeniem to przecież nie nazwę go CarWithEngineAndGearboxAndSuspension.

2

Samochód składa się z części. Czemu nie zrobisz czegoś w ten deseń:

struct CarPart
{
   string partID;
   string partName;
};

struct Engine : public CarPart
{
   Engine(int power) : partID("engineID"), partName("Engine"), horsePower(power)
   {};
   int horsePower = 0;
}

class Car
{
protected:
   vector<CarPart*> parts;
}
0

Możesz sobie nazywać CarDescriptor, CarDTO, CarSpecification etc., czyli nie jest to samochód, a raczej jego opis (na potrzeby czegoś, np. przekazania informacji między interfejsami).

1

To zależy ile masz tych typów, możesz spróbować z np
dla pełnego samochodu CarDTO (DTO możesz sobie zamienić na Model albo ViewModel, w zależności co to w sumie jest, podejrzewam że DTO)
dla uproszczonego SimpleCarDTO

Tutaj nazewnictwo albo powinno mieć wpływ danej podstrony na której to będzie wyświetlane pod względem biznesowym - dlaczego tutaj potrzebujesz tylko ID a gdzieś indziej pełnego obiektu?

0

Chcesz tu zrobić coś co się nazywa lazy loading. Zakładam, że nie używasz żadnego ORMa, więc poza powyższymi sugestiami możesz spróbować jeszcze czegoś w ten deseń:

class DbObject
{
  public:
    int GetId() const;
    bool IsLoaded() const;
    void SetLoaded();
    void EnsureIsLoaded()
    {
        if(!IsLoaded())
        {
          //tutaj w magiczny sposób odczytujesz sobie klasę
          SetLoaded();
        }
    }
}

class CarEngine: public DbObject
{
  public:
    int GetBlabla()
    {
        EnsureIsLoaded();
        return m_blabla;
    }
private:
  int m_blabla;    
}


class Car: public DbObject
{
  CarEngine m_engine;
}

Piszę to z palca, więc coś może nie działać do końca.
Zasada jest prosta. Tworzysz sobie klasę bazową, która zwraca Ci ID i określa, czy obiekt został w pełni odczytany. Potem tworzysz sobie klasy potomne (CarEngine) ze wszystkim co potrzebujesz mieć w danej klasie. Ważne, żeby w getterach i setterach umieścić EnsureIsLoaded.
Jak to ma działać?
ZAWSZE odczytujesz tylko Id. W momencie kiedy próbujesz użyć tego obiektu, obiekt najpierw sam się odczyta w pełni, a dopiero potem zwróci Ci wartość. Np:

SELECT * FROM cars

Zwraca Ci coś takiego:

ID CarName EngineId
1 Skoda 2
2 Fiat 8
std::vector<Cars *> cars;
ReadCars(cars);

Car * pCar = cars[0];
int engineId = pCar->GetEngine()->GetId(); // tu bierzesz Id silnika. Nic się nie dzieje
int engineBlabla = pCar->GetEngine()->GetBlabla(); //tu dzieje się cała magia. Najpierw dzięki EnsureIsLoaded odczytuje się cały silnik, a na koniec zwraca Ci odpowiednie pole.

To taka podstawa do bardzo prymitywnego ORMa z LazyLoading. Pokazuję to jako jedną z możliwości. W C# zdecydowanie prościej coś takiego napisać ze względu na refleksje, w C++ będzie trudniej i trzeba pamiętać o EnsureIsLoaded. Chociaż pewnie dałoby się to jakoś mądrze ominąć.

1 użytkowników online, w tym zalogowanych: 0, gości: 1