1. Branch development process
GIT branch development specification, specific please refer to: www.jianshu.com/p/cbd8cf5e2… .
Code specification
Mainly use the Java language for development, strictly follow the Java coding specification of Sun Company. In addition, there are the following supplements.
2.1 case
Constants are capitalized and words are separated by an underscore character (_).
Names except constants are mixed with case to improve the readability of names.
Lowercase letters are generally used, but the first letter of the name of a class and interface, as well as the first letter of any middle word, should be capitalized.
2.2 Encoding Format
Ensure that the IDE working environment uses UTF-8 encoding.
Indent with Spaces instead of tabs.
All indents use 4 Spaces. You can set IDE 1Tab=4 Spaces.
For code files that are not created for the first time, the reformate operation is prohibited. This operation will destroy the history of code modification and result in push, merge, and pull operations with high probability.
2.3 Constant Definition
Numbers or characters with special meaning should be defined in the form of constants, and the meaning of constants should be explained to avoid magic numbers.
2.4 Define common constants
For the use of some common constants, we should define corresponding constant classes separately and use them in a unified manner, instead of defining and directly using them in business classes and function classes.
2.5 Naming Rules
Package:
1.1 package: each package name always lowercase, tentatively will com. Keegoo. + (module) as the general prefix, such as com. Keegoo. Demo. Blog. Service, com. Keegoo. Demo. Blog. Dto;
1.2 a different business advice create package, such as the User of business: com. Keegoo. User. The service, com. Keegoo. User. The dto;
Class: The class name must be a noun and begin with a capital letter. Class names should be simple and clear.
Interface:
3.1 Interface is tentatively provided in the form of XxxService;
3.2 The Interface provided shall be in the form of Java Interface;
3.3 Each Interface of an independent business should have an independent package, and a package can contain multiple interfaces of the business module;
3.4 One method of each Interface corresponds to a so-called “middle layer service Interface”, which needs to be described in accordance with the specification;
Cache naming rules: Use the namespace for cache keys to avoid conflicts. At the same time, consider the cache hit ratio and do not waste cache space.
2.6 Controller, Interface class, interface implementation class preparation matters needing attention
Business logic cannot appear in controller class, only Service class can be directly called, not Biz class (Biz class is the implementation encapsulation of business logic, does not rely on DAO layer, can do unit test independently), while Manager class is the glue of Service, Biz and DAO. To coordinate the three executive relations.
The interface definition class only defines methods, which are implemented in the implementation class. The interface ends with xxxService and the interface implementation class ends with xxxServiceImpl.
2.7 annotations
Method annotation: Each interface or method should have an overall description of the method, including the function implemented by the method, the detailed meaning of parameters, the value of return value and its detailed meaning.
Class annotations: For utility classes or process classes, you need to specify the functionality of the class in class annotations. For Model classes, annotate important attributes with meaning, overloading the hashCode and equals, toString methods if necessary.
3. Design specifications
3.1 Abstraction of functional modules
In the development process of business modules, it is necessary to avoid excessively long methods and to extract and abstract reasonable function modules to avoid copying the same code and similar codes everywhere.
3.2 Single Responsibility Principle (SRP)
The single responsibility principle states that a class should have only one cause that causes it to change.
The reason for the change is called “responsibility”. If a class has more than one reason for its change, it means that the class has more than one responsibility, and further, that the responsibilities are coupled together. This will cause the mutual influence of responsibilities, and the change of one responsibility may affect the realization of other responsibilities, or even cause other responsibilities to change. This kind of design is very fragile.
This principle seems to be the simplest and best understood, but in fact, it is difficult to fully achieve. The difficulty lies in how to distinguish the “responsibility”, which is not quantified by standard, which is the responsibility, how much granularity of the responsibility, how to refine the responsibility and so on. Therefore, in actual development, this principle is also the easiest to violate.
3.3 Open-Closed Principle (OCP)
The open-close principle states that a class should be open for extension and closed for modification. Generally referred to as the open and closed principle, the open and closed principle is a very core principle in the design.
The open-close principle requires that the behavior of a class be extensible, and that it be extended without modifying existing code, source code, or binary code.
It seems like a contradiction, but how do you do that?
The key to implementing the open closed principle is proper abstraction, separating the parts that change from those that don’t, and reserving extensibility for the parts that do change, such as hook methods or dynamically composed objects.
This principle may seem simple, but in fact, it is almost impossible, and unnecessary, for a system to fully comply with the on/off principle. Moderate abstraction can improve the flexibility of the system, making it extensible and maintainable, but excessive abstraction will greatly increase the complexity of the system. Instead of getting bogged down in over-design, you should just apply the open and close principle where you need to change it.
3.4 Liskov Substitution Principle (LSP)
The Richter’s substitution principle states that child types must be able to replace their parent types. This is clearly a case of polymorphism, which can avoid some hidden errors in the application of polymorphism.
In fact, when a class inherits from another class, the subclass has properties and operations that can be inherited from the parent class. In theory, replacing the parent type with a subtype should not cause errors in the program that used the parent type.
Unfortunately, there are situations where this can be a problem, such as: If the child type covers some method of parent types, or modified the parent type subtype some attribute’s value, then use the parent type of original program may appear mistake, because during the period of running, on the surface, it is the parent type of method calls, need is the function of the parent type method, but the actual operation call coverage is indeed a subtype implementation method, And that method is not the same as the parent type, which can cause an error.
From another perspective, the magnitude of substitution principle is to realize the opening and closing one of the main principles, the open closed principle request open for extension, expand an implementation method is the use of inheritance, and magnitude of substitution principle is to guarantee a subtype can replace the parent type correctly, only can replace correctly, can we achieve extension, the extension will appear mistake.
3.5 Dependence Inversion Principle (DIP)
The dependency inversion principle refers to relying on abstractions rather than concrete classes. To do dependency inversion, you typically do:
High-level modules should not depend on low-level modules; both should depend on abstractions;
Abstract should not depend on concrete implementation, concrete implementation should depend on abstraction;
It is a classic misconception that when hierarchical calls are made, the higher level calls “interfaces owned by the lower level”. In fact, the general high-level modules, which contain the processing of business functions and business policy choices, should be reused, and it is the high-level modules that influence the underlying implementation.
Therefore, the low-level interface should be proposed by the high-level and then implemented by the low-level, that is, the ownership of the low-level interface is in the high-level module, so it is a kind of ownership inversion.
This is the famous Hollywood principle: don’t call us, we’ll call you.
3.6 Interface Segregation Principle (ISP)
The principle of interface isolation states that customers should not be forced to rely on methods they do not use.
This principle is used to deal with interfaces that are “big” and have a lot of action declarations and responsibilities. When the client uses such an interface, it usually has many methods that it does not need. These methods are a kind of interface pollution for the client, which is equivalent to forcing the user to find the method he needs in a lot of “garbage methods”.
Therefore, such interfaces should be separated into customer-specific interfaces based on customer requirements. In this way, the interface contains only the operation statements required by customers, which not only facilitates the use of customers, but also avoids errors caused by interface misuse.
In addition to separating code directly, interfaces can be separated using delegates, and in languages that support multiple inheritance, interfaces can be separated using multiple inheritance.
3.7 Least Knowledge Principle
The least knowledge rule is this: Only talk to your friends.
This principle is used to guide us when designing the system, we should minimize the interaction between objects, objects only talk to their friends, that is, only to interact with their friends, thus loosening the coupling between classes. Reducing the interdependence of classes by loosely coupling them so that changes in one part of the system do not affect other parts, making the system more maintainable.
So what kind of people can be considered friends? The least knowledge principle provides some guidance:
The current object itself;
An object passed in as an argument to a method;
The object created by the current object;
The object referenced by the instance variable of the current object;
An object created or instantiated within a method;
In summary, the least knowledge principle requires that our method calls remain within certain bounds and minimize object dependencies.
3.8 Other Principles
In addition to the principles mentioned above, there are some familiar ones, such as:
Interface oriented programming;
Preference for composition/aggregation over inheritance;
Of course, there are also many less familiar principles, such as:
The data a class needs should be hidden inside the class;
There should be zero or only conductive coupling between classes, in other words, classes either have no relationship with each other or only use operations provided by another class’s interface;
Distributing system functions as uniformly as possible horizontally;
4. Log specification
Logs are classified into the following five types according to their severity and functions:
FETA: Fatal error, the program cannot or should not run properly. Logs at the FETAL level record critical errors that cause the program to fail to run properly, such as failure to obtain FileSystem objects, Job running failures, and ODFS failure to write important data files.
ERROR: indicates a serious ERROR that does not affect program flow. Tool can continue to run. The error-level logs record serious errors that do not affect the running of the program, such as the Parser parsing failure. The portion of the log output after an exception is caught in the code will be at the ERROR level.
WARN: indicates warning logs that do not affect program flow and allow Tool to continue running. Logs at the WARN level are similar to logs at the ERROR level. However, logs at the ERROR level cannot be correctly judged. For example, logs to be captured in a certain round are 0. ERROR logs usually detect problems in some or several aspects of code, flow, or data during program running.
INFO: indicates information logs that do not affect program flow. Tool can continue to run. INFO level logs are used to record statistics, such as capture statistics, and necessary information, such as program start and stop.
DEBUG: DEBUG logs, which do not affect program flow and enable Tool to continue running. DEBUG logs record debugging information. Logs at this level are not generated when running online.
These log levels are designed to facilitate log filtering. For online systems, the log level is usually set to WARN. This enables maintenance personnel to quickly identify problems based on logs and does not cause performance problems due to frequent disk writes. When you search for a specific problem, you may need to set the log level to DEBUG to locate the problem through more output information.
5. Log format
Log format refers to the format that each log output to a log file follows. For convenience, each log format consists of several “key=value” attribute pairs separated by tabs (” \t “). There are a few special attributes that are slightly different and do not take the form “key=value” :
Time: Time is the first entry in a log. Because the Outlog automatically records the log time in the yyyyMMddHHmmssSS format, you do not need to add the key=value format.
Level: Indicates the second entry of a log. The LEVEL is in the format of [LEVEL], for example, [INFO].
Message body: The message body is the last entry in a log. To be more intuitive, the message body does not use the “key=value” format, but directly output, for example, “This is a message.”.
All other attributes are in the key=value format. These attribute pairs are located between the level and the message body, separated by a TAB character (that is, “\t”) and do not require sorting. For the key in key= Value, some common values can be defined as constants, such as CLASS (CLASS name) and ERROR (ERROR type). For unusual or special requirements, you can define the key in the log, and ensure that the values are consistent during parsing. There is also a special attribute in the property called “ERROR”, which is used to indicate the type of ERROR. This attribute is required for logs of the ERROR and FETAL levels, but not for logs of other levels. The value of the “ERROR” attribute has a fixed range, including but not limited to the following:
IOException
ConnectionRefused
Link: http://www.jianshu.com/p/93e3d991756b