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
Related
I'm creating a framework with showcase composables of core functionalities (in this case some ecommerce product lists, categories etc.). The main point is that we will just need to swap the url of the client and maybe add an interceptor (in this case I apollo graphql but in retrofit it would be the same) and we will be able to use these composables with loaded data. Here's the problem: Since I'll probably want to use hilt how do I pass the url and/or interceptors to the framework? I thought about some sort of init function but the hilt classes are generated during build, so I'd somehow have to pass it during runtime. Is that even possible? Or maybe there are some good alternatives to that approach?
I want to implement Room database in my app, but I want to do that by creating a Library project.
Library project will store data
Android project will have the Objects and Dao's
Is this possible?
For this I have to implement Room in both Android project as well as Library
But can I have Dao's and Objects in Android project and Database in Library
Why I want to do this.
I want to build this feature in a generic way so that it can be used in my other project. Also Library will not just store the data, it will have some offline functionality which read a Offline data table and checks the internet connection and picks data from the table and send it to server.
None of this is implemented yet. I am in the process of thinking what is the right aproach
Thanks for your suggestions
R
It's a great desire to move Room to the separate module as far it's Android specific and violates the principle of the Clean Architecture. Here is where you can start, at least it looks similar: another stack question and take a look at all the answers.
About re-usage, probably, it will be quite hard. Not sure, that time you spend to make it universal be less than when you implement it in each project. So, take the time in the account also.
The case where it makes sense.
At my company, we did the next. We have a few related products (a few apps) that have similar user-intended logic. So we have a library that takes care of all user login / token expiration logic and so on and it provides a simple interface for the app to handle user account. Single code base, useful when fixing bugs. And connect this library to each project as a general module. But still, each app has its own internet communication and database because of domain-specific data.
The best for testing and architecture - move all room and internet logic to the module in the app. Access it by interfaces. You can share that module between apps.
I think you can use dynamic feature module, because it dependency to the app module and you can use Dao and Objects from app.
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.
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/
There is a core ERP mobile application for Android. A customer has requested additional features that will require more screens (and Activities) and extra functionality.
Is there a way I can add sort of an extension to the core mobile application in order to intergrate the extra features or should I code on top of the code of the core application?
I am interested in finding a neat solution focused on extendability since different clients might ask for different additional features. How would you deal with such an issue? Any tips on the structure of such a project would also be welcome.
Would it make a difference if the extra features need to use the same db as the core application?
Thank you in advance for your help.
The answer to your question lies in the Open/Closed principle introduced by Bertrand Meyer. Open/Closed Principle is a very simple Object Oriented Design principle which states that
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"
From your question its clear that you have identified the core functionalities in your application. So rather than Modifying this core functionalities and making it more specific, I would recommend, on the basis of the Open/Closed principle, that you should freeze your code features and write your customer specific functionalities over it without corrupting the core.
Now to answer your question on what kind of structure you may follow. I would recommend that you create a library project of your core functionalities and make different client specific projects that would include your core functionalities as a library project.
It won't make a difference if your application is using the same db as your core application provided all your applications uses it, else it should not be in your core application in the first place.
Hope this explanation help you.
Update:
My friend pointed out that I may not have understood the question right. So rather than correcting my old post(...which may be useful for others) I am updating it.
So if I understand it right, you have an ERP project which you may not have coded. The right approach, according to me,still would be that you build over this existing code. Rather than making changes on this project, include it as a library because if the project is downloaded from a reliable source, you will have the benefit of getting the updated version as and when it is available.
This is kind of a design philosophy question. Here are a couple choices that might give you ideas:
You could look into making your core application code/features into a custom library. Then your new core application is just a simple wrapper that includes the custom library. Your additional features for a specific customer could then be a different app that also references the core library but will include additional features. There are lots of tutorials on how to turn your app into a custom library. You would end up with different apps that target different a customers. (A tip that took a while for me to uncover is that if you have a resource name in your custom library you can "override" it by using the same name in the app that includes the library. Another tip is that you need to essentially duplicate the manifest of the library in the app by listing all the activities in the library that would be used by the app.) I haven't tried this but it might be that your additional features are each libraries that are included in different apps.
You could have an key the user inputs that will unlock certain features. You could save this as a shared preference so that they don't need to keep entering the key. This approach has the benefit that you can "reuse" features for other clients without any more implementation other than determining which client gets what feature. The majority of users just wouldn't have a key to unlock anything.
Both these solutions should use the same db since they would be calling the same core classes, etc.
Another possible solution is to create a Library Project. Put your core ERP app code inside the library Project, and then create different project for different customers. Each one of these projects will also use the same library project.
Your core library project could expose an api to dynamically register new features (Such as a menu that can expose new menu items).