IMCAFS

Home

business management

Posted by deaguero at 2020-03-04
all

The more complex the process, the more error prone it is. In order to reduce the error situation, we need to extract and encapsulate the general logic and provide services with an easy to understand name. At different levels of abstraction in the business, do the corresponding tasks of their respective responsibilities.

The more interaction processes between front and back stations, the more states need to be maintained, and the greater the probability of problems. Therefore, on the premise of not affecting the main functions, the process can be simplified as much as possible. Those simplified paths, in some abnormal scenarios, will have a certain impact on the business. It's hard to say what programs are affected before going online. The real data after online can be obtained through data buried points for weighing.

When it comes to complex business, you can't start writing at first. You need to design the framework and overall process first. For some requirements, there is no clear interaction details, which are generally based on general interaction details.

For the realization of specific subfunctions, it needs to be considered carefully. The better practice is to list them one by one, and what kind of input will get what kind of output in each state or situation.

In the process of complex program execution, multiple states need to be maintained. With the change of business, when dealing with the events related to States, the burden of thinking will be more and more heavy, and it is easy to lose one or the other. In order to better control the complexity and simplify the logic, it is necessary to manage the state hierarchically and stratify the state and corresponding processing of each level. The external unified state operation interface, in each module, manages the state through the unified state interface.

Failure process

Any failed retrying class operation should consider the impact on the background. Because the gateway can only forward requests, a large number of redundant requests will cause huge pressure on the background, which may affect the normal business process. For failed retries, you must set the timing interval and the number of retries. The types of failures here should be differentiated. If it is a failure of a business operation class, the business layer will directly prompt for an error. If there are other types of failures, the bottom layer needs to make a retry policy. Only when the retry policy returns a failure can it be considered a failure. This process is transparent to the top layer.

In some business scenarios, different types of failures need to be assigned error codes for external processing. For example, in the function of reading configuration information, there are several possible errors:

If reading the configuration file fails due to the above reasons, the default configuration should be handled properly. According to the product requirements, the corresponding handling should be made for different abnormal situations. The default configuration should be used to continue running, or the pop-up box should prompt the user.

When parsing the formatted data returned from the background, it is necessary to consider how to handle it when the corresponding field does not exist. No matter what type of error data is returned in the background, it cannot crash.

Process optimization

Carefully analyze the business process to avoid unnecessary dependence and operation. The relevant business logic should be aggregated.

The thinking of analyzing problems should be polished, reflected and summarized in practice. The first time I think of the plan, there is often a lot of optimization space, so, from what point of view to think about optimization? In the development practice, two major directions are gradually defined. Record here

Thinking from the bottom to the top: the bottom is the most basic data layer, whether the data of the business process can move down to the bottom layer, and then call the underlying explicit semantic interface function to achieve the upper level business, instead of putting a bunch of judgement logic to the business layer.

Think from the top to the bottom: there should be an indirect layer between the business layer and the bottom data, which provides higher-level functions to the top, encapsulates the bottom data to the bottom, and provides a higher-level interface.

Similar business processing adopts similar methods instead of a bunch of conditions. For scope a-c, this method is used. For scope d-f, this method is used. For other types of business, other methods are used. In this way, business and corresponding error handling are scattered everywhere, and later maintenance is easy to make mistakes.

Thinking from the bottom to the top: the bottom is the most basic data layer, whether the data of the business process can move down to the bottom layer, and then call the underlying explicit semantic interface function to achieve the upper level business, instead of putting a bunch of judgement logic to the business layer.

Think from the top to the bottom: there should be an indirect layer between the business layer and the bottom data, which provides higher-level functions to the top, encapsulates the bottom data to the bottom, and provides a higher-level interface.

Similar business processing adopts similar methods instead of a bunch of conditions. For scope a-c, this method is used. For scope d-f, this method is used. For other types of business, other methods are used. In this way, business and corresponding error handling are scattered everywhere, and later maintenance is easy to make mistakes.

If a class needs to obtain relevant information from other classes, it should not rely on the inheritance organization relationship between classes, but try to obtain it through this forced conversion, because this kind of hierarchical relationship may change in the future, and the change of this kind of hierarchical relationship will not know the users, so when implementing similar needs, it is necessary to reduce the external dependency as much as possible Low, it is recommended to adopt the message mode. Each layer specifies the responsibility of the message, passing the request up layer by layer until a certain layer responds.

this this

Uniformity

Consistency refers to the consistency of naming UI elements and code, and the consistency of naming the same logical elements. Its core vocabulary in UI layer, middle layer, network layer and background interface should be consistent, so as to increase the readability of code.

Consistency is reflected in resource management. For the same resource, Whoever applies will be responsible for release. Whoever increases the citation count is responsible for the reduction.

It is important to maintain code consistency in the settings of some general functions. For example, when setting control font, the native system will provide a set of interface, and the self drawing part will also provide a set of interface. When using it externally, there will be doubts. Do you want to use the native interface or self drawing interface to set font? Will they influence each other? In the early design, only one set of interface is better for the same type of function.

If similar operations can be gathered together, they must be gathered together so that the logic can be aggregated rather than scattered.

