directory

general

  • KISS (Keep It Simple Stupid)

  • YAGNI

  • Do the simplest thing

  • Separation of concerns

  • Keep things from repeating themselves

  • Write code for maintainers

  • Avoid premature optimization

  • Boy Scout rule

  • 2021Java interview treasure book

Module/class

  • Minimal coupling

  • Demeter’s rule

  • Composition over Inheritance

  • orthogonality

  • Conservatism principle

  • Inversion of control

Module/class

  • Maximized polymerization

  • Richter’s substitution principle

  • Open/closed principle

  • Single responsibility principle

  • Hiding implementation details

  • Corey’s law

  • Encapsulate frequently changed code

  • Interface Isolation Principle

  • Command query separation

KISS

Most systems work best if they are kept simple rather than complex.

why

  • Less code takes less time to write, has fewer bugs, and is easier to fix.

  • Simplicity is the pinnacle of complexity.

  • Perfect situation, not jumbled, but left.

YAGNI

YAGNI means “you don’t need it” : don’t do extra things before you have to.

why

  • Making any features that are only needed in the future means diverting effort from what needs to be done in the current iteration.

  • It bloats code; Software becomes larger and more complex.

How to do

  • Make them happen when you really need them, not when you see you need them.

Do the simplest thing

why

  • Only when we only solve the problem itself can we solve the actual problem to the maximum.

How to do

  • Ask yourself, “What’s the easiest thing to do?” .

Separation of concerns

Separation of concerns is a design principle that separates a computer program into different parts so that each part focuses on a single concern. For example, the business logic of an application is one concern and the user interface is another. Changing the user interface should not require changing the business logic or vice versa.

To quote Edsger W. Dijkstra (1974) :

I sometimes refer to this as “separation of concerns,” and even though it’s impossible to do exactly that, it’s the only mind-organizing technique I know of that works. This is what I mean by “focusing your attention on one aspect” : it doesn’t mean ignoring other aspects, just doing justice to things from one perspective and things that are irrelevant on the other.

why

  • Simplify the development and maintenance of software applications.

  • When concerns are well separated, parts can be reused and developed and updated independently.

How to do

  • Divide program functionality into as few modules as possible.

Keep things from repeating themselves

Within a system, every knowledge must have a single, unambiguous, authoritative representation.

Every important feature in a program should only be implemented in one place in the source code. In cases where similar functions are executed by different blocks of code, it is often beneficial to abstract out the different parts and combine them into a single function.

why

  • Repetition (unintentional or intentional repetition) can lead to nightmarish maintenance, poor maintenance and logical inconsistencies.

  • Changes to any single element in the system do not require changes to other logically unrelated elements.

  • In addition, the changes in the elements of the related logic are predictable and uniform, and therefore synchronized.

How to do

  • Write business rules, long expressions, if statements, mathematical formulas, metadata, and so on in only one place.

  • Identify a unique source for each knowledge used in the system, and then use that source to generate applicable instances of that knowledge (code, documentation, tests, and so on).

  • Use the Rule of three.

Write code for maintainers

why

  • Maintenance is by far the most expensive phase of any project.

How to do

  • _ become _ maintainer.

  • Whenever you write code, remember that the person who ends up maintaining it is a violent psychopath who knows where he lives.

  • If someone starting out has mastered the code, they get a kick out of reading it and learning about it, writing code and comments with that in mind.

  • Don’t make me think.

  • Use the Principle of Least Astonishment.

Avoid premature optimization

To quote Donald Knuth:

Programmers waste a lot of time thinking about or worrying about the speed of non-critical parts of a program, and trying to optimize these things actually has a very negative impact on debugging and maintenance. For example, 97% of the time, we should ignore inefficiencies: premature optimization is the root of all evil. However, we should not throw away our opportunity in the crucial 3%.

Of course, you need to understand what is “premature” and what is not.

why

  • Where the bottleneck is is unknown.

  • After optimization, reading and maintenance may be more difficult.

How to do

  • Make It Work, Make It Right, Make It Fast

  • Don’t optimize when you don’t need it, only optimize when you find a bottleneck.

Minimal coupling

Coupling between modules/components is the degree to which they depend on each other, and lower coupling is better. In other words, coupling is the probability that code unit “B” is “broken” after an unknown code unit “A” changes.

why

  • Changes in one module often lead to changes in other modules, creating ripple effects.

  • Module assembly may require more effort and/or time due to increased dependencies between modules.

  • Specific modules may be difficult to reuse and/or test because related modules must be included.

  • Developers may be afraid to change code because they are not sure what will be affected.

How to do

  • Eliminate, minimize, and reduce the complexity of necessary associations.

  • Reduce coupling by hiding implementation details.

  • Use Demeter’s rule.

Demeter’s rule

Don’t talk to strangers.

why

  • This usually leads to tighter coupling.

  • Too many implementation details can be exposed.

How to do

Object methods can only call the following methods:

  1. Methods of the object itself.

  2. Method in a method parameter.

  3. Method of any object created in the.

  4. Object to any direct property or field method.

Composition over Inheritance

why

  • The coupling between classes is reduced.

  • With inheritance, it is easy for subclasses to make assumptions and break the Richter’s substitution principle (LSP).

How to do

  • Tests the LSP (substitutability) to determine when to inherit.

  • Use composition when there is an “have” (or “use”) relationship and inheritance when there is a “is” relationship.

orthogonality

