Code Concise 2 - Functions, Classes

        Students who have read the spring source code must still remember the core method in spring - refresh(), which describes the startup process of the spring container for us with more than a dozen lines of code:

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) { 
			// Prepare this context for refreshing.
			prepareRefresh();
 
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);
 
			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);
 
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);
 
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory); 
 
				// Initialize message source for this context.
				initMessageSource();
 
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();
 
                // Initialize other special beans in specific context subclasses.
				onRefresh();
 
                // Check for listener beans and register them.
				registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);
 
				finishRefresh();
			} catch (BeansException ex) { 
				destroyBeans();
				cancelRefresh(ex); 
				throw ex;
			} finally { 
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

2. Function

2.1 short

        The first rule of functions is to be short, and the second rule is to be even shorter.

2.2 Do only one thing

        Take the refresh method in the spring source code mentioned at the beginning of the article as an example. What this method does is to refresh the container, and then under this abstraction level, there are multiple abstraction levels, such as: pre-refresh, get beanFactory, beanFactory preprocessing wait.

        Similarly, when we usually write a business interface, an interface implements a function, but each function can be split into multiple different sub-functions, and each sub-function is abstracted into a function instead of accumulating all business logic in In the main function, the main function is very bloated.

2.3 One abstraction level per function

        To ensure that a function does only one thing, the statements in the function must be at the same abstraction level.

        Different abstraction levels are mixed in the function, and it is difficult to judge whether an expression is a basic concept or a detail when reading the code. And, like the broken window theory, once the details get mixed up with the underlying concept, later iterations will put more details into the function.

        This rule is more idealistic, and it is difficult to write functions that only stay at one abstraction level in practical applications. But this rule can make the function short and ensure that the function only does one thing.

2.4 switch statement

        The emergence of switch is to accomplish many things, so it is difficult to achieve the above when using it: short and only do one thing. In this case, you can generally consider using design patterns or using Enum in java instead of switch.

2.5 Use descriptive names

        This point is the same as mentioned in the previous article-meaningful naming is to let readers know the name when they see .

2.6 Function parameters

        The fewer arguments to a function, the better.

2.7 No side effects

2.8 Separate commands and queries

2.9 Use exceptions instead of returning error codes

2.10 Don't repeat yourself

        The business modules used in multiple places need to be extracted. First, it is convenient for code reading, and second, if you need to modify the business logic, you only need to modify one place.

2.11 Structured Programming

2.12 How to write such a function

        Writing code is the same as writing an article. You must first think about what to write, and then polish it after writing. The first draft may be crude and unorganized, but you have to think about it carefully until you get what you want.

2.13 Summary

        Every system is built using some domain-specific language designed by programmers to describe that system. Functions are verbs of the language, classes are nouns. This does not simply mean that the nouns and verbs in the requirements document are the original assumptions of the classes and functions in the system. The art of programming is and is consistently the art of language design.

        Good programmers write systems as stories, not as programs. They make the programming language a richer and more expressive language.

        People are inert. Many times we write the code just to meet the business requirements, and the function is realized, and we don’t care whether the code is elegant or readable.

3. class

3.1 Organization of classes

        Following standard Java conventions, a class should begin with a list of variables, public static constants, if any, should appear first, followed by private static variables, private entity variables, and rarely public variables.

        Public functions should come after the variable list.

Package:

        We are used to keeping variables and utility functions private, but we are not obsessed with it. Sometimes protected variables or utility functions are also used to facilitate test access.

3.2 Classes should be short 

        This is similar to functions but also different. The name of the class should describe its responsibility. If a class cannot find a suitable name to describe its responsibility, then the class is probably too long. The more ambiguous the class name, the more likely the class has too many responsibilities.

3.2.1 Single Responsibility Principle

        The Single Responsibility Principle states that a class or module should have one and only one reason to be modified.

3.2.2 Cohesion

        Cohesion: Indicates the degree of aggregation and association between interiors. Ways to increase cohesion: 

  1. The module only exposes the minimum interface and forms the lowest dependency.
  2. As long as the external interface remains unchanged, the internal modification of the module shall not affect other modules.
  3. Deleting a module should only affect other modules that have dependencies, and should not affect other irrelevant parts.

3.2.3 Keep cohesion and you will get many short classes

3.3 Organizing for revision

        For most systems, modifications will be ongoing. By not making changes we risked the rest of the system not working as expected. In a clean system, we organize our classes to reduce the risk of modification.

Modifications in isolation:

        Requirements change, so code changes too. Abstract classes are generally used to present concepts, and concrete classes contain implementation details. Client classes that depend on specific details are at risk when the details change. We can isolate the impact of these details with the help of interfaces and abstract classes.

Guess you like

Origin blog.csdn.net/zhoushimiao1990/article/details/122672507