Android architecture: Part 1 — mistakes we made in those years

This series of articles aims to outline the problems we may encounter when building an Android application architecture. I realized that no matter how difficult the process of implementing Android App architecture is, it turns out that these must be the basis for completing every excellent application. Each technology has its own natural evolution. Or rather, its community has undergone an evolutionary process. The early adopters of a new computer language or framework are enthusiasts. They just want to master the technology and complete some work as soon as possible. Often, new communities are small and have limited potential for knowledge transfer among developers, that is, everyone learns from their mistakes because there are no architectural guidelines available.

The pain point of early Android: does Google care? You can say that many senior guys have a lot of experience in different technologies, but no one has time to put forward standards. Well, not necessarily. If a powerful company behind the technology is looking to make money, their evangelists will tell you how cool the new language is, can do a lot of things, easy to learn, scalable, and can meet millions of users. Microsoft often uses its technology to do such things. On the other hand, when Google bought Android, I really thought they just regarded it as an insignificant project. If you have entered the Android world since the birth of Android, you must remember that Google doesn't care about your depression. A few people who have additional experience, ability and willingness to help the community are now Android superstars or gods - such as Jake Wharton.

“When Google bought Android, I honestly think they treated it just as some other side project.”

You might say that you don't have to think too much about architecture and organizing code, because the (Android) framework helps you do it. Android forces you to put the interface into activity, the reusable interface into fragment, the background service into service, and use broadcast receiver to communicate with other components, which can make your life better, isn't it? no, it isn't. First of all, there are some good practices and principles that are really good, independent of Technology (platform). For example, the single responsibility principle, the dependency inversion principle, interface oriented programming, killing the global state, trying to eliminate all States, and so on. I rarely force you to follow principles. On the contrary, they violate these best practices and principles in the worst way. Think about context, the God object you use everywhere, various singleton managers, fragments with life cycle (what kind of nightmare is that), and asynctask that often cannot be implemented correctly. They suck the blood of your app. A novice developer who lacks guidance can easily create a monster instead of an app. Think of it as a spaghetti monster - it's a good monster, but not a good app.

Spaghetti Monster means a mess of code

Finally, technology and framework hide the purpose of app. OK, this is an android app, but what kind of android app? News reader? Music player? Language learning program? Weather applications? Maybe it's a schedule. If everything is packaged into classes provided by the framework, you can't tell (what app this is). As Robert Martin, Uncle Bob, said, "your architecture should scream out what app does". More technically, business logic should be clearly separated and independent of the framework. I hope to have made it clear that you should not rely on the framework to keep your code neat and orderly, especially when writing Android code. We realized this a long time ago, but we lack experience in coming up with awesome solutions. Architecture failure takes a lot of time to show, and you can't change the whole architecture in the middle of the project. It is also impossible to have time to restructure old projects into new, cool and (want to be) the best architecture. Therefore, we take a gradual approach, slowly build our architecture from one project to another, and learn from our mistakes. We believe that our architecture should meet several objectives, which are the criteria for testing our method. A good architecture should:

Meet the needs of many stakeholders, support separation of concerns, escape from the real world (Android, DB, Internet...) and make your components testable

1. Meeting many stakeholders (in this article) is anyone interested in your app development. In addition to development, there are visual designers, interaction designers, project managers, database administrators, testing and so on. Of course, you can't organize your code in some way. For example, interaction designers can open the project and know everything immediately, and even make some changes. It’s a unicorn.

I mean, you can organize your code in such a way that the programmer who interfaces with the interaction designer only needs to take care of the interaction related code. Therefore, all interactions are separated into classes / modules / components / whatever (components) responsible for interaction. When dealing with the interactive part of the app, only those components need to be taken care of.

Translator's note: if you can't understand the stakeholders for the time being, it doesn't matter. You'll understand it after reading part 3 of this series

2. Support separation of concerns. What I just said is an example of separation of concerns. We support this specific approach because it can well express the cooperation between team organization and project stage. Generally speaking, your architecture should also support separation of concerns. The principle of separation of concerns or single responsibility means that each component should have only one reason for change. 3. Escape from the real world (Android, DB, Internet...) the rule of escape from the real world has been mentioned earlier. We said we wanted to scream out what app really does, that's it. We want to emphasize business logic and hide the details of the framework. This rule should be stricter: hide not only the details of the framework, but also all the details related to the outside world.

All the dirty Android things, such as sensors, notification mechanisms, screen details, database access, Internet access, etc. 4. To make your components testable, you should unit test your app as much as possible, and your architecture should allow you to do so. If you can't test everything, you should at least cover your business logic. Separation from the real world can easily do this. If your business logic is clearly isolated from the rest of the app, it is easy to test.

First iteration - public final class usersactivity extends listactivity{

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //… new ListUsers().execute(); }

private final class ListUsers extends AsyncTask<Void, Void, Void> {

   @Override
   protected Void doInBackground(Void... voids) {
       // final sqliteOpenHelper sqliteOpenHelper = ...
       // JsonObjectRequest jsObjRequest = new JsonObjectRequest
       // (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
       // MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
       // showData(user);
       return null;
   }

}Copy code you may have seen such code in "ancient times". If not, you are young. What's going on? Everything!

We have an activity to operate the database, access the network, parse data, switch threads and render data. All stakeholders are looking at this class. There is no separation of concerns. It is untenable. Business logic and Android are mixed together.

Note: pay attention to the red label on the left of the figure above. Each label corresponds to a golden rule, and red indicates dissatisfaction. SRP refers to the principle of single responsibility, i.e. separation of concerns.

The second iteration - the first method of MVP obviously doesn't work. The first thing we tried was MVP, or Model View Presenter. Everyone is familiar with MVP. It is one of the most popular architectural patterns. It looks like this:

Here, we separate the view that is actually Android fragment. We have a (domain) model representing our business. Finally, we have a presenter that coordinates everything. This must be better. With some separation of concerns, stakeholders are no longer so confused, and you can write some unit tests. Nevertheless, because presenter operates directly on databases and everything, we are still mixed with the real world. The presenter became the object of God. It processes the model, sends data to the view, and it has business logic (business logic is those gears)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>