The basic idea of orthogonality is that things that are conceptually unrelated should not be related in the system.

Source: Orthogonal

The simpler it is, the more orthogonal the design, the fewer exceptions there are. This makes it easier to learn, read and write programs in the programming language. Orthogonal features are meant to be independent of environment; The key parameters are symmetry and consistency.

Source: the Orthogonality

Conservatism principle

Adhere to the conservative own actions, freely accept the actions of others.

Collaborating services depend on each other’s interfaces. Often, the interface needs to be promoted, causing the other end to receive unspecified data. If the data received does not adhere strictly to the specification, the simple implementation will simply refuse to cooperate. A more complex implementation can ignore data that it cannot recognize.

why

  • To be able to improve services, you need to ensure that providers can make changes to support new requirements with minimal disruption to existing clients.

How to do

  • Code that sends instructions or data to other machines (or other programs on the same machine) should conform to the specification perfectly, but code that accepts input should accept inconsistent input, as long as its meaning is clear.

Inversion of control

Inversion of control is also known as the Hollywood principle, “Don’t call us, we’ll call you.” It is a design principle in which the custom authoring part of a computer program receives control flow from a common framework. Inversion of control has a strong implication that reusable code and problem-specific code are developed independently, even though they work together in the application.

why

  • Inversion of control is used to improve the modularity of programs and make them extensible.

  • Separate task execution from implementation.

  • Focus the module on its design task.

  • Make modules independent of assumptions about how other systems perform their tasks, relying instead on conventions.

  • To prevent side effects during module replacement.

How to do

  • Using factory Mode

  • Use the service locator pattern

  • Using dependency Injection

  • Using dependency Lookup

  • Use the template method pattern

  • Using the Policy Pattern

Maximized polymerization

The cohesion of individual modules/components is the degree to which their responsibilities form meaningful units, and the higher the cohesion, the better.

why

  • This increases the difficulty of understanding modules.

  • This increases the difficulty of maintaining the system because changes in domain logic affect multiple modules, and changes in one module require changes in related modules.

  • Because most applications do not need the random set of operations provided by modules, it becomes more difficult to reuse modules.

How to do

  • Group-related functions share a responsibility (for example, in a class).

Richter’s substitution principle

The Richter substitution principle (LSP) is all about the expected behavior of objects:

Objects in a program should be substitutable for instances of their subtypes without changing the correctness of the program.

Open/closed principle

Software entities, such as classes, should be open to extension but closed to modification. That is, such an entity can be allowed to modify its behavior without changing its source code.

why

  • Improve maintainability and stability by minimizing changes to existing code

How to do

  • Write classes that can be extended (not modified)

  • Expose only the moving parts that need to be replaced and hide everything else.

Single responsibility principle

There are reasons why a class should not have multiple modifications.

The long version: Each class should have a separate responsibility, and that responsibility should be completely encapsulated by the class. Responsibilities can be defined as reasons for modifications, and classes or modules should have one and only one reason for modifications at a time.

why

  • Maintainability: Only one module or class needs to be modified.

How to do

  • Use Corey’s law.

Hiding implementation details

Software modules provide interfaces to hide information (that is, implementation details) without giving away any unnecessary information.

why

  • When the implementation changes, the interface used by the client does not have to change.

How to do

  • Minimize the accessibility of classes and members.

  • Do not disclose member data.

  • Avoid putting private implementation details into a class’s interface.

  • Reduce coupling to hide more implementation details.

Corey’s law

Corey’s Law is all about choosing a well-defined goal for any particular code: do only one thing.

  • Curly’s Law: Do One Thing

  • The Rule of One or Curly’s Law

Encapsulate frequently changed code

A good design identifies the hot spots that are most likely to change and encapsulates them behind the API. When an expected change occurs, the change remains local.

why

  • Minimize the required changes as they occur.

How to do

  • Different concepts behind encapsulating apis.

  • Divide potentially different concepts into their own modules.

Interface Isolation Principle

Reduce bloated interfaces to multiple smaller, more specific client-specific interfaces. An interface should be more dependent on the code that calls it than the code that implements it.

why

  • If a class implements an unwanted method, the caller needs to know the method implementation of that class. For example, if a class implements a method but simply throws an exception, the caller will need to know that the method should not actually be called.

How to do

  • Avoid bloated interfaces. Classes should not implement any methods that violate the single responsibility principle.

Boy Scout rule

The Boy Scouts of America has a simple catch-22 that we can apply to our careers: “Leave camp cleaner than you arrived”. According to Scouting rules, we should always keep the code cleaner than it looks.

why

  • When changes are made to an existing code base, code quality tends to degrade, accumulating technical debt. According to Scouting rules, we should pay attention to the quality of each Commit. No matter how small, technical debt is resisted by constant restructuring.

How to do

  • Make sure every commit doesn’t degrade the quality of the code base.

  • Any time someone sees some code that isn’t clear enough, they should take the opportunity to fix it there.

Command query separation

The command query separation principle states that each method should be a command that performs an operation, or a query that returns data to the caller but cannot do two things at once. Asking questions should not change the answer.

Using this principle, programmers can code with more confidence. Query methods can be used anywhere and in any order because they do not change state. With commands, you have to be more careful.

why

  • By clearly separating methods into queries and commands, programmers can code more confidently without knowing the implementation details of each method.

How to do

  • Implement each method as a query or command. 2021Java interview treasure book

  • The method name uses a naming convention. The method name indicates whether the method is a query or a command.