Android veteran's development architecture thinking and experience summary

Android veteran's development architecture thinking and experience summary

Preface

What is architecture design? Based on my studies and my own thinking during this period, I believe that architecture is a consensus reached based on products and technologies. I am not a professional architect, nor an experienced developer. This article has three purposes: first, to organize my architecture studies and thoughts during this period and summarize the development experience and lessons learned this year; second, I hope to discuss the architecture design of mobile apps with you friends; and third, I hope that each of our application developers can have an awareness of architecture. My personal level is limited, and if there are any inappropriate points in the article, I hope to criticize and correct them.

[[238756]]

1. Bud

As a programmer with little programming experience, I have always felt that architects are a mysterious profession, and architecture design is even more so. After several projects this year, I have previously written about my practical experience in refactoring projects from MVC to MVP, and I have also said that I am ready to refactor the current projects under my control. However, some time ago, I changed my mind. The refactoring of the development model is just a change of routine. Perhaps in the process of refactoring, the logic of the business was sorted out, and some optimizations were made based on the code design of predecessors. However, this is far from enough, and this is not my ideal development scenario.

During the project development process, I also found many problems, but they were all scattered problems. I often hoped to change the status quo and program more elegantly, but the actual situation was that I fell into an endless cycle of iterative function development and bug fixing. Now looking back, my ideal should be that development should be guided by planning and design, so architectural design is particularly important.

2. Introduction to the architecture

1. Read "The Beauty of Architecture" on architecture

I have only read the first part of "The Beauty of Architecture": On Architecture, and have a general understanding of architecture. The following figure is a summary of the knowledge points in this part:

Concepts that inspired me from the book:

  • Architecture is a compromise, a trade-off. What architects need to learn is balance, the balance between quality and cost;
  • The architect’s primary concern is not the functionality of the system, but meeting requirements and satisfying quality;
  • What architectural design needs to do is to separate concerns and design a certain structure for each concern, which is conducive to answering the problem defined by this concern;
  • A good architecture should be able to guide product, development, and test personnel to feel very comfortable and reliable with the design, and the design should cover all stakeholders and concerns of the software system;
  • Design only what you know you need, any extra design is a waste;

The architecture affects almost all people and things related to the system and determines whether the software system is healthy.

2. Analyze the architecture evolution of various apps in the industry

Here I just searched some articles about the architecture evolution of various apps through Google, and analyzed why they evolved? How did they evolve? What benefits did they bring? A simple summary is as follows:

(1) Why architecture needs to evolve

  • Project requirements are expanding, and the old architecture is not adaptable to new requirements
  • As the number of development team members increases, the requirements for collaboration become higher
  • Introduction of new technologies
  • Higher software quality requirements

(2) How did they evolve?

  • The Ele.me Mobile App Architecture Evolution 2016-01-20
  • Common components
  • Business Components
  • Module decoupling
  • Excalibur mapping system, registration mechanism
  • Introducing the Hybrid Framework
  • React-Native & Hot Patch
  • Ctrip Mobile App Architecture Optimization Journey 2016-04-07
  • Adjust the engineering structure, decouple the business, make products independent of each other, and use event bus or URL bus for page jumps
  • Unify basic functional business components and SDK
  • Performance data collection and monitoring
  • Native plug-in and HotFix
  • The Evolution of Nuomi Mobile Component Architecture 2016-05-24
  • Componentization
  • Unified service entrance
  • Hybrid framework optimization
  • Suning 11.11: Suning.com Mobile Terminal Architecture Optimization Practice 2016-11-11
  • Layered decoupling to solve vertical decoupling
  • Intermediary reference structure (protocol and url), horizontal decoupling
  • H5 container optimization
  • Network link optimization
  • Mobile App Performance Monitoring System

(3) Benefits

  • Modular decoupling has been carried out, and the products are relatively independent, which makes it more flexible to deal with changes in demand and technology updates, and makes team collaboration more convenient. It also reduces a lot of useless work and leaves some technical accumulation for the team.
  • Necessary unified standards have been carried out, the organizational structure is clearer and the system is healthier;
  • A new technical framework has been introduced to provide a better product experience;
  • We have carried out system optimization work, the software quality is higher and the experience is better;

3. Google search keywords: architecture design

Search engines are the best learning tools for us. I searched for keywords such as architecture design, read some articles, and carefully read Keegan Xiaogang's blog series "Xiaogang's Architecture Thinking". I read these articles when they were first published, but I didn't understand them very well at the time, probably because I didn't have a general understanding of architecture. When I consulted a senior, he told me about his understanding of architecture and recommended these articles again. So I read them again several times. The figure below is a summary of the knowledge about architecture design in the article.

(1) Knowledge Overview

(2) Personal summary

The architecture is divided into three stages: planning, design, and construction. The design of the architecture has different functions in each stage. In the planning stage, we consider product requirements, quality requirements, technical feasibility analysis, and preliminary research. In the design stage, we consider how to split a complex system and design how to organize these split modules. In the construction stage, we consider specific implementation issues and ensure a certain degree of scalability because the architecture is constantly evolving. The article quotes a model diagram from the book "Software Architecture Design", and I think it is necessary to post it here. Recently, I have also been thinking about the modular design of software. Maybe everyone has their own understanding of modular design, so I will not discuss it here. As shown below:

