Am working on a huge android project that has more than 50 APIs request
and using the MVVM pattern, My question is:
can I add all the requests in the same app repository or I must create a repository for each service?
As others suggested in the comments you should first define the modules of your app and then create the corresponding Repositories. This way you can easily maintain and test your application.
I strongly suggest you to have a look on this https://github.com/nickbutcher/plaid and mostly this video https://youtu.be/Sy6ZdgqrQp0
A good solution to this problem is, You must not implement all your API calling code to the same repository as it will become a massive single repository class. It will also be violating design principles i.e. rule of 30 as you are saying you have at least 50 APIs to work with.
Also, it is not a good practice to modify a class, again and again, see Open Close Principle.
You can make multiple API calling classes under the same package name.
Related
I am building a library that every 30 seconds displays a question (obtained from a REST Api) and allows the user to select one of the possible answers.
Also, I need to make use of that library in an app, displaying a video underneath the question.
Desired result
All the business and UI logic should be handled in the library.
Does it make sense to use an MVVM approach, with repository pattern in the library?
With this package structure?
Possible package structure
You're creating the library, which is totally different context and way of creating the codebase comparing to the app.
First of all you need to make decisions about the dependencies. Of course it is super easy to put retrofit, mvvm and other dependencies into the app and manage them further.
With library it's not that easy. What I would expect from library in the first place is to have as little dependencies as possible. If you're going to provide aar file, then the developer would have to include those dependencies in the project. On the other hand, if you're publishing the library to maven repo, the gradle will take care of the library's dependencies. However the biggest challenge here is maintaining the library and resolving conflicts in actual app that uses the library. It can lead to frustration and eventually someone can throw your library away, which is the worst thing from library creator's perspective.
What I would suggest for this small library (calling api and providing data to custom view) is to:
Use only OkHttp without retrofit to provide the data from the REST api.
If it's the case for the library, create some abstraction over the OkHttp client with public functions/methods so the developers can get the data by themselves. Cool approach for creating this kind of interface is to use Fluent Interface (for example if you want the client of the library to put their access token/secret key for the REST api to detect who is calling the api, how much, limit their requests etc)
If you want to also provide the Custom View I would suggest to think twice about separating the REST client and Custom View itself and let the developer put the data by themselves. On the other hand if you want to handle it by yourself, you have to consider error handling, state management, lifecycle callbacks for cancelling the requests etc. You can provide some Listener interfaces for the developers so they know what is going on in the custom view.
The way you structure the library is up to you, if you have only one dependency (the rest client) just pass the objects via constructor so you won't need to add another dependency. Or just simply use ServiceLocator pattern, however it should also be connected to the Application/Activity itself when setting up the library so the objects are destroyed properly
I know that both Exposed and Anko can operate SQLite easily, could you tell me which one is more better when I develope an Android App?
Use the framework you are most comfortable with. I tried Exposed once and it was ok for what I've used it. jooq might also be a valid alternative instead.
Reading the documentation of both, Room and Anko, I would stick to either one of those.
Regarding which of those, I just found an issue asking the very same question (even though just as a second or third question):
https://github.com/Kotlin/anko/issues/484
Some other resources I found regarding Room and Anko:
Stress-free SQLite with Anko: the comment regarding Anko vs Room is also insightful:
Anko SQLite provides a nice API to manage your data persistence layer but you still have do the heavy lifting by yourself. While Room is more like a framework. Generates databases from annotated classes for you, provides observable queries and has a really nice testing support. Also works well with Android Architecture Components.
Ah... and don't get me wrong. Exposed is ok too, I am still using it ;-) But if you are familiar with both, you may also have your preferred choice already. If you don't know any, you can try both and choose the one where you grasp the documentation more quickly or you feel more comfortable sooner.
using MVVM or MVP should i name packages like model, viewmodel, view and put proper classes and interfaces there or is it just a logical structure that should not be visible in classes structure?
If you want to go by the book, the current "correct" way to implement MVVM in Android is the Android Architecture Components set of libraries.
Read more about it here, and try this code lab. These will also show you how to name and place your classes.
But in general, you should go with what matches your app best. For smaller apps I would recommend going with M V P folders, while for bigger, more long-term ones tend to work better with folder-per-feature structure.
Google in it's sample Android Architecture project uses Model(Data) V(views) VM(view-models) file structure
Google sample sunflower app to show architecture components
Probably that's the best approach
Additionnaly you may find this resource interesting https://overflow.buffer.com/2016/09/26/android-rethinking-package-structure/
An implementation is visible here https://github.com/SamYStudiO/beaver
I also would like to indicate watching this TUTORIAL.
This guy goes well on teaching about the Architecture MVVM and also uses the ROOM Persistence Library.
It is worth giving a look at it.
I'm currently developing an Android application and I'd like to have an scalable architecture with a clean separation of concerns. The requirements of this application are, mainly:
User autentication (I'm dealing now with Google Sign-In for Android after many unsuccessful fights agains Android Identity Toolkit)
Synchronization with REST services (this application should be collaborative, I've already done a proof of concept to consume a "heartbeat" service, using AsyncService, that was the only way I've found to clean activies code, I got to that library researching about Robust Android Architectures)
ORM at client side to store user generated data and retrieved data in the future (my choice has been ORMLite for Android)
Material Design (as the best approach to the UI I have in mind)
First of all I'd like advices on how to separate classes inside the project, I mean, should I use folders (activity, model, DAL, service, sync...) or should I create my own libraries? (in .Net I'd create libraries with parent namespace)
My second and biggest concern is about user identity: how should looks like my architecture to achieve my goals? (sign up / Sign in with multiple providers, authenticated rest client and synchronization using SyncAdapter)
I hope you don bane this quiestion because maybe is too generic but I ask about all this stuff because I couldn't find information or advices about this stuff.
Thank you in advance.
This is a generic question and every dev has his own way to achieve this, but I would recommend to follow one of the trending patterns right now.
There is a project call the clean architecture. It has pretty much everything from dB to Api. In my opinion is a over-engineered.
I prefer another pattern called Flux.
Together with retrofit, eventbus or Otto makes building apps easy and keep the structure
You can read more about it here:
http://lgvalle.xyz/2015/08/04/flux-architecture/
Recently I’ve been rethinking my android architecture project, trying to adapt it to a more “clean architecture”, specifically, the kind of design suggested by “Uncle Bob”.
Which it involves several layers of abstractions, a nice isolation of responsibilities and a very strong dependency inversion achieved by dependency injection; which, ultimately, leads to a very decoupled-portable system. A perfect candidate to be tested by unit testing and integration testing.
In my android implementation I’ve ended up having three different modules or layers:
-domain: entities, interactors, presenters (pure java module)
-data: (acts as a repository to supply the data to the domain) (android library module)
-presentation: ui related stuff, fragments, activities, views, etc (android application module)
So, I’m trying to figure out what would be the best approach on the iOS ecosystem.
I’ve tried creating a project with multiple targets to achieve the same solution:
-domain: command line target (which seems very weird but I think is the most pure swift target available)
-data: cocoa touch framework
-presentation: cocoa touch framework
With this approach I can use these targets in the way I did with android modules. But the first caveat I’ve found it is that I need to add manually every new file to the dependent target.
But my knowledge is very limited in projects with multiple targets. I mean I’ve never created an iOS application with multiple targets. So I don’t know even if the solution would be use a framework (cocoa touch/cocoa) as a target instead of a command line module for the domain layer.
Any thought would be really appreciate.
Thanks!
Uncle Bob's Clean Architecture absolutely applies to iOS, Swift, and Obj-C. Architecture is language agnostic. Uncle Bob himself codes mostly in Java but in his talks he rarely mentions Java. All his slides do not even show any code. It is an architecture meant to be applied to any project.
Why am I so sure? Because I've studied MVC, MVVM, ReactiveCocoa, and Clean Architecture for 2 years. I like Clean Architecture the best, by far. I tested it by converting 7 Apple sample projects to using the Clean Architecture. I've used this approach exclusively for over a year. It works out better every time.
Some of the benefits are:
Find and fix bugs faster and easier.
Extract business logic from view controllers into interactors.
Extract presentation logic from view controllers into presenters.
Change existing behaviors with confidence with fast and maintainable unit tests.
Write shorter methods with single responsibility.
Decouple class dependencies with clear established boundaries.
We also added a router component so we can use multiple storyboards. No more conflicts.
Writing unit tests is greatly simplified too because I only need to test the methods at the boundaries. I don't need to test private methods. On top of that, I didn't even need any mocking framework because writing your own mocks and stubs becomes trivial.
I've written my experience for my last 2 years studying iOS architecture at Clean Swift I also put together some Xcode templates to generate all the Clean Architecture components to save a ton of time.
UPDATE - To answer #Víctor Albertos's question about dependency injection in the comment below.
This is a really great question and demands a long detailed answer.
Always keep the VIP cycle in mind. In this case, the doSomethingOnLoad() method is not a boundary method. Rather, it is an internal method invoked only within CreateOrderViewController. In unit testing, we test a unit's expected behavior. We give inputs, observe outputs, then compare the outputs with our expectations.
Yes, I could have made doSomethingOnLoad() a private method. But I chose not to. One of the goals of Swift is to make it easy for developers to write code. All the boundary methods are already listed in the input and output protocols. There is really no need to litter the class with extraneous private modifiers.
Now, we do need to test this behavior of "The CreateOrderViewController should do something on load with this request data" somehow, right? How do we test this if we can't invoke doSomethingOnLoad() because it is a private method? You call viewDidLoad(). The viewDidLoad() method is a boundary method. Which boundary? The boundary between the user and view controller! The user did something to the device to make it load another screen. So how do we invoke viewDidLoad() then? You do it like this:
let bundle = NSBundle(forClass: self.dynamicType)
let storyboard = UIStoryboard(name: "Main", bundle: bundle)
let createOrderViewController = storyboard.instantiateViewControllerWithIdentifier("CreateOrderViewController") as! CreateOrderViewController
let view = createOrderViewController.view
Simply calling the createOrderViewController.view property will cause viewDidLoad() to be invoked. I learned this trick a long time ago from someone. But Natasha The Robot also recently mentioned it too.
When we decide what to test, it is very important to only test the boundary methods. If we test every method of a class, the tests become extremely fragile. Every change we make to the code will break many, many tests. A lot of people give up because of this.
Or, think about it this way. When you ask how to mock CreateOrderRequest, first ask if doSomethingOnLoad() is a boundary method that you should write test for. If not, what is? The boundary method is actually viewDidLoad() in this case. The input is "when this view loads." The output is "call this method with this request object."
This is another benefit of using Clean Swift. All your boundary methods are listed at the top of the file under explicitly named protocols CreateOrderViewControllerInput and CreateOrderViewControllerOutput. You don't need to look elsewhere!
Think about what happens if you were to test doSomethingOnLoad(). You mock the request object, then assert that it equals to your expected request object. You are mocking something and comparing it. It's like assert(1, 1) instead of var a=1; assert(a, 1). What's the point? Too many tests. Too fragile.
Now, there is a time when you do mock CreateOrderRequest. After you've verified the correct CreateOrderRequest can be generated by the view controller component. When you test CreateOrderInteractor's doSomething() boundary method, you then mock CreateOrderRequest using interface dependency injection.
In short, unit testing is not about testing every unit of a class. It is about testing the class as a unit.
It is a mindset shift.
Hope that helps!
I have 3 series of draft posts in Wordpress on different topics:
In-depth look at each of the Clean Swift components
How to break up complex business logic into workers and service objects.
Writing tests in Clean Swift iOS architecture
Which one of these do you want to hear more first? Should I bump up the series on testing?
In my opinion Clean Architecture is a set of ideas, rules, principles... to make a code better.
[Android Clean Architecture]
With this approach I can use these targets in the way I did with android modules.
You are able create a target[About](application target or framework target...) but it depends on your needs
If you read Architecting Android...Reloaded from Fernando Cejas
you might have seen that I used android modules for representing each layer involved in the architecture.
A recurring question in discussions was: Why? The answer is simple… Wrong technical decision
The idea is that is not necessary to use some build components to implement Clean Architecture