GRASP design Principle

GRASP(General Responsibility Assignment Software Pattern) is a General Responsibility Assignment Software design Pattern. It was developed by Craig Larman, author of Applying UML and Patterns. The general approach in object-oriented design is to conceive of the responsibilities, roles, and collaborations of objects. Generally speaking, we analyze the problem domain in the coding process and abstract objects from it to solve the problem. The difference between simple object-oriented design and good object-oriented design lies in how to divide the roles of objects, assign reasonable responsibilities to objects, and interact with each other.

In my understanding of the nine principles of GRASP, SOLID seven principles, GOF23 design modes of three design principles. GRASP is at the top, SOLID further elaborates on it, and GOF further generalizes more specific patterns based on these principles. The GoF pattern is a solution to a specific problem, and GRASP looks at object-oriented software design from a higher Angle. It is the foundation of THE GoF design pattern. GRASP is the basic principle of the assignment of responsibilities of objects. Its core idea is the assignment of responsibilities and the design of objects with responsibilities.

Information Expert pattern

Definition:

If a class has information necessary to perform a responsibility, assign that responsibility to that class.

To understand:

We can follow this principle when we are not sure whether A responsibility should be assigned to class A or class B. This design principle is different from the single design principle in that the single responsibility principle considers whether the responsibilities in a single class belong to a single responsibility. The information expert pattern considers whether to place that same kind of responsibility in class A or class B. Assuming we have a Rectangle class with width and height attributes and a Measure class, should we add the getArea() method to the Rectangle or pass width and height parameters to the Measure class? How about implementing getArea() in Measure? According to this guideline, now that the Rectangle method already has the necessary attributes to implement getArea(), it should put the getArea() method into the Retangle class. Similarly what if you have a calculated property? This principle also applies, for example, in the widthHeightRatio. == This principle is consistent with the congestion model in DDD design idea, you can understand. = =

The Creator (Creator)

Definition:

If one or more of the following conditions are met, the responsibility for creating instances of class A can be assigned to class B

  • B contains A;
  • B.
  • B has the data that initializes A and passes the data to class A when creating instances of class A;
  • B records an instance of A;
  • B frequently uses A.

To understand:

In object-oriented design, you can’t avoid creating objects. Suppose object B creates object A, then object B produces A coupling with object A. And that coupling cannot be removed, even if you assign the responsibility of creating object A to object C, that coupling is still there, just by moving from object B to object C, that coupling is still there in the system, and it cannot be avoided. So when we cannot eliminate the coupling, we should consider how to reduce the coupling degree. This principle provides guidelines. The above conditions implicitly indicate that B is already coupled to A, and since B is already coupled to A, we might as well assign to him the responsibility of creating A. With this assignment, there is only one coupling of A and B in the system. If the responsibility for creating A is assigned to C, then there will be A coupling between B and A(B contains conditions such as A and B frequently uses A) and C and A. In the JDK Map, the creation responsibility for the Entry class is assigned to the Map that holds it. Another classic example is Order creating an SKU.

Low coupling

Definition:

Coupling is a measure of the degree of dependency between elements (classes, modules, subsystems) in a system, and good design should minimize this degree. Here are some examples of coupling:

  • A has an attribute of type B;
  • A calls B’s method;
  • Methods of A contain references to B, such as method parameter type B or return type B.
  • A is A direct or indirect subclass of B;
  • B is an interface, and A implements the interface.

To understand:

The more of these coupling conditions occur, the higher the coupling degree. These conditions are simply defined as A’s “perception” of B. This awareness is reflected in object properties, method parameters, method return values, and interfaces. Highly coupled classes rely too much on other classes, and this design can lead to changes in one class causing significant impact on the other classes, making it difficult to maintain and understand the system. When you reuse a highly coupled class, you have to reuse other classes on which it depends, and the system is not reusable. Here are some ways to reduce coupling: minimize references to other classes, increase access to methods and properties, and use composition/aggregation principles instead of inheritance whenever possible. In fact, polymorphism in object-oriented programming is a way to reduce type coupling. Without polymorphism, our method needs to know all subclass types, whereas polymorphism only needs to know the parent class. Reduced type coupling.

High Cohesion

Definition:

