11

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

Jesse
  • 3,243
  • 1
  • 22
  • 29
MikeWallaceDev
  • 1,458
  • 2
  • 14
  • 28

1 Answers1

2

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.

Jaime Mendes
  • 643
  • 3
  • 9
  • Thanks for your answer. Yes, I know that it's Uncle Bob's :) I'm referring to Mr Cejas' version for two reasons a) I'm making an Android app and b) the above text is just an edit of a letter that I sent to him. :) The specifics of the use case do not matter, there are many use cases. What matters is the data. For example, I can get a user from the user repository. But then one would expect to be to do user.getBooks() (synchronously). Then with the returned book, do book.getPage() (again, synchronously). What is the correct design to make this possible? – MikeWallaceDev Aug 25 '15 at 20:16
  • Not sure if I understood. You want something similar to lazy loading? Load main entity first and only load the child entities at request (getBooks())? – Jaime Mendes Aug 25 '15 at 20:19
  • 2
    No, I'm trying to understand the correct way to rebuild this tree structure. All the documentation/examples work with simple POJOs. And I understand that. But nothing shows how to work with objects that are parent->children. Using the knowledge from the documentation, I would have a User object and *beside* it another object of type list. I do not know how to correctly build a User object that HAS a child of list. – MikeWallaceDev Aug 25 '15 at 20:24
  • Ok. As soon as I can I will make an example – Jaime Mendes Aug 25 '15 at 20:24
  • Feel free to contact me for more information/help/anything :) – MikeWallaceDev Aug 25 '15 at 20:46