I didn't understand this picture very well at first, and I tried to draw some pictures to express my ideas. However, when I looked back at this picture again, I suddenly realized it. The design of architecture can be considered from two dimensions, one is architectural thinking, and the other is architectural principles. Thinking is our way of thinking and our way of solving problems. Principles are the direction of our thinking and some of our standards for solving problems.

III. Definition of Architecture

The industry has different opinions on the definition of architecture. I have also consulted some experienced seniors in the industry through WeChat. The book "Software Architecture Design" summarizes the definition of architecture into two categories: composition and decision-making:

  • Compositionalism: Architecture = Components + Interactions: The architecture of a software system describes the system as computing components and the interactions between components.
  • Decision-making school: Architecture = set of important decisions: Software architecture is a collection of decisions made in some important aspects.

Keegan Xiaogang mentioned in "Xiaogang's Architecture Thinking: What is Architecture": Software architecture is the process and result of planning, designing and building software. The book "The Beauty of Architecture" proposed in 1.1.3 The Meaning of Architecture: Architecture describes the structure used to design and build a system. "Software Architecture in Practice, Second Edition" proposed: The software architecture of a program or computer is a structure or a set of structures of the system, which includes software elements, the externally visible properties of these elements, and the relationships between the elements.

I have not experienced large-scale software systems, and I have only done mobile app development, so I can only give a narrow understanding from the perspective of mobile app architecture design. I believe that mobile app architecture is a consensus formed by the coordinated management of products and technologies. Most app development, especially that of small teams, is driven by products. When demand comes, it is implemented by technology. When demand changes, it is changed. After all, the development of the application layer is responsible for the business and must ensure normal release. Therefore, in most cases, programmers have to compromise in front of product managers, which makes the work of developers very passive. Therefore, there are jokes about programmers and product dogs. The reason for this phenomenon is that the relevant stakeholders of the project have not reached a consensus on products and technologies, which is exactly the problem that mobile architecture design needs to solve.

4. Products

Products are the result of our product managers' design and the final result of developers' development. They are the common goal of both groups. As software architects, you should fully understand the design concept of the product. In addition to understanding the functional business that has been designed, you must also have a certain degree of foresight and grasp the development trend of the product. The following mainly discusses products from the perspective of development.

1. Product design (what to do)

As a developer, I cannot talk about product design professionally, but I still want to talk about product design from a developer's perspective. What is product design? I think it can be thought of from the following aspects.

(1) User group (who uses it)

As the name implies, the products we design and develop are ultimately for people to use. So first of all, we have to identify who the users of the product are? The user group represents the market for our product. So whether the product is good or not is ultimately determined by the market and the users. Without users, without understanding users, and without paying attention to the user experience, everything is in vain.

(2) Core Concept (What to do)

Do you know what kind of product you have worked so hard to develop line by line every day? It may be easy for us developers to fall into the iteration of one version after another. These endless tasks make people forget to think and forget to ask product personnel, what are we going to do in the end? What will our product be like in a year? What is our ultimate vision? How will we realize our ultimate vision step by step? You may say, what does this have to do with my development. When I receive the requirements, I will develop and implement it. However, there are many complaints in our team. The product personnel keep making changes, and I change the code back and forth. Our leader emphasizes that our developers should have their own initiative in this regard and can refute the unreasonable design of the product. However, the premise is that you at least understand the core concept of the product and what we want to do in the end.

2. Iteration plan (how to plan)

For a product, users have many needs, and they keep changing over time. There are two types of needs: one is the instinctive needs of human nature, and the other is the needs generated by our products. Both of these needs are reasonable, and they are exactly what we need to satisfy users. How can we plan to implement various needs? In agile development, we put these needs into a "requirement pool" and then plan and arrange them in different versions of iterations. This work is not only decided by product personnel, but developers should also play a certain role in decision-making. Product personnel need to consider from the perspective of the product, and developers need to consider from the perspective of technical implementation. The final plan should be a joint decision of both. It is particularly important to note that according to the characteristics of the product, technical personnel should also put forward technical requirements. A reasonable iteration plan can ensure a normal development rhythm and achieve iteration goals.

3. Development resources (what to use)

(1) Development team configuration (people)

The book "Peopleware" mentions that the human factor is very important in software development, and it is very important to configure the development team properly. An App development team needs at least 5 roles, namely product, interaction, UI, software, and testing. Different roles are also divided into different levels, such as software is divided into primary, intermediate, and advanced. Only by properly matching different roles and different levels can we achieve higher work efficiency and ensure the smooth progress of product development.

(2) Data content configuration (object)

The product ultimately presents data to users, and there are two types of data. One is private data, which is produced by the developer himself. The other is platform-generated data, which is produced by users. If it is self-generated data, you have to consider the source of the data, the coverage of the data, the accuracy of the data, the legality of the data, etc. If the data is produced by users, you have to consider the motivation, entry point, data security, and dissemination of the data, etc.

(3) Development investment budget (money)

