RESS - New architecture for mobile applications
Contrary to the provocative title, this is not a new architecture, but an attempt to translate simple and time-tested practices into newspeak, which is spoken by the modern Android community
Introduction
Recently it has become painful to look at what is happening in the world of development for mobile platforms. Architectural astronautics is thriving, every hipster considers it his duty to come up with a new architecture, and to solve a simple problem, instead of two lines, insert a few fashionable frameworks.
Ayishnye sites flooded tutorials on fashionable frameworks and over-architected architectures, but there is even no best practice for REST-clients for Android. Although this is one of the most frequent application cases. I want a normal approach to development, too, went to the masses. Therefore I am writing this article
this articles.
Scheme [/b]

And this is for every screen! My eyes hurt. I especially sympathize with those who at work with this have to face not on their own. For those who have implemented it themselves, I sympathize with slightly different reasons.
The new approach
Hey, I also want the fashionable name . Therefore, the proposed architecture is called RESS - R equest, E vent, S creen, S torage. The letters and names are picked up so stupidly for the word to be read. Well and not to create confusion with already used names. Well, with REST consonant.
At once I will make a reservation, this architecture for REST-clients. For other types of applications, it probably will not work.

1. Storage
The data warehouse (in other terms, Model, Repository). This class stores data and processes it (stores it, loads it, puts it into a database, etc.), as well as all data from the REST service first get here, parsed and saved here.
2. Screen
The application screen, in the case of Android is your Activity. In other terms, this is the usual ViewController as in MVC from Apple.
3. Request
The class that is responsible for sending requests to the REST service, as well as receiving responses and notifying about the response of the remaining components of the system.
4. Event
The link between the remaining components. For example, the Request sends an event about the response of the server, to those who subscribed to it. A Storage sends a data change event.
Here is an example of a simplified implementation. The code is written with assumptions and was not checked, so there may be syntax errors and typos
Request [/b]
public class Request
{
public interface RequestListener
{
default void onApiMethod1 (Json answer) {}
default void onApiMethod2 (Json answer) {}
}
private static class RequestTask extends AsyncTask
{
public RequestTask (String methodName)
{
this.methodName = methodName;
}
private String methodName;
@Override
protected String doInBackground (Void params)
{
URL url = new URL (Request.serverUrl + "/" + methodName);
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection ();
//
//Make the request and read the answer
//
return result;
}
@Override
protected void onPostExecute (String result)
{
//
//Parsim JSON from result
//
Requestr.onHandleAnswer (methodName, json);
}
}
private static String serverUrl = "myserver.com";
private static List
listeners = new ArrayList <>();
private static void onHandleAnswer (String methodName, Json json)
{
for (RequestListener listener: listeners)
{
if (methodName.equals ("api /method1")) listener.onApiMethod1 (json);
else if (methodName.equals ("api /method2")) listener.onApiMethod2 (json);
}
}
private static void makeRequest (String methodName)
{
new RequestTask (methodName) .executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void registerListener (RequestListener listener)
{
listeners.add (listener);
}
public static void unregisterListener (RequestListener listener)
{
listeners.remove (listener);
}
public static void apiMethod1 ()
{
makeRequest ("api /method1");
}
public static void onApiMethod2 ()
{
makeRequest ("api /method2");
}
}
Storage [/b]
public class DataStorage
{
public interface DataListener
{
default void onData1Changed () {}
default void onData2Changed () {}
}
private static MyObject1 myObject1 = null;
private static List
myObjects2 = new ArrayList <>();
public static void registerListener (DataListener listener)
{
listeners.add (listener);
}
public static void unregisterListener (DataListener listener)
{
listeners.remove (listener);
}
public static User getMyObject1 ()
{
return myObject1;
}
public static List
getMyObjects2 ()
{
return myObjects2;
}
public static Request.RequestListener listener = new Request.RequestListener ()
{
private T fromJson
(Json answer)
{
//
//Parsim or deserialize JSON
//
return objectT;
}
@Override
public void onApiMethod1 (Json answer)
{
myObject1 = fromJson (answer);
for (RequestListener listener: listeners) listener.data1Changed ();
}
@Override
public void onApiMethod2 (Json answer)
{
myObject2 = fromJson (myObjects2);
for (RequestListener listener: listeners) listener.data2Changed ();
}
};};
}
Screen [/b]
public class MyActivity extends Activity implements DataStorage.DataListener
{
private Button button1;
private Button button2;
@Override
protected void onCreate (Bundle savedInstanceState)
{
super.onCreate (savedInstanceState);
button1.setonclickListener ((View) -> {
Request.apiMethod1 ();
});
button2.setonclickListener ((View) -> {
Request.apiMethod2 ();
});
updateViews ();
}
@Override
protected void onpause ()
{
super.onpause ();
DataStorage.unregisterListener (this);
}
@Override
protected void onResume ()
{
super.onResume ();
DataStorage.registerListener (this);
updateViews ();
}
private void updateViews ()
{
updateView1 ();
updateView2 ();
}
private void updateView1 ()
{
Object1 data = DataStorage.getObject1 ();
//
//Here we update the required views
//
}
private void updateView2 ()
{
List
data = DataStorage.getObjects2 ();
//
//Here we update the required views
//
}
@Override
public void onData1Changed ()
{
updateView1 ();
}
@Override
public void onData2Changed ()
{
updateView2 ();
}
}
App [/b]
public class MyApp extends Application
{
@Override
public void onCreate ()
{
super.onCreate ();
Request.registerListener (DataStorage.listener);
}
}
Same schematics, but in terms of RESS, for understanding [/b]

