As per clean architecture, design Interactor is part which contains all business logic. The term Interactor is quite confusing to me. Interactor seems to me like interacting between two different layers like data and presenter.
Is it the right term to use?
Can anyone please clear the purpose of Interactor? Which pattern does it follow?
If Interactor is not what it seems to me then what is the design pattern for
layer-layer interaction?
An Interactor is a design pattern that has nothing to do with "business logic" concept. Without going in deeper level of detail the Interactor pattern is an extension of the Command pattern; Each "business logic" object is treated as a "black box", a simple instruction to be executed for the client, decoupling the object that invokes the operation from the one that knows how to perform it. (refer to the bibliography for extended explanation).
In the android enviroment there is a simple 'rule' that demands to the programmer to do long time consuming task in a background thread, so the interactor patterns extends the "Command pattern" adding a layer of threading. All this complex stuff is implemented to create a "clean architecture" which entails a code that is scalable, maintainable and (arguably) understandable.
About the question .. ¿what is the design pattern for layer-layer interaction? It could have more than one rigth answer, depends of the situation. You could use a simple Interface as the entry point, so you could use the Adapter pattern, or maybe the Facade pattern, or if you want to do something more advanced you could implement an eventbus system.
Source:
Design patterns explained simply - auth Alexander Shvets. page 14 (Adapter), page 32 (Command), page 47 (Facade)
In the clean architecture approach, the Use Case Interactor is a layer that express the specific business rules. The Use Case Interactor interacts with the Entities (agnostic business rules) to achieve the Use Case intention. Entities can be used in another applications, once they are agnostics, on the other hand, the Use Case Interactors are specific application objects.
Can be found in the Clean Architecture book by Robert C. Martin at chapter 20
If you're familiar with domain driven design, then an Interactor can be compared to an Application Service. Also, it is incorrect to say "As per clean architecture, design Interactor is part which contains all business logic." On the contrary, Entities would contain the business (application-agnostic) logic; whereas Interactors would contain the application-specific logic. The Interactors would call the Entities to fulfill a use case, where a use case might be something like Create Purchase Order.
Going back to using Clean Architecture terms that Robert Martin (Uncle Bob) uses in his training video Architecture, Use Cases, and High Level Design, Uncle Bob says the following:
Interactors are application-specific. That means that any application specific business rule belongs inside an interactor. The interactors achieve their goals with application-specific logic that calls the application-agnostic logic within the entities. For example, the CreateOrderInteractor invokes both the constructor and the GetId method of the OrderEntity. Clearly, these two methods are application-agnostic. It's the interactor that knows how to call those two methods to achieve the goal of the use case.
For your observation that the Interactor seems like it is interacting between two different layers like data and presenter, that job actually belongs to the Boundary. The Boundary sits between the delivery mechanism and the Interactor, where the delivery mechanism might be a desktop application, MVC app, API, etc. This keeps the actual application and business code separate and transferable from one delivery mechanism to another.
He also has a nice diagram in the Extras section showing the interaction if you purchase the video. It looks something like the following:
Delivery Mechanism ==> Boundary ==> Interactor ==> Entity
P.S. The video referenced above is highly entertaining and informational.
From what I'm reading, it's the equivalent of the Presenter in the Model View Presenter (MVP) architecture.
It does business logic, not store or display data. It create a separate layer independent of how or where data is stored or displayed. It only cares about inputs and outputs in any format. It could be used in a combination of the Observer, Adapter, and Façade patterns to be an interface for callbacks, a generic extension point of the code, and a decoupled entry point for any non UI or data-storage usage, respectively.
I assume it is called an Interactor because the View interacts with it to calculate values and refresh any displayed UI elements and it interacts with the Model objects to extract data. It could also interact with a database for CRUD operations, but I think that's mostly addressed in the Repository Pattern as that isn't really business logic.
Interactors provides implementations for various use cases. Ideally, there should be one interactor per use case but it may differ according to the scale of your application.
Now, why it doesn't make sense for every application? Imagine you have two applications. In the first app, you just need to read a user. In the other application, you just update the very same user. You would have two different interactors like GetUserInteractor and UpdateUserInteractor. If you think about it, UpdateUserInteractor would make no sense for the first application (and vice versa), right? But your business/domain logic for both applications can still be the same where the implementations of both services (read and update) are included, for example, in the regarding business/domain object (or as separate use-case objects). These objects obviously encapsulate application agnostic business rules as they can be plugged under two or more different applications.
The communication takes place between the app and users is often application-specific. As others already mentioned, you can have your interactors execute commands on user actions. Or you can go for another similar way. But the command pattern is really convenient and arguably make the whole code more consistent, uniform, and easy to understand.
Last but not least, the other important aspect of interactors are 'boundary interfaces' which are the classes that polymorphically deployed for both input and output delivery.
(PS: For example, in Android, with the new architecture components, Fragment/Activity can be thought as an implementation of the input boundary as you deliver input events down to your business logic (or domain model) - it's the controller. LiveData is more like the output boundary implementation as it uses observer pattern under the hood and deliver the data back to the UI through the interactor. In this case, I think this makes the ViewModel a strong candidate for being the interactor since it receives the input events (and commands corresponding those events) and also contains the LiveData instance to be observed. Are all these decoupled nice, or, polymorphically deployed? Well, this is mostly related to your design. And with coroutines, now it seems like there's no need for callbacks/listeners - so another dimension into this picture.)
This is my take. I hope it's clear.
It's MVP pattern. Yes as you said it's mediator between presenter and data(as a form of rest call or shared preference or Sqlite).
Related
I am using Kotlin Corountines with MVVM pattern and faced a problem: The data processing part is being done inside the ViewModel. While the repository seems not really necessary. When the application needs to call many APIs, the ViewModel will swell. What is everyone's solution to this problem? Thank you
The repository is needed, because in the case when you have a large app and gave too much responsibility to the ViewModel it's broke the separation of concerns principle.
Basically in the Andorids Guide to app architecture :
A first idea for implementing the ViewModel might involve directly
calling the Webservice to fetch the data and assign this data to our
LiveData object. This design works, but by using it, our app becomes
more and more difficult to maintain as it grows. It gives too much
responsibility to the UserProfileViewModel class, which violates the
separation of concerns principle. Additionally, the scope of a
ViewModel is tied to an Activity or Fragment lifecycle, which means
that the data from the Webservice is lost when the associated UI
object's lifecycle ends. This behavior creates an undesirable user
experience.
Instead, our ViewModel delegates the data-fetching process to a new
module, a repository.
And direct answer for your question:
Even though the repository module looks unnecessary, it serves an
important purpose: it abstracts the data sources from the rest of the
app. Now, our UserProfileViewModel doesn't know how the data is
fetched, so we can provide the view model with data obtained from
several different data-fetching implementations.
Basically, you can give all work to your ViewModel, but it's not recommended.
If you work/planning to work as a dev, maintaining your code, make it flexible to change and understandable for others is also important and usually, everyone appreciates this
What is Use Case and Interactor in context of Clean Architecture. I read that use case contains business logic, but why use case if there is a presentation layer where in presenter we can put business logic.
In Clean Architecture "use case" and "interactor" means the same: it is the component which contains business logic. The presenter in this architecture does not contain any business logic. The job of the presenter is to map data structures returned by the use case interactor into data structures most convenient for the view.
"Use Case" is a term that, to my knowledge, was coined or at least formalized by computing pioneer Ivar Jacobson. It is a concept the stresses a particular view on the system, namely a user-centric view, i.e. he asks, what does the user want to achieve with a system? One interaction of one user with one system end-to-end is a use case.
I haven't heard the term "Interactor" in this context but maybe it's just what Jacobson calls the "Actor." The words are similar enough.
Let's say you want to transfer money. You open the transfer web page, enter the amount, select the beneficiary or enter a new one, you provide a one-time password, and you see that your transfer is in progress. This is one use case.
Use cases can have multiple scenarios. In the example, what happens if you don't have the required funds? What happens if your beneficiary information fails to validate? What happens if you enter the one-time password incorrectly several times? What happens if you try to transfer a very large amount or many small amounts in a short time?
Also, use cases can have preconditions, e.g. you have to be already authenticated to even begin with the money transfer use case. The authentication would be specified elsewhere and just documented as a precondition, to keep things neat and tidy. Post-conditions can also specify the state of the system after the use case is complete.
And finally, the actor performing the use case might not be a person at all--it could be another system.
Recently, I've heard the term "customer journey" that seems to mean the same or at least a similar concept.
Bottom line: "Use case" is not a term that is in any way specific to the implementation of a system. Rather, use cases are used to look at a system from the outside and describe its behavior from a user point of view.
A use case is a methodology used in system analysis to identify, clarify, and organize system requirements. The use case is made up of a set of possible sequences of interactions between systems and users in a particular environment and related to a particular goal. It consists of a group of elements (for example, classes and interfaces) that can be used together in a way that will have an effect larger than the sum of the separate elements combined. The use case should contain all system activities that have significance to the users. A use case can be thought of as a collection of possible scenarios related to a particular goal, indeed, the use case and goal are sometimes considered to be synonymous.
A use case (or set of use cases) has these characteristics:
Organizes functional requirements
Models the goals of system/actor (user) interactions
Records paths (called scenarios) from trigger events to goals
Describes one main flow of events (also called a basic course of
action), and possibly other ones, called exceptional flows of events
(also called alternate courses of action)
Is multi-level, so that one use case can use the functionality of
another one.
Use cases can be employed during several stages of software development, such as planning system requirements, validating design, testing software, and creating an outline for online help and user manuals.
When using Firebase Cloud Messaging on Android, it is often desirable to notify the current Activity of an incoming push notification. One of the recommended ways to do this has been to use LocalBroadcastManager to send an Intent from the FirebaseMessagingService implementation to the Activity (StackOverflow example answer).
However, as of version 1.1.0-alpha01 (2018-12-17), LocalBroadcastManager is deprecated:
LocalBroadcastManager is an application-wide event bus and embraces layer violations in your app: any component may listen events from any other. You can replace usage of LocalBroadcastManager with other implementation of observable pattern, depending on your usecase suitable options may be LiveData or reactive streams.
While it is highly likely that this class will remain available for a while longer, I would like to start cleaning up our applications anyway, so I want to migrate to something better before Google actually removes the old way.
Right now, there are two main roles that these local broadcasts have in our apps:
Update the UI with the new data from the push notification. The way this worked was that each Activity that cares about the incoming push data has a broadcast receiver that listens for the appropriate message and updates its own view data.
Force the user to log out if the server sends a notification to end the session. This works with each activity having an instance of a broadcast receiver that listens for a logout event, ends the Activity, and starts the Login Activity.
As I see it, these use-cases have issues with both of their suggested alternatives:
LiveData is easiest to use in an Activity or Fragment as part of a ViewModel. However, ViewModel is only meant to be used from those classes that directly deal with the UI. Accessing the ViewModel from within the FirebaseMessagingService takes an ugly hack and is a really bad idea from an architectural perspective. Also, different activities and fragments have different ViewModel objects, and I don't want the service to need to access them all.
I can create a Kotlin object (a.k.a. Singleton) with a bunch of LiveData properties, have the FirebaseMessagingService update those LiveData objects from the incoming messages, and have the Activity observe those changes and copy them into its own ViewModel's LiveData properties. The problem with that is twofold: first, it requires me to have two identical LiveData objects for each piece of data, one in the ViewModel and one in the object; and second, it doesn't help me with handling the "log out event", because LiveData is meant to handle changing data, not listening to a stream of events. (I may be able to handle the second issue using this LiveData Event Wrapper, but that still feels like a bad hack over something that isn't meant to work this way.)
While reactive streams, such as RxJava, will probably do what I need, I already forced my team to learn Kotlin, Android Databinding, Android ViewModel, and a bunch of other new stuff in the last few months, and I don't think they can take much more. RxJava is also a large thing to add for just this one use, and we have no plans to rewrite the entire application to take advantage of it in order to justify its addition.
One suggestion I found was to use Kotlin Coroutines with Channels or Flows. These can be used very similar to reactive streams, but (unlike RxJava) are intended to be used with Kotlin and benefit from Kotlin's improvements over Java. This option is especially attractive now that Google has announced that they are focusing on Kotlin for Android development instead of Java.
While this seems to me to be the best option, I have not managed to find any feedback from others about whether it works and if there are side-effects and/or pitfalls to such an implementation. The only thing I found was an open issue on the kotlinx.coroutines repository about the need for providing an example of an application like this. While I'd love to contribute such an example, I don't think I know enough about it to create a good example, and I don't want my production apps to be the guinea pig. I also don't know whether it is better (or proper) to use explicit couroutines with Channel or to use suspend with Flow for this case.
In summary:
Are Kotlin Coroutines and their associated concurrency structures a good way to handle communication between Android Service and Activity?
If yes, which Kotlin type makes more sense to use, Channel or Flow?
Coroutines don't really help with the handoff of data from one software component to another. They help with the processing multiple units of asynchronous work using syntax that appears as if they were synchronous. That's the bottom line for coroutines. They're analogous to async/await syntax in JavaScript. While you might use a coroutine to access data from asynchronous sources, it doesn't give you any primitves to proxy that data on to other components.
LiveData probably works just fine for what you're trying to do. Don't conflate ViewModel with LiveData - they solve different problems. While you're correct that ViewModel should only be accessed by code that deals with UI, that guideline doesn't extend to LiveData. It's perfectly reasonable to expose a LiveData that reflects current data from FirebaseMessagingService that is later picked up by a ViewModel, transformed, and passed on to a view. This LiveData could be a singleton, or obtained via whatever dependency injection infrastructure you choose.
Bear in mind that LiveData is really only supposed to be used for managing changes in state. It's not a "stream" of data that your app can listen to. You will need to make sure that your infrastructure is state-based in order for this to work out well. FCM itself is not state-based, but if you want your views to respond to messages from FCM, you'll need to retain enough context between each message to make sure your UI responds consistently to new messages (or the lack of messages altogether).
I have been reading some articles about the clean architecture, and how it can be implemented in android. I saw the sample app which shows its Android Implementation. Also, I went through a nice talk on Clean architecture on Android
So, I kind of understand most of the concepts, but there is some clarity that I would like to get on certain things.
As per my Understanding,
The View layer is the outer layer which deals with the UI, and
framework related stuff
The presenter is the direct communicator for the view, which accepts user inputs, and executes certain use cases based on this by passing it to the use case layer or the interactor layer.
Interactor executes the use-case, give it back to the callback sent by presenter,
Presenter again converts this result into a view understandable data structure (a ViewModel) and just pass it back to the view.
I am not listing more details about the inner layers like repository since my question is related to the above-mentioned steps
Here, does the presenter have the only job of acting as a mediator between UseCases and UI, as a data dispatcher?
Does it only do the view model to use case model conversion and vice-versa?
The input validation logics rely on which layer? Can it be inside the presenter? For example, if we take a small use case of a sign-up process,
Once the user entered the details and clicked sign-up button, and data sent to the presenter, is it like
Presenter validates the input values if any error is there notify
the view
If values are proper, convert it to a use case model, and execute
certain use case, and once the result is given by the interactor,
again convert to view model, send it to view.
And the second question is, who controls the navigation? The View or the Presenter or the UseCase?
who decides where to go next?
For example - Consider a use case of a login process, Where user will enter the credentials and click OK.
On successful login,
If users e-mail is not verified, go to email verify screen
If users profile is not completed, set-up the profile then only go to home screen
If user is new, show new offers screen, else directly go to home screen
So, who is responsible for making these decisions on which screen to go next? Is it the presenter, which decides and navigate the view accordingly? Or is it the use case handlers responsibility to inform the presenter what is the next State?
Sorry for making the question too long, but I just wanted to elaborate my current understandings. Thanks in advance
Here, does the presenter have the only job of acting as a mediator
between UseCases and UI, as a data dispatcher?
Yes
The input validation logics rely on which layer? Can it be inside the
presenter?
validation should rely on business layer not the presentation, can it be inside the presenter? sure it could, but what if you have multiple screens that take similar inputs, do you have to repeat your validation logic inside each presenter! you can argue that you can make a base presenter, but it's not the perfect solution, because presenter should have one purpose.
And the second question is, who controls the navigation? The View or
the Presenter or the UseCase?
do you consider the navigation is part of the Domain or the presentation or the data layer, it's likely related to the presentation layer, but you could make a small component inside the presentation layer which is control the whole navigation generically, So you can use this component the moment you decide that you do need other platform and throw your activities away. you can find this approach in the sample you've mentioned.
EDIT:0
How you pass data between modules where they have different models?
you simply use mappers, and the reason is to make each module has its own models or entities, so it would be easy to test each module separately.
About presenter and view, let's say you want show error message, presenter decides why it would be shown, view decides how it would be shown.
I think the problem in understanding the clean code presentation layer with Android, that Activities and fragments aren't only view, they're also The process and the lifecycle which your code would be live in, clean code came along to separate spaghetti code on those Activities and fragments.
EDIT:1
adding to the last point, it's clear now that Google and the support team there made a great effort to make Activities and Fragments dummy views as possible via introducing the great set of libraries "Architecture components". I encourage anyone to check them out, even if you're using MVP, you'll find a great benefits.
how does a good architecture for an android app look like? Should all the "work/business logic" been done in a background service and the Activity communicates just with the service to query/fetch data from somewhere (local/distant)?
Would you implement the "service" that the Activity calls as a real Android-service? Or a POJO-Singleton that does the work (perhaps using background threads). Or instantiate background threads in your activity for time-consuming actions (query a webservice).
How do you abstract your data access the right way? Would you use a ContentProvider to access/abstract your data? How/From where should it be queried? Activity? Service? ..?
I've tried to search for a good app architecture design, but I only found how the Android architecture looks like, not how an Android app should look like.
So what's your opinion about that? What components of an Android application should communicate which each other to ensure best extensibility/encapsulation,...?
There's no one answer to this question. Good OO design isn't Android specific. I'd say that the rule is - if the framework gives you a high level object (such as Service in the case of Android) that fits your use case, use it. If you find yourself making POJO implementations of the same things you get for free with the framework, go with the framework.
As far as separation of concerns, this is standard OO stuff. Don't put anything in your Activity classes that isn't the job of the Activity. Over-stuffing the Activity with methods and properties that the Activity needs but aren't really the job of the Activity is bad - makes the intention of your Activity hard to understand.
I usually separate stuff into sub-packages in my apps.
com.myname.myproject.app - base classes, global application functionality
com.myname.myproject.net - network stuff, network related utils
com.myname.myproject.data - db helpers, providers, etc
com.myname.myproject.model - object model
etc.
As far as communication within your app...
I always have a custom Application class that I register in the manifest. This way, when I have controllers and helpers that need to be a "single instance", I don't have to do all that crazy thread safe singleton stuff...I just keep one global copy of.
RoboGuice is a dependency injection framework that makes this even easier to accomplish...definitely worth looking into. If this interests you, the Google Group for RoboGuice is great and is constantly filled with the creators of the framework who can basically answer anything you need.
As far as in-app communication, I use my single instance Controller and State classes to hold state and do common tasks, and I usually use BroadcastIntents to communicate back to Activities from Services