Everything is ready, only the east wind is missing. To complete the development of an app, a professional development team is needed, and the labor cost here is also very high. Of course, I will only talk about the development budget here, and I will not talk about the operation. We have to consider how long the development cycle is, how many people are needed, and how to do the later maintenance. For example, an APP requires 5 people to develop, 2 months, and two versions. If calculated based on a salary of 10,000 per person, it will also cost 100,000. This is probably the lowest level of algorithm. Therefore, if it is a startup company, when we form a development team, we also have to look at the budget and how much money can be used to do a lot of things. Of course, if it is those bosses who don’t care about getting investment, it’s another matter. However, too many companies that died this year used to be big spenders. Once the money is burned, it’s gone. If it’s a big company, it may not be so stingy. However, we should also consider how much resources the development team will consume the company and whether we can get corresponding or higher output.

(4) Third-party resources

For current development, many resources can be obtained through third-party cooperation, such as servers, cloud storage, payment interfaces, login interfaces, content data, and some open source frameworks in the development process. We need to select, negotiate business, and integrate them into our own APP.

4. Product quality (how is it made)

(1) User experience

Now for us, user experience is a word that is overused. That is because user experience is really important and determines the success or failure of a product. After the product is developed, it will eventually reach the hands of users. Whether the product is good or not, the users have the final say. What factors affect the user experience? I think it can be seen from the responsibilities of the five roles. Does the product design directly hit the user's pain points? Does the interaction meet people's preferences and habits? Does the UI make users feel comfortable? Is the performance of the software good? Does the software have many defects?

(2) Software Performance

From a technical perspective, we can analyze the quality of a software product through its performance. This year, many technical articles are talking about performance optimization. The performance of software is mainly judged from several aspects, such as software startup speed, fluency, memory, power consumption, traffic, APK size, etc. If you want to make a good application, performance optimization should be incorporated into daily development and carried out continuously. I will not go into details about how to optimize it here.

(3) Product safety

Product security can be viewed from two perspectives: the manufacturer of the product and the end user of the product. For manufacturers, there are many contents that need to be protected by law, and there is a lot of sensitive information, core technology, network interfaces, etc. that cannot be leaked. For users, we must store a lot of user information locally or on the server, such as account passwords. Once some information is leaked, it will seriously harm the personal interests of users. Therefore, in order to protect ourselves and the interests of users, we must produce a safe and reliable product. Then for an application developer, our compiled apk will eventually be in the hands of users. Therefore, we need to protect our applications through some technical means such as code obfuscation, data encryption, and permission restrictions.

(4) Quality Assessment

I think whether an application is good or not can be judged mainly from the above three dimensions: user experience, software performance, and product security. So, how should we organize these evaluations? Are we doing these things? For now, I believe that most product, development, and test personnel are more or less involved in these tasks, but perhaps they have not quantified some data and have not systematically organized these tasks. At present, most applications have integrated behavior collection, and the number of product downloads and user activity are also the main parameters that reflect the user experience of the product. The development team has been working on performance optimization, such as exception repair, bug repair, content leakage, overdrawing, and apk slimming. We have also carried out code obfuscation, data encryption, and apk signature encryption. However, do you know the quality of your product? Compared with similar products, what do you do well and what do you do poorly? Therefore, I think it is a very meaningful thing to systematically organize these fragmented tasks, quantify some influencing factors, and let us understand our product quality more clearly.

5. Risk avoidance

(1) Risk of human resource changes

People are fickle, especially in IT, where personnel turnover is even more frequent, including internal adjustments, employee job-hopping, etc. Therefore, for a development team, the risk of personnel changes must be considered. If someone is gone, can the project run normally? Can the development teams cross-familiarize with each other's business?

(2) Risks of upper-level decision-making

Have you ever experienced a situation where a project was stopped halfway through? At this time, you are only doing half of it. If this happens, what should we do? Suppose just now your boss said that you can no longer do your current project, then how can you recover the losses to the greatest extent? How to finish the project so that you don’t end up with a mess when the project is suddenly restarted?

(3) Project delay risk

When developing a project, we will conduct a review and then develop it according to the iteration plan. However, there will be many problems that affect our expectations during the development process, such as demand changes, technical difficulties, etc. Project delays are a common problem in the development of software projects. For some iterations, it may not have a significant impact on the entire project, but this problem must be considered. In addition, we should strictly control the progress of the project, balance these issues, and ensure that the product can be delivered on time.

(4) Software defect risk

We should be able to provide a stable version at any time, which is what our leader requires. It is normal for software defects to exist. We keep writing bugs and fixing them. For those deeply hidden bugs, they may not be tested and finally circulate to users. How can we complete emergency repairs at this time? How can we respond quickly to provide users with a stable and reliable version? These are what we need to consider. At any time, there should be a Plan B.

(5) Risk of human error

Some time ago, due to an operational error, the company accidentally sent an apk to the wrong model when updating it, causing the users of that model to be unable to use the program after the upgrade. Then, due to the lack of maintenance for this model, the code could not be found, and only an apk file could be found, so the only option was to decompile and upgrade. I think there are many human errors like this, such as code submission errors, integration path errors, etc. People are always careless, so when designing, we should take these factors into consideration, how to actively warn when errors occur, how to initiate emergency plans when user errors have already occurred, and minimize the adverse effects.

6. Product Delivery

(1) Test version

In agile iterative development, we can basically submit two test versions a week. We can submit a testable version when we develop a part or fix a part, which can minimize development risks and is conducive to software stability.

(2) Grayscale mechanism

If your product has a large enough user base, you should carefully consider releasing a new version at this time, because users are the testers of your product. Currently, most people use a grayscale release strategy, first releasing it to a small number of users to see their feedback, and then gradually releasing it to all users.

