I have an app that has a lot of data that I need between the pages, such as:
design settings, user parameters, scanner access, printer queue, multiple things that got calculated and formed on one page and will be used on the others.
The general idea of the app is: you quickly select options or input data on each page and then it forms an order, sends it and prints it.
I have several repositories for different things but I can't get how to give access to them from the destination-fragments.
I'm pretty new to Android so I'm trying to find the best way to build this system but failing to do so.
What I found so far:
Room - I don't think so. I honestly tried it for several weeks but loading and saving data is unbearably slow especially when it's just a bunch of menu-pages flipping one after another. Also, I don't need to save data locally between the sessions, so it kind of misses the point of the local database.
Send some simple strings/numbers between the fragments - serialization/deserialization of everything I need for each menu doesn't sound great.
ViewModel factory - this way you need to create and store the ViewFactory somewhere and then access it from each fragment and then build a new ViewModel with it. Kind of might work but looks weird. How should it work? We have a link to the Factory in the "main" ViewModel and then get a link to this "main" app's VM, read the factory and then init local fragment's VM?
One big application's ViewModel - doesn't sound right: too big, too bulky.
Singleton(s) - that's just sad.
Dependency injection - I didn't try Dagger yet (going to, right now). Is it the thing I'm looking for?
I tried to google a lot on this topic but all of the answers look like: "here's how to pass a simple string between the screens", how do people organize the more complex applications? Maybe there's a more sophisticated way to split the application state into some kind of services or other terms that I'm missing.
Could you please help me to understand the proper application architecture in terms of state and data?
I think that your solution is something between a session implementation (in memory or using Room) and a ViewModel for the parts where a screen depends on another. If it is a flow I recommend you to use a way to share the ViewModel between the fragments like this or this (which I use and recommend) and then setting it as a state for the rest of the flow, leading to shared data that survives some config changes. If you need the settings surviving throughout the app execution you should implement a session using a simple class singleton or a Room implementation.
Related
I've given a bank application which I should modify so the balance of an account gets updated on every GUI screen. This should be done with RMI(Observable) in my example. I already made this work, at least, I'm almost certain about that.
There is a REMOTE interface called IBankingSession.
This REMOTE interface should have a method like setGUI(BankSessionController) or something like this. But, This isn't possible because the JavaFX parts aren't Serializable. The IBankingSession doesn't have any relationship to a GUI.
How can I link an instance of IBankingSession to this GUI? So I can update the GUI from this instance? It also feels weird to make a method like setGUI in a REMOTE interface. Because the GUI is of course, on the same screen as where the session is created.
I'm curious for some good idea's. Thanks in advance.
IBankingSession session = desk.logIn(tfAccount.getText(), tfPassword.getText());
First of all: you don't want to link your "remote" thing directly to your local clients that make use of it. That IBankingSession has no business knowing anything about the fact that your client wants to use JavaFx to put something on the user screens.
Instead, try something like this: define an interface that allows for callbacks (in other words: some kind of "push" model):
A client registers with the remote server; telling it: "I am interested in balance updates".
Then, upon a "balance" update, the remote service pushes that information to each client.
Now each client will be notified; and can then decide what to do with incoming updates; for example update some JavaFx UI component; or maybe, to log them into some persistent storage - giving you one mechanism that might be useful for a huge variety of different use cases.
You shouldn't be using observables at all, and certainly not over a network.
As far as RMI goes, you should strenously avoid anything in the nature of a client-side callback. There are firewall problems, latency problems, connectivity problems, ... every kind of thing that could cause your client to misfire.
You need to completely rethink this. It is not a viable design.
I'm trying to make a design based on the Uncle Bob's Clean Architecture in Android.
The problem:
I'd like to solve is how to make the changes generated in one repository to be reflected in other parts of the app, like other repositories or Views.
The example
I've designed a VERY simplified example for this example. Please notice that boundary interfaces has been removed to keep the diagrams small.
Imagine an app that shows a list of videos (with title, thumnail and like count), clicking a video you can see the detail (there you can like/dislike the video).
Additionally the app has an statistics system that counts the number of videos the user liked or disliked.
The main classes for this app could be:
For the Videos part/module:
For the Stats part/module:
The target
Now imagine you check your stats, then navigate the list of videos, open the detail of one, and click the like button.
After the like is sent to the server, there are several elements of the apps that should be aware of the change:
Of course the detail view, should be updated with the changes (this can be made through callbacks so no problem)
The list of videos should update the "likes" count for the given video
The StatsRepository may want to update/invalidate the caches after voting a new video
If the list of stats is visible (imagine a split screen) it should also show the updated stats (or at least receive the event for re-query the data)
The Question
What are the common patterns to solve this kind of communication?
Please make your answer as complete as you can, specifying where the events are generated, how they get propagated though the app, etc.
Note: Bounties will be given to complete answers
Publish / Subscribe
Typically, for n:m communication (n senders may send a message to m receivers, while all senders and receivers do not know each other) you'll use a publish/subscribe pattern.
There are lots of libraries implementing such a communication style, for Java there is for example an EventBus implementation in the Guava library.
For in-app communication these libraries are typically called EventBus or EventManager and send/receive events.
Domain Events
Suppose you now created an event VideoRatedEvent, which signals that a user has either liked or disliked a video.
These type of events are referred to as Domain Events. The event class is a simple POJO and might look like this:
class VideoRatedEvent {
/** The video that was rated */
public Video video;
/** The user that triggered this event */
public User user;
/** True if the user liked the video, false if the user disliked the video */
public boolean liked;
}
Dispatch events
Now each time your users like or dislike a video, you'll need to dispatch a VideoRatedEvent.
With Guava, you'll simply pass an instantiated event object to object to EventBus.post(myVideoRatedEvent).
Ideally the events are generated in your domain objects and are dispatched within the persisting transaction (see this blog post for details).
That means that as your domain model state is persisted, the events are dispatched.
Event Listeners
In your application, all components affected by an event can now listen to the domain events.
In your particular example, the VideoDetailView or StatsRepository might be event listeners for the VideoRatedEvent.
Of course, you will need to register those to the Guava EventBus with EventBus.register(Object).
This is my personal 5cents and maybe not closely enough related to your example of "The Clean Architecure".
I usually try to force a kind of MVC upon androids activities and fragments and use publish/subscribe for communication. As components I have model classes that handle business logic and the data state. They data changing methods are only to be called by the controller classes which usually is the activity class and also handles session state. I use fragments to manage different view parts of the application and views under those fragments (obviously). All fragments subscribe to one or more topics. I use my own simple DataDistributionService which handles different topics, takes messages from registered publishers and relays them to all subscribers. (partly influenced by the OMGs DDS but MUCH MUCH more primitive) A simple application would only have a single topic e.g. "Main".
Every part of view interaction (touches etc) is handled by its fragment first. The fragment can potentially change a few things without sending notifications. E.g. switching the subrange of rendered data elements if the rest of the app does not need to know/react. Otherwise the fragment publishes a ViewRequest(...) containing the necessary parameters to the DDS.
The DDS broadcasts that message and at some point reaches a controller. This can simply be the main activity or a specific controller instance. There should be only ONE controller so that the request is only handled once. The controller basically has a long list of request handling code. When a request arrives the controller calls to the business logic in the model. The controller also handles other view related things like arranging the view (tabs) or starting dialogs for user input (overwrite file?) and other things that the model is not supposed to know about but influences (Throw new NoOverWritePermissionException())
Once the model changes are done the controller decides if an update notification has to be send. (usually it does). That way the model classes do not need to listen or send messages and only take care of busines logic and consistent state. The update notification ist broadcasted and received by the fragments which then run "updateFromModel()".
Effects:
Commands are global. Any ViewRequest or other kind of request can be send from anywhere the DDS can be accessed. Fragments do not have to provide a listener class and no higher instance has to implement listeners for their instanced fragments. If a new fragment does not require new Requests it can be added without any change to controller classes.
Model classes do not need to know about the communication at all. It can be hard enough to keep consistent state and handle all the data management. No message handling or session state handling is necessary. However the model might not be proteced against malicous calls from the view. But that is a general problem and cannot really be prevented if the model has to give out references at some point. If your app is fine with a model that only passes copies/flat data its possible. But at some point the ArrayAdapter simply needs access to the bitmaps he is supposed to draw in the gridview. If you cannot afford copies, you always have the risk of "view makes a changing call to the model". Different battlefield...
Update calls might be too simple. If the update of a fragment is expensive (OpenGL fragment reloading textures...) you want to have more detailed update information. The controler COULD send a more detailed notification however it actually should not have to/be able to know what parts of the model exactly changed. Sending update notes from the model is ugly. Not only would the model have to implement messaging but it also gets very chaotic with mixed notifications. The controler can divide update notifications and others a bit by using topics. E.g. a specific topic for changes to your video resources. That way fragments can decide which topics they subscribe to. Other than that you want to have a model that can be queried for changed values. Timestamp etc. I have an app where the user draws shapes on canvas. They get rendered to bitmaps and are used as textures in an OpenGL view. I certainly don't want to reload textures everytime "updateFromModel()" is called in the GLViewFragment.
Dependency Rule:
Probably not respected all the time. If the controller handles a tab switch it can simply call "seletTab()" on a TabHost and therefore have a dependency to outer circles. You can turn it into a message but then it is still a logical dependency. If the controller part has to organize some elements of the view (show the image-editor-fragment-tab automatically after loading an image via the image-gallery-fragmen-tab) you cannot avoid dependencies completely. Maybe you can get it done by modelling viewstate and have your view parts organize themselves from viewstate.currentUseCase or smth like that. But if you need global control over the view of your app you will get problems with this dependency rule I'd say. What if you try to save some data and your model asks for overwrite permission? You need to create some kind of UI for that. Dependency again. You can send a message to the view and hope that a DialogFragment picks it up. If it exists in the extremely modular world described at your link.
Entities:
are the model classes in my approach. That is pretty close to the link you provided.
Use Cases:
I do not have those explicitly modelled for now. Atm I am working on editors for videogame assets. Drawing shapes in one fragment, applying shading values in another fragment, saving/loading in a galleryfragment, exporting to a texture atlas in another one ... stuff like that. I would add Use Cases as some kind of Request subset. Basically a Use Case as a set of rules which request in which order are allowed/required/expected/forbidden etc. I would build them like transactions so that a Use Case can keep progressing, can be finished, can be cancelled and maybe even rolled back. E.g. a Use Case would define the order of saving a fresh drawn image. Including posting a Dialog to ask for overwrite permission and roll back if permission is not give or time out is reached. But Use Cases are defined in many different ways. Some apps have a single Use Case for an hour of active user interaction, some apps have 50 Use Cases just to get money from an atm. ;)
Interface Adapters:
Here it gets a bit complicated. To me this seems to be extremely high level for android apps. It states "The Ring of Interface Adapters contains the whole MVC architecture of a GUI". I cannot really wrap my head around that. Maybe you are building far more complicated apps than I do.
Frameworks and Drivers:
Not sure what to think of this one. "The web is a detail, the database is a detail..." and the graphic contains "UI" in this Ring as well. Too much for my little head
Lets check the other "asserts"
Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
Hm yeah well, if you run your own architecture that is what you get.
Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.
As in my approach model classes neither know about controllers or views nor about the message passing. One can test state consistency with just those classes alone.
Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
Again a bit overkill for android is it not? Independence yes. In my approach you can add or remove fragments as long as they do not require explicit handling somewhere higher up. But replacing a Web UI with a console UI and have the system run like before is a wet dream of architecture freaks. Some UI elements are integral part of the provided service. Of course i can easily swap the canvas drawing fragment for a console drawing fragment, or the classic photo fragment for a 'take picture with console' fragment but that does not mean the application still works. Technically its fine in my approach. If you implement an ascii console video player you can render the videos there and no other part of the app will necessarily care. However it COULD be that the set of requests that the controller supports does not align well with the new console UI or that a Use Case is not designed for the order in which a video needs to be accessed via a console interface. The view is not always the unimportant presenting slave that many architecture gurus like to see it as.
Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
Yeah, so? How is that directly related to your architecture? Use the right adapters and abstraction and you can have that in a hello world app.
Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.
Same here. If you want modularized independent code then write it. Hard to say anything specific about that.
I have a web service layer that is written in Java/Jersey, and it serves JSON.
For the front-end of the application, I want to use Rails.
How should I go about building my models?
Should I do something like this?
response = api_client.get_user(123)
User user = User.new(response)
What is the best approach to mapping the JSON to the Ruby object?
What options do I have? Since this is a critical part, I want to know my options, because performance is a factor. This, along with mapping JSON to a Ruby object and going from Ruby object => JSON, is a common occurance in the application.
Would I still be able to make use of validations? Or wouldn't it make sense since I would have validation duplicated on the front-end and the service layer?
Models in Rails do not have to do database operation, they are just normal classes. Normally they are imbued with ActiveRecord magic when you subclass them from ActiveRecord::Base.
You can use a gem such as Virtus that will give you models with attributes. And for validations you can go with Vanguard. If you want something close to ActiveRecord but without the database and are running Rails 3+ you can also include ActiveModel into your model to get attributes and validations as well as have them working in forms. See Yehuda Katz's post for details on that.
In your case it will depend on the data you will consume. If all the datasources have the same basic format for example you could create your own base class to keep all the logic that you want to share across the individual classes (inheritance).
If you have a few different types of data coming in you could create modules to encapsulate behavior for the different types and include the models you need in the appropriate classes (composition).
Generally though you probably want to end up with one class per resource in the remote API that maps 1-to-1 with whatever domain logic you have. You can do this in many different ways, but following the method naming used by ActiveRecord might be a good idea, both since you learn ActiveRecord while building your class structure and it will help other Rails developers later if your API looks and works like ActiveRecords.
Think about it in terms of what you want to be able to do to an object (this is where TDD comes in). You want to be able to fetch a collection Model.all, a specific element Model.find(identifier), push a changed element to the remote service updated_model.save and so on.
What the actual logic on the inside of these methods will have to be will depend on the remote service. But you will probably want each model class to hold a url to it's resource endpoint and you will defiantly want to keep the logic in your models. So instead of:
response = api_client.get_user(123)
User user = User.new(response)
you will do
class User
...
def find id
#api_client.get_user(id)
end
...
end
User.find(123)
or more probably
class ApiClient
...
protected
def self.uri resource_uri
#uri = resource_uri
end
def get id
# basically whatever code you envisioned for api_client.get_user
end
...
end
class User < ApiClient
uri 'http://path.to.remote/resource.json'
...
def find id
get(id)
end
...
end
User.find(123)
Basic principles: Collect all the shared logic in a class (ApiClient). Subclass that on a per resource basis (User). Keep all the logic in your models, no other part of your system should have to know if it's a DB backed app or if you are using an external REST API. Best of all is if you can keep the integration logic completely in the base class. That way you have only one place to update if the external datasource changes.
As for going the other way, Rails have several good methods to convert objects to JSON. From the to_json method to using a gem such as RABL to have actual views for your JSON objects.
You can get validations by using part of the ActiveRecord modules. As of Rails 4 this is a module called ActiveModel, but you can do it in Rails 3 and there are several tutorials for it online, not least of all a RailsCast.
Performance will not be a problem except what you can incur when calling a remote service, if the network is slow you will be to. Some of that could probably be helped with caching (see another answer by me for details) but that is also dependent on the data you are using.
Hope that put you on the right track. And if you want a more thorough grounding in how to design these kind of structures you should pick up a book on the subject, for example Practical Object-Oriented Design in Ruby: An Agile Primer by Sandi Metz.
In my project I am to provide some functions which can be provided using session and application variable like in c#.
MY information is confidential so can not be stored in files like xml
Thanks in advance.
Edit : 1-
Solution for session variable i've found called sharedpreference but don't know how to use please tell me
how to initiallize it and
set it from other class and
get the value from some other?
?...?...?..
First of all, your application can basically die at any time, because it can be killed off by the Android scheduler after your app sits in the background for a while and the platform needs more memory.
That being said, storing your data in a global Application class is generally considered a bit hacky. Instead, the way you use this depends on how you are going to access the application. It's a pretty commonly accepted thing that a lot of apps keep things like their OAuth tokens in SharedPreferences (though I'm not sure exactly how kosher this is). What you might do is keep your session variable in an Application class, and then -- whenever the app dies -- simply reauthenticate. This is probably good practice anyway, as after that long someone may have picked up the phone, etc...
However, you seem to be under the impression that SharedPreferences can be read by anyone. This is incorrect, see this. Now, if you have a rooted phone, sure, then there's a way around that, but this is always going to be an issue, on a rooted phone you should basically consider that you don't really have any security at all...
Application class is there for you. use it and save your application level data, like this:
public class WhatEverApp extends Application
{
String mApplicationLevelVar = "Hello";
}
WhatEverApp will be the name of your app used in manifest.xml
Look here for detailed discussion on Application class.
My Java application is not very big, but I would like to do it the "right way". Looking for suggestions to not make a big mess...
I am using Swing, the Swing Application Framework and H2 database.
It is a single frame application with different tabs. Most tabs will reflect some aspects of the data in the database. Some of them will be able to change it. Some tabs will have buttons or actions that will redirect to another tab... that's basically it.
I would like to keep things clean, rather portable and flexible (can enable disable some tabs for example or add some easily).
Here are the questions :
1) How to have tabs "refreshed" when the database content changes ? Implement some Listener interface ? Should I define that interface or there is something already existing I can reuse ?
2) How to "link" the different tabs together so that it is easy to jump from one to another (and may have to carry some argument to setup the destination tab to the right "view")
3) If I set some preference with some filters in another part of the application, how do I share such settings with the whole application ?
And when I ask "how to", I really mean "what is the best way"... I can get that working already... just looking for the right tool to use, design pattern or such.
There are different strategies of gui application building. Here some article about.
If using swing, you can use tabbed pane to have a tabular layout.
Implement a listener (as you are planning). Have a look at observable interface in Java.
You can implement a singleton(eg PreferenceManager class) to hold the preference and access it across the application to access properties.
Do you really want a push model where the server has to maintain a connection to every client and then update them all when anything changes? This is feasible with a handful of clients, but quickly becomes problematic. It's probably better to use a pull model, where the client manually (periodically?) asks for updates. This is also a good way to use optimistic locking with a last_modified field in the DB. Attempt an update, if it's changed since you last reloaded, warn the user and allow them to overwrite / merge.
As for Swing in general, best practice is to factor everything out that's not GUI related into core classes ('business logic') that fire off events. Register all your Swing classes as the appropriate event listener and update the gui appropriately (SwingUtilities.invokeLater() is your friend here).