It works like this: When a button is clicked, the requested method is jerked at the Request, Request sends a request to the server, processes the response and notifies the DataStorage first. DataStorage parse the response and cache the data in itself. Then Request notifies the current active Screen, Screen takes data from the DataStorage and updates the UI.
Screen subscribes and unsubscribes from the modem onResume and onpause, respectively. And also updates the UI in addition to onResume. What does it give? UvUnits come only to the current active Activity, no problems with processing the request in the background or turning Activity. Activity will always be up to date. Prior to the background activity, the notification will not reach, and upon returning to the active state, the data will be taken from the DataStorage. As a result, there are no problems with the rotation of the screen and the re-creation of the Activity.
And for all this missing defaults from the Android SDK.
Questions and answers to future criticism
1. What profit?
Real simplicity, flexibility, maintainability, scalability and minimum dependencies. You can always complicate a certain part of the system if you need to. A lot of data? Gently break the DataStorage into several. A huge REST API for the service? Do a few Request. Can they be too simple, slim and unfashionable? Take the EventBus. Are they looking askance in barbershop on HttpConnection? Well, take Retrofit. Bold Activity with a bunch of fragments? Just think that each fragment is Screen, or break it into subclasses.
2. AsyncTask is a mauve, take at least Retrofit!
Yes? And what problems does it cause in this code? Memory leaks? No, here AsyncTask does not store links to activations, but only a link to the statics method. The answer is lost? No, the answer always comes in the static DataStorage, until the application is killed. Trying to update the activates on a pause? No, notifications only come in the active Activity.
And how will Retrofit help? Just watch here . The author took RxJava, Retrofit and still sculpts crutches to solve a problem that RESS simply does not have.
3. Screen is the same ViewController! You need to separate the logic and the view, arrr!
Drop this mantra already. A typical client for a REST service is one large view for the server part. All your business logic is to set the required state for the button or text box. What are you going to share there? Speak so it will be easier to maintain? Support 3 files with 3 tons of code, instead of 1 file with 1 ton is easier? OK. And if we have activati with 5 fragments? We already have 3 x (5 + 1) = 18 files.
Separation on the Controller and View in such cases simply breeds a bunch of meaningless code, it's time to admit it already. Adding functionality to a project with MVP is especially fun: do you want to add a button handler? Ok, correct Presenter, Activity and View-interface. In RESS for this, I'll write a couple lines of code in one file.
But in large projects ViewController horribly grows? So you did not see big projects. Your REST client for the next site for ?000 lines is a small project, and ?000 lines are there only because each screen has 5 classes. Really great projects on RESS with 100+ screens and several teams of 10 people feel great. Just do a few Request and Storage. A Screen for fat screens contains additional Screen for large UI elements, for example, the same fragments. The project on MVP of the same scale will simply choke in the heap of presenters, interfaces, activations, fragments and non-obvious links. And the transition to VIPER in general will make the whole team quit one day.
Conclusion
I hope this article will encourage many developers to reconsider their views on architecture, not to produce abstractions and look at simpler and time-tested solutions of
It may be interesting
This publication has no comments.
weber
Author23-09-2018, 03:17
Publication DateDevelopment / Development of mobile applications
Category- Comments: 0
- Views: 304
Comments
Visit Our website If You Need Custom thanksgiving couple shirts, Shirts For Your Company, Family Or Friends & We’ll Cook Something Special for you!
Inursing test bank was very pleased to find this site.I wanted to thank you for this great read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you post.
You completed certain reliable points there. I did a search on the subject and found nearly all persons will agree with your blog.
nursing test bank
nursing test bank
Great post i must say and thanks for the information. Education is definitely a sticky subject. However, is still among the leading topics of our time. I appreciate your post and look forward to more.
nursing test bank
nursing test bank
So good! This web post provides knowledge, knowledge, good news, and is very useful. Thank you for everything Taxi Driver Jacket