(3) Version management

We have many versions in the development process, and there are many ways to divide them. For example, debug and release versions. Sometimes we also need to provide data versions with test data for the content, and sometimes we need to develop the next version of the function before the previous version is officially released. How do we manage the codes of each version and how do we distinguish these versions by version names? We need to formulate certain management specifications, and whether this specification is agreed upon by the development team is very important.

5. Technology

I have been talking a lot before, but I have finally come to this point. For a developer, the key question is how to do it. I only know Android development, so I will only discuss Android below. I will mainly talk about how to do it from the following aspects.

1. Technology selection

(1) Development Platform

Currently, mobile development mainly focuses on two major camps: Android and IOS. I won’t say much about the others.

(2) Development Tools

  • Compilation tools: Eclipse & Ant, Android Studio & Gradle. As an Android developer, you should undoubtedly choose Android Studio & Gradle.
  • Code repository: Git, SVN, tools include Turtle, AndroidStudio also integrates VCS;
  • Maven warehouse: You can use nexus to create your own Maven private server;
  • Continuous integration: Jinkens, Buildbot, Travis CI, Strider, Integrity.

(3) Development language

Java, Kotin, Grovvy, SQL, etc.

(4) Development Model

MVC, MVP, MVVM, clean, etc. each have their own advantages and disadvantages, which will not be explained in detail here.

(5) Open Source Framework

It is said that you should not reinvent the wheel, because your wheel may not be better than others. For us developers, one very good thing is that we have too many open source and free third-party libraries for us to use, which saves us a lot of work and makes development more efficient. However, how to choose and whether to introduce is a question we need to consider. The following lists some commonly used third-party libraries, please click for more.

  • Network: okhttp, android-asyn-http, volley, Retrofit
  • Event Bus: otto, EventBus
  • Dependency Injection: Dagger, RoboGuice, ButterKnife
  • Images: Fresco, Glide, Picasso
  • Database: GreenDao, Ormlite, LitePal
  • Json parsing: Gson, Jackson, FastJson
  • Responsive programming: RxJava, RxAndroid
  • Abnormal statistics platform: Tencent Bugly, Crashlytics
  • Performance optimization: blockcanary, leakcanary

(6) Emerging Technologies

In software development, new technologies are developing very rapidly, but it takes a long time for us to actually implement them in projects, because new technologies have to be learned and there are risks that new technologies are not mature enough and have defects. Of course, we should actively introduce good new things to keep up with the times. The following may not be new things, but they are also new technologies that have been sought after in recent years.

  • AndroidSupport: DataBinding, MaterialDesign, etc.
  • Hybrid development: ReactNative, Hybrid, Weex, etc.
  • Programming language: Java8, Kotlin
  • Hot fixes: AndFix, HotFix, Tinker, etc.
  • Build: InstantRun, Freeline

2. Business Splitting

When we split the business, I think we can divide the business into three categories:

(1) Common basic services

Basic business mainly refers to some basic functions of our app. For example, our company has a BFC team that has developed SDKs for file upload and download, network request, behavior collection, account system, etc., which relieves us of some repetitive labor. How to define what business is basic business? I think it can be distinguished in this way. If your business is needed by ordinary application apps in the industry, then these are basic businesses with universal applicability. We split them according to different functions.

(2) General technology business

I think general technology business is a business related to your own app and has strong technical characteristics. It may be the core technology part of your application. For example, the image processing of beauty software and the image recognition of Xiaoyuan Search are general technology businesses. The characteristic of general technology business is that there will be technologies needed in the same type of app as yours, and we can split it according to different technical fields.

(3) Specific functional services

Specific function business is the specific function of your own app, which can generally be divided into different modules according to the function. For example, my current one-click search (similar to Xiaoyuan search question) mainly has three functions: search question, look up words, and translate. Then it can be split into three major parts. Searching questions requires steps such as taking pictures, framing questions, image processing, and network requests. Each step can be regarded as a small business and split accordingly. Most of the specific function businesses are only applicable to your own APP.

The above statement is only based on my own experience. In our actual development, there may be some special cases or different splitting methods. In short, the splitting of business still needs to be based on the actual situation.

3. Architecture design (separation of concerns, abstraction)

(1) Core Concepts

Separation of concerns

There is no architecture in the world. Once the concerns are separated, there is architecture. We divide the development of a software system from multiple dimensions, design each field, and organize each field in a systematic way. This organizational structure is architecture. However, how to reasonably separate the concerns of a complex system is very challenging.

abstract

Abstraction, this is the last point emphasized to me when I asked a senior for advice. If you follow the interaction and write the app page by page, then obviously, you have not abstracted your business, but only implemented it. As a design concept of Java, it also emphasizes the concept of abstraction. So what is abstraction? Abstraction is what you want to do! A simpler understanding is to write interfaces instead of classes. I don’t know if you have had this experience. In the development of our MVP, we have a Model and an IModel, but we didn’t know how to write IModel until we finished writing the Model, and it became a manual labor of copying and pasting. If you do this, you can think about it yourself. If we write IModel first instead of Model, what kind of experience is that? This is to abstract your business. In the design of the architecture, you only need to know what you want to do? You don’t need to pay too much attention to how you implement it specifically. This is design.

(2) Design Thinking

Procedure Oriented

