Adrian Diaz
Adrian Diaz

Reputation: 129

correct management of repository in clean architecture

I´m new to implementing clean architecture although I really like the concept, however, when I think of repository implementation I'm always unsure.

For example: I always find diagrams like this repo interface using entity

In these diagrams, the repository interfaces use the entities and the entities know nothing about anything. The thing is I think it may be more useful for entities to be conscious of repository interfaces instead. I think it wouldn't violate the inversion of control principle since they are just interfaces and not implementations.

an example (not real code or language because language is not important in this case):

Class StudentEntity:
    important method: getMathGrade

Class MathClassroomEntity:
    constructor(repository){
       this.repo = repository
    }

    important method: getStudents(){
       this.repo.getStudents()
    }

    important method: getAverageGrade(){
       students = this.getStudents()
       sum = 0
       foreach student in students:
             sum = student.getMathGrade()
       return sum/students.length
    }

As you can see, many important business logic in one entity is related to other entities.

if the entities don't know anything about repos (interfaces at least).

how can I put these methods in my entities?

should I make my entities abstract? which I think is not so pretty

should I put this business logic in my use cases? which sounds even worse

why do they make repo interfaces use entities and not the other way? what are the advantages?

I know this is a lot, so thanks a lot in advance

Upvotes: 4

Views: 3170

Answers (1)

René Link
René Link

Reputation: 51463

how can I put these methods in my entities?

You don't need to put these methods in your entities.

The use case queries the repository and the repository should return the MathClassroomEntity which should just contain the students.

class RepositoryImpl implements Repository {

    public MathClassroom getMathClassroom(){
        return new MathClassroom(getStudents);
    }

    private List<Student> getStudents(){
         return .....;
    }
}

Thus the MathClassroom will only know about students

public class MathClassroom {
    private List<Student> students;

    public MathClassroom(List<Student> students){
         this.students = students;
    }

    public double getAverageGrade(){
       double sum = 0;

       for(Student student : students){
             sum += student.getMathGrade()
       }

       return sum / students.size();
    }
}

Easy to test and decoupled from the repository.

Upvotes: 4

Related Questions