Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you implement one to many relationships in Clean Architecture

I'm having problems using Clean Architecture. For those of you who have read Fernando Cejas' blog post http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/, my question is based on it, and his code.

His example project has only one Domain Object a User. And everything is clear with POJOs. Where I am having a problem is, let's say that the user has books. A one to many relationship. How would you deal with this in Clean Architecture?

Just like him I have a few layers, so 3 classes per Domain Object (User, UserModel, UserEntity) and a repository per Domain Object (UserDataRepository). Our new example would also have Book, BookModel, BookEntity and BookDataRepository.

I also have use case classes with CRUD variations.

The problem for me is at the UI/Presenter level. At this point in the program I have a UserModel object AND a list of BookModels. I do not have userModel.getBooks(). I do not have userModel.save() (which would save all the book changes too).

To accentuate the problem, to make this analogy look even more like my actual use case, I also have the list of all the pages in the books! :) So when I save the User, I want to save to books, and all the pages for every book that might have been modified.

How would I go about this?

Second BONUS question : In my real world problem, I have classes that derive from a base class. To use the above analogy: LeftPage and RightPage would derive from PageBase. A Book has a list. However LeftPage and RightPage both have their separate repositories, separate use cases, etc. (But this doesn't work) How do I save a list ?? Do I have to make a separate use case SavePages which would have a :

if (pages.elementAt(i) instanceof LeftPage) { SaveLeftPage saveLeft = new..... } else { SaveRightPage saveRight = new..... }

I don't think that I can use Polymorphism because in all the documentation that I have seen, the Models don't know of the use cases.

I hope that you can help, thank you very much for your time :)

-MIke

like image 741
MikeWallaceDev Avatar asked Aug 25 '15 17:08

MikeWallaceDev


1 Answers

That's Uncle Bob's Clean Architecture. Fernando Cejas made a simplified example in Android but you should read the concepts from the original.

For your problem, what is actually your use case? Save the user with the books and the pages? You can do this, if is the requirements of the use case. Your entity User can have a collection of Books which in turn each book will have a collection of Pages and your UserRepository must be able to resolve each to its own table (or you can inject repositories to your own repositories, but in this case you must be able save all or rollback)

Can you save a book only with just a user reference? Have a property that identifies the book's owner or pass it by argument to a UseCase for just the book.

      public class SaveBookCase extends UseCase
      {
          public SaveBookCase(IBookRepository repository, Book book, int userId) 
          {
          /// 
          }

          //or

          public SaveBookCase(IBookRepository repository, SaveBookRequest request)
          {
          /// SaveBookRequest is a class that has the book and the user id
          }
      }

Regarding your second bonus question, if you only have a list of PageBase than you must pass it to the usecase SavePages, which will resolve each item to the correct repository (in this case you will inject 2 repositories).

But in your example, it can be the same database entity with a field identifying if its left or right and in this scenario, use only one repository.

like image 64
Jaime Mendes Avatar answered Oct 03 '22 19:10

Jaime Mendes