As we all know, in C language development, our logic is mostly based on the task flow. This is a typical example of process orientation. Process orientation focuses on the work flow and completing tasks step by step.

Object Oriented

Java language is a typical representative of object-oriented development, which is well known to us. We design computers according to human thinking. Each object has its own attributes and its own operation methods. There are inheritance, combination and other relationships between objects. We complete our program by organizing these relationships. Just like people and things in society, the various complex relationships between people complete the operation of various social activities.

Aspect-Oriented

Aspect-oriented programming is created to make up for some defects in object-oriented programming. We encapsulate some functions together and provide external interfaces for easy calling anywhere. For example, SharedPreferences, Json, Xml, File, Device, System, Log, format conversion, etc. are usually in the until package. It is equivalent to a cross section. We can complete operations facing this cross section at any time, and there is no need to repeat the design in our own logic.

Service Oriented

Service-oriented means splitting the system into independent programs or components and providing a service to the outside world. Each service communicates with each other through a certain protocol, such as HTTP, and is deployed separately, thus achieving the purpose of loose coupling.

The above four types of thinking focus on different perspectives on the problem. Different perspectives lead to different solutions to the problem. Of course, each perspective has its own advantages and disadvantages. So, in Android development, is it just designed according to OOP principles? Obviously not. In the face of different needs and different scenarios, we need to adjust our thinking in time, use it flexibly, find the most suitable perspective, and come up with the best design solution. This is what we pursue.

(3) Design principles

High cohesion

How to understand high cohesion? I think when we split, a certain subdivision field only completes a single function, and handles its internal affairs by itself. From the surface, for example, a model class provides an interface to the outside world, so it has an input and an output. Looking at this interface alone, it is highly cohesive. Of course, its internal organizational structure may vary greatly, so the form of cohesion is different. So we classify them into functional cohesion, sequential cohesion, temporal cohesion, etc.

Low coupling

Coupling refers to the dependency between modules. Mutual dependence will inevitably lead to checks and balances. Therefore, if the coupling is too high, it will lead to ripple effects, which is something we don't want to see and will greatly affect the iteration of program versions and bug fixes. According to the different dependencies, we divide them into indirect coupling, data coupling, content coupling, switch coupling, control coupling, external coupling, etc. To complete the development of a system, we must organize the modules effectively. This organizational relationship cannot avoid coupling. What we need to do is to minimize these dependencies, especially avoid cross-dependencies, reduce the coupling to a minimum, and make our program design more flexible.

Moderate design

If we don't consider it carefully when designing, then the design is not enough and cannot meet the existing or foreseeable needs. From the perspective of development, it will lead to many problems in the later development. If you think too much, it is easy to over-design, so that a simple system is designed to be very complicated, which will add a lot of meaningless work to the current development and reduce the development efficiency. So what kind of design is a reasonable design? I think it can meet both existing and foreseeable needs, and can be easily expanded when facing the adjustment of the architecture. Such a design is a very good design. How can such an effect be achieved? I personally think that when designing the system, the granularity of separation of concerns needs to be grasped. The system is just an organization of different single small modules. Then these small modules are the basis of architectural design, which is like the bricks for building a house. What are these bricks? They can be a public method that provides an interface to the outside world, a private internal method, or a member variable held by someone. Of course, looking at the big picture, it can be a certain functional module. In the architectural evolution of each app in the above industry, modular transformation is emphasized. Therefore, only by separating your systems well can you organize them flexibly and respond to ever-changing situations with the same approach.

(4) Design plan

Guidance Model

The following picture has been mentioned in the article, and I will introduce it again here because it really inspired me and expressed what I was thinking. Facing a complex system, how do we separate and organize it? I think this picture has conveyed the essence of it, so I think it is a guiding model for architectural design. No matter what MVC, MVP, MVVM, etc. you are, you can understand it from it.

Model decomposition

Based on my personal understanding in practical development, I have simplified this diagram again as follows:

Horizontal block

According to the simplified model in the figure above, we can understand that we divide modules horizontally according to business functions. For example, the theme store can be divided into wallpaper, ringtone and other modules, and each module is decoupled. At the same time, the business of each layer is divided into blocks again. For example, wallpaper has image request, loading, caching, cropping and so on in the data layer.

Vertical stratification

Next, we divide the business of each module into presentation layer, business layer, and data layer according to their responsibilities. The data layer is mainly responsible for data acquisition and packaging, while the business layer mainly coordinates the needs of the upper layer and finally returns the data to the presentation layer. The work of the presentation layer is to display the data on the UI interface, and respond to various instructions from people to switch the UI and operate new data.

Interface communication

From a horizontal perspective, we divide the business into blocks to ensure that there is no dependency between blocks, ensuring absolute decoupling. From a vertical perspective, the dependency between each layer is obviously unavoidable, so we can ensure that the upper layer only depends on the interface of the lower layer, thereby achieving the purpose of reducing its coupling.

As shown in the figure above, after the three steps of horizontal block division, vertical layering, and interface communication, we can decompose a system well and get an ideal model. Of course, this is an ideal model. In our actual development, we may not be able to avoid some special situations such as crossover, and we still need to proceed from the actual situation. But one thing is that we can ensure the separation of interfaces to achieve the purpose of lower coupling.

Unified Management