That is, functionally closely related responsibilities should be placed in a single class that collectively performs a limited set of functions. This is consistent with the SOLID principles of single responsibility and interface isolation.

To understand:

As an intuitive example, if the functionality of a class is highly cohesive and has a single responsibility, the complexity of the class is reduced, which leads to lower maintenance costs. In the traditional Dao design pattern, we should try to split daOs with a single fine-grained responsibility for Service invocation. In a Service, it is obvious which Dao is called by which type of data operation, and the individual DAOs are not too bloated to cause poor maintainability. High cohesion also represents high isolation, which means that you can change one method without affecting too many other classes.

Controller (the Controller)

Definition:

Assign responsibility for receiving or processing system event messages to a class. This class can represent: entire systems, devices, or subsystems; Use case scenarios for system events when they occur, using the same controller in the same use case scenario to handle all system events.

To understand:

A controller is a component object that receives or handles events. The C in the MVC pattern is the controller pattern. A controller should handle a class of events. For example, a common UserController in our project takes care of adding and deleting users. A subsystem needs to define multiple controllers for different event handling. In general, a controller should delegate the functionality to a Service or other business processing object, which only coordinates and controls the business process and contains as little business logic as possible.

Polymorphism (Polymorphism)

Definition:

When related choices or behaviors vary with a type (class), polymorphic operations are used to assign responsibility to the type of behavior change.

To understand:

In object-oriented design, operations are often performed according to the type of the object. Suppose we have a Rectangle, Circle, and Square class to Draw a picture. If you want to Draw according to different graphics classes, you need to use if-else program structure in the method of Draw class, and then judge the type to Draw. If you add a graphics class, you’ll need to change this code again. This violates the open close principle. In the form of polymorphism, the concrete steps of drawing are handed over to the subclasses of graphics. You don’t need to use if-else program structures, and you don’t need to modify the Draw class when you add graphics classes. By introducing polymorphism, subclass objects can override the behavior of parent objects and better adapt to change. Policy pattern and factory method pattern are good examples of polymorphism.

Pure Fabrication

Definition:

Assign a set of highly cohesive responsibilities to a fictitious or easily handled “behavior” class, which is not a concept in the problem domain, but a fictitious thing to support high cohesion, low coupling, and reuse.

To understand:

A domain model in OO design is a modeled representation of a concept within a domain or an object in the real world. The key idea in creating domain models is to reduce the representational difference between the software people’s thinking and the software patterns. Therefore, at OO design time, most classes in the system are derived from real classes in the real world. However, when assigning responsibilities to these classes, you may encounter design principles that are difficult to satisfy with low coupling and high cohesion. The pure fiction model provides a solution to this problem by assigning a highly cohesive set of responsibilities to artificial classes that do not represent the concept of the problem domain, but rather imaginary things. An obvious example is the adapter pattern, which conjured up the concept of an adapter to decouple the coupling between two objects. Many projects need to operate on a database to persist objects in the system. The information Expert pattern suggests assigning the responsibility for persistence to each specific model class. But this suggestion has been proved to be inconsistent with the principle of high cohesion and low coupling. As a result, the current practice tends to include classes such as DAO or Repository in the project. These classes do not exist in the domain model.

Indirect (Indirection)

Definition:

Assigning responsibilities to intermediate objects to coordinate operations between components or services so that they are not directly coupled. An intermediate object is a mediation established between other components.

To understand:

Mediation simply means dealing with a matter through a middleman. Two objects that are directly related to each other can interact with each other through another intermediate object, thus achieving isolation and decoupling. Changes in one object do not affect the other object, but only the intermediate object. The adapter pattern in the design pattern, the bridge pattern, uses an intermediate object for decoupling.

Protected Variations

Definition:

Identify elements that are expected to change or be unstable and assign responsibility for creating stable “interfaces” for them.

To understand:

The protected change pattern, or PV, is the foundation of most programming and design and is one of the fundamental motivations for patterns that enable systems to adapt and isolate change. It corresponds to the open and close principle of object-oriented design, that is, to extend the functionality of an element without modifying the original element (class, module, subsystem or system). An obvious example is the policy pattern, which responds to possible new policies by creating policy interfaces and defining abstract methods within them. Instead of changing the original code when a new policy is created in the future, create a new class that implements the policy interface.

My personal blog, vc2x.com