jeudi 6 mai 2021

How to pass objects to different layers and how do we name them?

Clean Architecture

I am having stressful time on how to pass objects to different layers (should we map while before we send to inner layer or after - when we are inside of that layer) and how should I name them. I believe this is more of asking you people's opinions rather than answering my question. By looking at examples on internet there is no strong opinion, convention on this issue.

I wrote oversimplified code with comments to make my confusions clear.

Even in this example it was hard to refactor when I change something on domain layer let's say I want use book_id rather than id on domain. I am getting pretty scared because in my projects some domain entities have more complex objects than this so changing the shape of the domain layer resulting a lot of refactoring. I know that we should not change domain layer a lot but are there any approaches you guys are adopting when the change is necessary.

interface IControllerDependencies {
  usecase: (todoParam: any) => any;
}

interface IRepository {
  create: (todoObject: any) => { _id: string; desc: string };
}

interface IUsecaseDependencies {
  repo: IRepository;
}

function todoFactory(todoItem: any) {
  return {
    id: undefined,
    desc: todoItem.desc,
  };
}

function usecase(dep: IUsecaseDependencies) {
  const _dep = dep;
  return function (todoParam: any) {
    const todoEntity = todoFactory(todoParam);
    // Should we map immediately here to persistance layer
    // or should we map inside persistence layer. By mapping I mean _id: id
    // todoEntity.toPersistence or toPersistence(todoEntity)
    const todoPersistenceItem = _dep.repo.create(todoEntity);
    // When we receive persistence layer object
    // Should we call todoDAO and map it in here or before create actually returns 
    // And should we map it to toDomain() or DTO  
    return todoPersistenceItem;
  };
}

function repository(): IRepository {
  return {
    create: (obj) => ({ ...obj }),
  };
}

const sanitize = (req) => req;

function controller(req: { desc: string }, res, dep: IControllerDependencies) {
  // First of all I believe we should sanitize the request obj in here.
  // And then call sanitized variable todoDto ? todoInput ?
  const todoDTO = sanitize(req);
  const obj = dep.usecase(todoDTO);
  res.send(obj);
}

function main() {
  const TodoRepo = repository();
  const CreateTodoUsecase = usecase({ repo: TodoRepo });
  controller(
    { desc: "buy milk" },
    { send: () => {} },
    { usecase: CreateTodoUsecase }
  );
}

Aucun commentaire:

Enregistrer un commentaire