Unified management means that some things in our design need to be managed uniformly. Through the above principles, we have disassembled a complex system and achieved the purpose of separating the focus in architectural design. However, in actual development, in addition to splitting the business, we also need to manage certain businesses uniformly. For example, some mode switch management, such as switching between the test environment and the formal environment when making network requests, we can place these mode switches in one place to facilitate our management, rather than go to various places to modify. For example, whether our request URL address can be written together for unified management. In some applications, a middleman will be used to uniformly manage data circulation and page jumps. This is also a solution that can be tried. For details, please see the module manager and Url jump manager mentioned in the architecture optimization practice of Suning.com mobile.

Unified management means putting some characteristics of a certain type of split small module in a certain place for unified management. However, there will be a problem, such as the unified switch management mentioned above, which causes switch coupling. How to avoid it? I think it can be written to your own module by default and the modified interface is disclosed to facilitate the upper layer to make unified modifications to achieve the purpose of unified management. In this way, even if the module is detached, it will not be affected. However, in this way, its security will be affected to a certain extent. Architecture design is always like this, and you always need to choose a solution that is suitable for you.

We cut a system into different small pieces through the above-mentioned horizontal chunking and vertical hierarchical methods. These small pieces are responsible for a single responsibility, and then connect the blocks to blocks through the interface, relying on interfaces rather than instances to weaken the coupling caused by communication between modules. Of course, the above-mentioned model is just an ideal model. If it is a very complex system, more levels can be split between levels. For example, in the data layer, we use Model to complete it under the development of the MVP mode. When the business of the Model layer becomes very complex, some people will consider splitting out the Data layer and putting it at the bottom, the most basic data operations, etc. Finally, in order to facilitate our combination and management of modules, we can consider opening out interfaces in small modules for unified control and management of the upper layer. Finally, when I want to say, we can consider following the above solution when separating and disassembling the business, and finally designing according to the actual situation.

4. Development and implementation

After completing our design work, we enter the development coding stage, where we mainly express our design and ultimately achieve tangible results. Before entering this stage, our design cannot be just a document, but a certain consensus reached by developers and architecture designers. No matter how good the design is, it needs to be well expressed and implemented. Let’s mainly talk about the issues that need to be considered in the implementation process.

(1) Project Subcontract

The subcontracting structure of a project reflects the architecture of a software. We always have a confusion when subcontracting. Because we have multiple divisions, for example, we can divide them into activities, fragments, adapters, utils, etc. according to the functions of the class. Sometimes, we divide them according to the functional modules, such as word search modules, question search modules, and small peripheral general functional modules such as network requests, software upgrades, etc. The problem is that there are some things that can be reused between modules, so when we split, we obviously have code redundancy. If we divide them according to the two schemes at the same time, there will definitely be architectural confusion. How can we achieve the balance between these two? I think this also needs to be more project size. If it is a very small project, there is no possibility of business expansion. We can adopt the first solution mentioned above, just a simple classification. However, for larger projects, I suggest using the second solution. Below, I will list a model for reference only:

  1. + app +main +com.jfg +common //Common basic business +util +wedget +base + function //General technology business +camera +sensor +moudule //Specific function business +mouduleA +model +presenter + view +mouduleB +model +presenter + view +mouduleC +demo //Main program +app +activity

As shown above, we split the subcontract according to the project business we started, as above, put the commonly used basic business into the common package. This package remains unchanged in most cases and provides basic services to the app. However, we try not to put it in the common package. If the common package becomes large enough, we must think about whether it should be split. Because common gives people the feeling that everything is, it makes us unable to quickly understand the responsibilities of this package.

We can understand this way that the common package is some businesses designed for tangents, but it is not absolute. Next, let’s talk about the module package. In fact, the business is split into modularly. As mentioned above, we split the mouseA and mouseB. There is no connection between the two. However, we have a problem, that is, some businesses of mouseA and mouseB are the same, and we disassemble them to repeat a lot of physical work. This should be a problem that most developers face. How to balance this? I consider this way. If there are overlapping businesses between mouseA and mouseB, we extract these businesses into function packages or common packages, which reduces the level of the business.

We allow the services of each module of the Moudle package to rely on the basic services provided by function and common. In order to better distinguish between module A and module B, although overlapping, they belong to each other logically, we have two methods to do it. The first is to abstract the two businesses to a certain extent, and the implementation process is still placed in each Moudle business. The second solution defines two interface classes, each of which defines their own interfaces. The methods of these two interface classes are implemented in the specific implementation class, and the same logical operations are performed internally. In this way, to the outside world, mouseA and moduleB are logically separated. In short, how to subcontract must also weigh the pros and cons, and try to divide them with one mindset to avoid design confusion.

(2) Abstract interface

If abstraction is important in architectural design, you may be a little confused, but if you are asked to write an interface or abstract class first instead of a class, you may feel the meaning of abstraction. We break a system into several large modules, and a module is divided into different levels, and each level is split into different details business again. Finally, we clearly know what we need to do to complete a certain function? Right, what we do is to do each interface. When we encode, we write the interface first and then write the implementation to help us split and abstract the business.

We all know that doing something generally requires some conditions, and after doing it, there will be a result. These can be done in the design of the interface. We need to note that an interface only does one thing. If two things are very similar, try to split rather than merge. In terms of interface naming, you must be sure that you know the name and meaning. How to judge it is, if your interface has no comments, it will also make people know what your interface is doing.