Modify impact assessment

For example, if you change branch a of function a, branch B of function a remains unchanged. The external O1 module uses the B branch of a function, and the O2 module uses the a branch of a function. What are the impact areas involved in this modification? O2 module is definitely to be tested. Does O1 module need to be tested? The answer is yes. In a broad sense, any module that calls a function must be retested. Even if there is no branch involved in this modification, test it.

When trying to modify the background program, pay attention to the compatibility with the previous system.

When modifying a problem with a relatively large scope, if there are too many areas involved, in order to solve the final problem and smooth transition in testing, it is necessary to divide and conquer the problem, make statistics and summary according to the functional requirements module, and then assign the problem list to each person in charge according to the module, so that they can further modify it in a decentralized way, so as to ensure large-scale problems Provides a buffer period for development and testing.

For example, this modification point can be divided into the following sets,

Set 1: what is involved

Set 2: what is involved

Set 3: what is involved

logical completeness

For hierarchical calls, special attention should be paid to the consistency of resource application and release. This is particularly easy to miss. For example, if you press in the cache first and then make a request, the time to clean up the cache should cover every execution path after the request is made. 7.1 failed to send the request 7.2 succeeded in sending the request and responded successfully 7.3 succeeded in sending the request and failed in responding

For a piece of business code, there is only one correct path, but there are many wrong paths. How to deal with the possible errors in this process is the obvious power.

If you encounter something that needs special processing, you should prioritize the majority of cases on the backbone logic and handle the extra in the extra branches.

If the network request is involved, if the page is closed halfway, please pay attention to the cleaning operation of the request resource, so that the last invalid response will not be received when the page is reopened.

Preparation before optimization

The optimization without profile is nonsense. Once the reconstruction is started, the optimization goal must be specified. All relevant modifications are focused on the goal and cannot deviate. Before optimization, it is necessary to analyze the current situation, formulate plans and quantifiable objectives. After optimization, it is necessary to extract relevant data and summarize and compare the quantifiable analysis and optimization results. Background reconstruction needs to configure a / b scheme. For modules or businesses that may change, or a or B scheme is not easy to choose, which scheme can be used for background configuration. When the reconstructed version goes online, the old module should be retained first. If there is a problem, the old module can be configured in the background and switched back to the old module. This idea can be used together with gray-scale publishing (5W, 10W)

In the process of component refactoring, we need to follow the minimum impact range. One refactoring only affects this business as far as possible, does not affect other businesses, and ensures controllability and testability.

Maintenance experience

If there is a new version of interface library or a better third-party interface library, how to choose the third-party library used in the old project?

When there are many intertwined logics in old code, it is necessary to change many places to change the word bug. It is not easy to assess the scope of the impact of changes. At this time, in order to maximize compatibility with old code, it is not possible to continue to fill and dig holes on the basis of old code. If you choose one of the simple interfaces, use clear and simple logic to achieve, and then gradually replace the old one Old module, improvement of jogging.

When you need to add new functions to the original functions, pay special attention to the fact that the instructions and processes used by the original functions cannot be changed. For example, to query the days information of product a, the original instruction only supports the query of one product. Now other interfaces query multiple products at the same time, while the original instruction only realizes the query of single product information. Then, there are two solutions:

优点 缺点 方法一:修改原有指令,使其支持多条信息的查询 增加指令的功能 需修改原有查询单条产品的页面,增加了测试成本 方法二:不改动原有指令,新增支持多条信息查询指令 不会影响已有功能 类似功能有多处实现,查多条包含查一条的功能

Because querying one product information is a special case of querying multiple product information, method one is better for maintainability.

A brief design of authority judgment function

A-- ID1, ID3 B-- ID2, ID3 C-- ID4

Now we need to design a function for permission judgment. Given the function ID and account number, do you want to return whether to allow this operation judgment?

One is from the top to the bottom, judging from the entry ID and each operable ID segment. The advantages are intuitionistic and simple, but the disadvantages are not good for scalability. When adding new entries in the future, multiple methods need to be modified: from the top to the bottom, the logic is simple and direct, and the scalability is poor

bool IsAllow(Account acnt, int nFunId) { if (A == acnt) { if (nFunId == ID1 || nFunId == ID3) { return TRUE; } } else if (B == acnt) { if (nFunId == ID2 || nFunId == ID3) { return TRUE; } } else if (C == acnt) { if (nFunId == ID4) { return TRUE; } } return FALSE; }

Another method is to gather each transaction ID and the operational conditions from the bottom to the top. This method has good scalability and readability, and is recommended.

struct TIDInfo { int nId; vectorAccount vAllowAcntType; // 该ID要求的账号属性 bool IsAllow(Account acnt) // 给定账号是否存在特定属性 { return vAllowAcntType.find(acnt) != vAllowAcntType.end(); } } vectorTIDInfo allIdInfo; // 所有功能ID集合 bool IsAllow(Account acnt, int nFunId) { for (int i = 0 ; i allIdInfo.size(); ++i) { if (allIdInfo[i].nId == nFunId) { return allIdInfo[i].IsAllow(acnt); } } return FALSE; }