Hello all. I'm just getting started with clean architecture on a personal project and have some questions. From what I have read and the videos I've seen, the interactor creates the entity objects and gives them to the persistence layer to store, but who "owns" the objects? In a managed language like c# (where most of my experience lies), I don't have to worry about the memory management usually. With me writing this in c++, I have to take care to not introduce memory leaks at the same time as trying to learn c++ and clean architecture. I'm getting really confused on the best way to pass these objects/classes around and how to manage their lifetimes. This is what I have, but I don't know if it is correct.
int main()
{
Persistence persistence;
AddOrder addOrder("My order", persistence);
addOrder.Execute();
const unique_ptr<Order> &order = persistence.GetOrder("My order");
AddLineItem lineItem("My Lineitem", order, persistence);
lineItem.Execute();
return 0;
}
class Persistence
{
public:
unique_ptr<Order> const& GetOrder(std::string OrderName)
{
return orders[OrderName];
};
void AddOrder(unique_ptr<Order> order)
{
orders[order->Name] = move(order);
};
private:
std::Map<std::string, unique_ptr<Order> > orders;
}
class AddOrder
{
public:
AddOrder(string OrderName, const Persistence &persistence)
{
this->OrderName = OrderName;
this->persistence = persistence;
};
void Execute()
{
std::unique_ptr<Order> order = std::unique_ptr<Order>(new Order(OrderName));
persistence.AddOrder(move(order));
};
private:
std::string OrderName;
Persistence persistence;
}
class AddLineItem
{
public:
AddLineItem(const std::string &LineItemName, const unique_ptr<Order> &order, const Persistence &persistence)
{
// store parameters
}
void Execute()
{
unique_ptr<LineItem> lineItem = unique_ptr<LineItem>(new LineItem(lineItemName));
order.AddLineItem(move(lineItem));
}
}
class Order
{
public:
Order(const std::string &OrderName) { /*store name*/ };
void AddLineItem(unique_ptr<LineItem> lineItem)
{
lineItems[lineItem->GetName] = lineItem;
}
string GetName() { return Name; };
private:
map<string, unique_ptr<LineItem> > lineItems;
}
class LineItem
{
public:
LineItem(const std::string &ItemName) { /*store name*/ };
string GetName() { return name; };
}
- Is my assumption correct that it is the persistence layer that "owns" the root level object of Order, but Order should "own" its LineItems, and LineItems should own their children, etc.
- Am I doing it right by creating Order and LineItem as a unique_ptr and using std::move to transfer ownership to the persistence layer?
- What should I be returning from Persistence::GetOrder() and Persistence::GetLineItem()? A const reference to the stored unique_ptr Order/LineItem, a struct with just the values?
- If I am returning the Order object from Persistence::GetOrder(), what prevents the delivery layer from just going directly to the object in the persistence class and adding a new lineitem and bypassing the AddLineItem interactor alltogether?
- The app layer is only supposed to return DTOs to the delivery layer (as I understand it), how would you pass a complex model up? Say a model of managers and employees where an employee could also be a manager, so you have a tree structure.
In c#, alot of this lifetime management is handled for me and I am having a hard time figuring this out in c++.