(3) Data storage

Commonly used data storage include SQLite, SharedPreference, files, etc., and whether cache can also be considered as a kind of. What I want to emphasize here is to pay attention to the standardization and security of data storage. If it is a database, it is necessary to consider its scalability. If it does not meet the needs, it will need to be upgraded.

(4) Performance Management

This comes from a little experience of performance optimization. We cherish server resources very much for server development, and we should buy it for money. However, we often ignore this point for client development. Although mobile phone devices now have large memory, how to write an excellent program is also a very important indicator. Performance optimization processing is that we correct errors, so we should make fewer mistakes afterwards. The performance experience is not good enough, it is nothing more than the uncontrollable use of memory, CPU, and GPU resources of the machine device, causing waste of resources. When the machine device cannot bear it, the application will have adverse reactions such as card segments, crashes, and abnormalities, which seriously affect the application experience. What we need to do is to have a strong sense of performance management, borrow memory, CPU, GPU and other resources on demand, and borrow and repay, that is, remember to release resources after use.

(5) Special treatment

During the development process, there are always so many problems that do not play according to the normal idea. These are attributed to our strong testing team. Different methods can get different results, and then we are given a lot of bugs. Therefore, we need to pay special attention to handling special circumstances in software development, which are often logically blind spots in the end. The following briefly summarizes some:

Functional conflict

Functional conflicts can be divided into two types, one is the function conflict within the application, and the other is the function conflict between applications. In-app conflicts, such as function A and function B use a resource file. If it is used at the same time, problems will arise. We usually add a synchronization lock to prevent this conflict. There are many conflicts outside the application, such as multimedia, alarm clock, calendar, ringtone, phone, etc., which one can cause these conflicts. For example, if you are playing a video and a call comes at this time, which one should I give priority? Also, when the alarm clock rings, an interface pops up is a vertical screen, then it will force the current interface to a vertical screen. What should I do if it is a horizontal screen at this time? There are many similar types, and I will summarize them in detail later.

Extreme operation

Our testers like to dot a button wildly, or install countless applications on the machine to fill up memory, or stuff various files into the disk. Although these scenarios are not caused by rational users, they are actually defects of the program. Therefore, we must pay attention to dealing with these issues.

Network Issues

Unavailable networks, networks with weak signals, network switching between wifi and traffic, 2G networks and 4G networks, network request timeout, etc., all require us to deal with the actual situation, such as whether to remind users when switching back to traffic. These processing is also standard for each application, so I won’t say more.

Process for null

This should be the most common problem. Most of the bugs we usually change or grab from background exceptions are null pointer exceptions. First, we have to figure out what the reason is null? Then we need to make a judgment as null and warn.

(6) Log Printing

I think it is important to take the log printing separately here. What is Log used for? Obviously, it is used to help us find problems. In most cases, we will add and print them when the problem comes. Moreover, TAG is a variety of things. Log.d is used in errors, but Log.e is used in temporary debugging. When we check the problem, we need to read a lot of code logic and finally position it. When we fix bugs, we spend a lot of time reading the code again, which affects work efficiency too much. If we have a good standardized design for Log at the beginning of coding, use Log.e when there are exceptions, use Log.w when there are possible problems, etc., use Log.i for key points, and use Log.d for temporary debugging. This is not good. We can distinguish the information we need in the console. We should fully use this tool to help us quickly locate problems.

(7) Software Refactoring

Refactoring is because of the business needs and the higher quality requirements for code. Refactoring is everywhere. We should not refactor for the sake of reconstruction, nor should we keep stagnating. We do not refactor when refactoring, and we owe too much technical debt. Refactoring can be as small as one method to refactoring as the entire system architecture. Refactoring is a necessary process for software iterative upgrades, and it is also a necessary means for us to meet current needs, adapt to future development, and obtain good scalability. Refactoring is not difficult, nor is it a big deal. The key is whether the purpose, idea and design behind the reconstruction are clear.

(8) Compatible and adaptable

The problem of compatibility and adaptation is a headache for us to develop. Android devices cannot have an Android version with uneven screen sizes and hierarchies. In addition to targeted processing, product designers must also be reminded to consider compatibility issues at the beginning of design.

5. Software testing

Software testing is a very important process in our development. In addition to being able to objectively sense the quality level of the software we develop, the ultimate goal is to help developers fix software defects and improve the quality of the software. In addition to the self-testing before the developers submit the test, we need professional testers to conduct the test. The efficiency of manual testing is relatively low, so we should consider completing automated tests, such as unit testing, etc. This is conducive to the stability of the software and also helps developers improve the quality of the code.

6. Development specifications

(1) Consistent design

What kind of design is standardized design? I personally think that the consistent design idea of ​​a project is standardized design. We can understand this way that in a certain category, we solve this type of problem according to a similar solution. Faced with complex systems, our design idea may not be able to meet the needs of the architecture, but we only need to understand that this kind of thing does this, that kind of thing does that, and the flexible combinations between each other do not intersect, giving people a clear sense of design ideas.

(2) Clear encoding

What kind of code is high-quality code? I think the code that can be understood at first glance is a high-quality code. Therefore, we can put aside the coding specifications, naming specifications, etc., and re-examine our code to see if it is comfortable to read. If a new colleague comes and knows nothing about you about the project, can you quickly understand your thinking? The last points are necessary to propose, first, use the design pattern carefully, second, write less document annotations, and third, follow the six major object-oriented design principles of Java. I think these three points are the principles of coding. Abide by these principles and form a habit, which is naturally a norm.

(3) The document is valid

What kind of document is an effective document? I think that documents that can explain the core problems are effective documents. As software developers, we do not have the patience to read a complex and verbose document. Documents only need to present us issues that cannot be explained by the code, help us quickly understand the project structure, memorize key issues, and trace historical records. There are many forms of documents, such as our git submission records, tags, project structure diagrams, core function flow charts, etc. In short, documents are for people to see, and just use as few documents as possible to explain the core problems.

7. Daily work

As a qualified software developer, we have many daily tasks, such as bug fixing, exception handling, Monkey, performance optimization, code quality improvement, etc. These things must be done every day, but you have to pay attention to them every day and have a clear idea. Only in this way can we cultivate a good programming habit and write excellent code and excellent programs.

VI. Development

1. Development Driver

The normal operation of a project must be led by one party, constantly putting forward product requirements, and organizing project members to divide the work and cooperate to complete product development and delivery. The following are two driving development models.

TDD: Test-Driven Development

Test-driven development refers to the work of development led by testing. Starting from the use of the product, it puts forward testing requirements for the product's functions and organizes various roles in the project to complete the development tasks.

BDD: Behavior Driven Development

Agile development is behavior-driven development, which emphasizes product design more and encourages each character in the project to put forward their own views on project development, and has obtained better product functions and completed product development.

2. Agile development

The following picture is quoted from a picture about agile development on the Internet. At present, our team basically conducts agile development based on this model. I think that in agile development, the communication and rapid response between each role is emphasized more in agile development. We do not design the entire system in a complete and detailed design, but carry out the design and development work at the stage and seek continuous iterative updates. In the process of agile development, the common problems are that communication is not timely and product changes are large, so how to dynamically coordinate and manage the management is very important. Through demand review, interactive review, visual review, bug review, etc., personnel from various relevant roles attend the review meeting to jointly complete the decision to ensure the smooth progress of software development. It has to be said that there are still many problems in this process, such as communication problems, product changes, process problems in the development process of product function details, etc. I will not talk about it in detail here, and I will summarize it later if I have time.

3. Achieve a consensus

A characteristic of agile development is that product development decisions are made by members of each role, and problems in each role field are finally decided by the role itself. Then a problem arises, and the problems determined by each role are checked and balanced by other roles. For example, the functions designed by the product manager have technical difficulties in the developers, and there are logical loopholes in the interactive design. I think these problems are the real reasons why a product cannot be completed at the expected time. So, which role coordinates and manages these problems? Usually, we have architects, project managers, bosses and other roles to control and manage projects.

The design of software architecture comes from product requirements and determines the final form of the product. However, in agile development, product requirements change very quickly, and we developers are required to respond quickly to this change. Therefore, it is very important to keep the overall software architecture and product design updated simultaneously.

For developers, we must first have a holistic understanding of the project and keep abreast of the product dynamics at any time. These include product design, iteration plan, development resources, quality requirements, delivery requirements, risk avoidance plans, etc. Then, dynamically adjust our software architecture according to changes in product demand. These tasks include technology selection, architecture design, code reconstruction, document update, etc. to adapt to new needs and share this architecture with relevant personnel to reach a consensus. This consensus requires a coordinated planning of the products and technologies. Only when all relevant stakeholders of the project can reach this consensus, our communication will be more effective and we can make a product that is satisfactory to all parties.

VII. Conclusion

At the end of the work, I looked back and found that the overall understanding of the architecture was on the side of the decision-making faction, that is, this consensus is a collection of decisions made in some important aspects of product planning, design, and development. These decisions are consensus reached by members of our project through planning meetings, review meetings, iteration meetings, etc., and are ultimately reflected in our products. Products, interactions, UI, development, and testing, each role is responsible for its own field, and needs to grasp information from other fields at any time in order to make correct decisions by itself. However, in the architectural design of software technology implementation, I tend to be a constituent faction, splitting and combining the business of the software system, and achieving system operation. I must admit that my understanding is still not transparent at this moment. Most of the aspects in this article are still generally discussed. There are still many things to study if each issue is in-depth. I hope to have a deeper understanding in my future work.

<<:  Android native communication with H5

>>:  How to update the iOS 12 beta version via mobile OTA

Recommend

"The girl was killed because Qvod was blocked" is pure conjecture

Using the murder of a girl as a basis for judging...

Xposed Framework first Oreo version released: all Oreo devices can use it

According to the latest news from the xda forum, ...

Mid-Autumn Festival brand marketing planning program!

For ordinary people, Mid-Autumn Festival is a goo...

How to do Tik Tok marketing?

During this period, Tik Tok is very popular and e...

Microsoft and Touch Technology invest heavily in Windows Game Contest

Recently, Chukong Technology and Microsoft jointl...

Maybe the Apple Watch isn't for you

Along with the launch of a series of new products...

Can’t push the product? Perhaps these problems have not yet been resolved.

Imagine if you tried to convince a traditional Ch...

Xiaomi App Store CPD Price and Resources Introduction

1. Service Introduction Xiaomi App Store is the f...

Low budget user growth model!

"Growth hacking" must be familiar to th...