oomall class notes

 1. Introduction to project hierarchical structure

Controller layer (controller layer):

Role: Responsible for output and input, receiving front-end data, and returning results to the front-end.

1. Process user requests and receive user parameters

2. Call the service layer to process the business and return the response

service layer (business logic layer):

1. Encapsulate business logic and provide services for the controller layer

2. Call the dao layer or mapper layer to process data.

3. Total control, the entry point for all things

dao layer (data access layer):

1. The main responsibility is to add, delete, modify and check the database, does not include business logic, and directly interacts with the database.

ps (traditionally: the code of the dao layer and the service layer is functional, and is a function. The service calls the dao layer, bo is passed as a value, and there are only get and set methods).

(In the full-blooded model, service becomes the coordinator. Cut the code in one method of the service layer into several methods in the bo object. Divide the code blocks into smaller pieces. It will be more natural and easier to understand and improve reusability.)

The dao layer is responsible for generating bo objects, and the bo objects are used to undertake tasks assigned by the service layer.

mapper layer:

Main Responsibilities: Data storage or retrieval of data.

The mapper layer is responsible for accessing specific data.

ps1: The mapper layer and controller layer have nothing to do with object-oriented. The main battlefield is at the service and dao layers.

ps2: oomall is a hexagonal architecture, which follows the mvc architecture, emphasizing domain model (bo) and application (service). Try to make the domain model part as fat as possible, and try to put the service and dao layer code into bo. Put as much code into it as possible.

The specific meaning of colors:

The white part is in the mysql database, the blue part is obtained from other parts, the yellow part is in the mongo database, and the green part is the code written entirely in java.

Calling logic:

User requests are sent to the controller layer, the controller layer calls the service layer, and the service layer calls the dao layer or mapper layer to return data from the database.

2. Introduction to dto, vo, bo, and po

dto (data transfer object) data transfer object: [controller layer]

Used for data transmission between service layers.

Contains data objects, mainly variable definitions and get and set methods.

dto can encapsulate the data that needs to be transmitted.

vo (view object) view object: [controller layer]

Used for controller layer and front-end data transmission.

It also contains data objects, mainly variable definitions and get and set methods.

Pass the data to the front-end display in the controller layer.

bo (business object) Business object: [dao layer]

Encapsulate data in business logic.

Contains business logic.

Data that contains business logic and the business methods associated with this data.

po (persistent object) persistent object: [mapper layer]

Used to represent a record in the database, corresponding to the database table structure

po usually corresponds to the fields in the database table one-to-one

Generally used in the mapper layer or dao layer to interact with the database

Features of the oomall project: The bo object containing business logic is written in the dao layer, which is called a full-blood model.

3. Design Pattern

3.1 Creator

Who created object A.

If B contains A (overall and local relationships, such as combination relationships. For example, a superior region creates a subordinate region.), B records A, B uses A, and B has the initialization data of A, then object A is created from object B.

3.2 Information Specialist

Question: What are the basic principles for assigning responsibilities to objects?

"He who knows does it" Whoever has the information necessary to complete the responsibility will assume the responsibility.

For example: api distribution

3.3 Template method design pattern

A template method is a method defined in an abstract class that combines basic operation methods to form a general algorithm or general behavior.

A basic method is a way to implement each step of an algorithm.

For fill-in-the-blank questions written in the parent category, different sub-categories will fill in the blanks with different content.

3.4 Strategy mode

Define a series of algorithms, encapsulate them inside the object, and can be replaced at will.

It is best used at the change point, and in order to loosely couple the system and the change point, the change point is extracted from the code. Use polymorphism to implement different subclasses so that new algorithms can be added in the future.

Teacher’s example: the packaging algorithm of the shop module. The strategy pattern is used to extract the changing points, and low coupling and polymorphism are used to make it satisfy the dependency inversion principle and the Liskov replaceability principle, so that the algorithm partially meets the object-oriented ultimate goal opening and closing principle.

3.5 Bridge mode

Break the problem into two independent parts and combine them to form the final solution.

4. Seven Principles of Software Design

1.Opening and closing principle

Open for extension, closed for modification.

Every modification will not touch or affect the existing code. The already written code does not need to be touched. If you want to expand, you do not need to touch other codes.

Both new additions and modifications have a very small impact, and modifications only affect a small part of the code.

Abstraction (create a new abstract interface and unify all interfaces to this interface), constraints (polymorphism), encapsulation, change (indirect)

Judgment points and evolution points, where modifications may be made, use the opening and closing principle.

2.Liskov’s replaceability principle

Inheritance must ensure that the properties possessed by the superclass still hold true in the subclasses (parent class and subclass).

This means that when overwriting the methods of the parent class, you cannot overwrite them at will. You must make sure that the properties of the parent class still hold true in the subclass.

The properties of the parent class cannot be violated. The properties of the parent class are still available in the subclass, and the subclass can add its own properties.

Satisfying Liskov's substitution principle must satisfy the opening and closing principle .

Inheritance is a highly coupled behavior, and the Liskov substitution principle requires that inheritance cannot modify the behavior of the parent class.

3. Dependency inversion principle (radical)

Interface-oriented programming, not implementation-oriented programming.

A high-level module should not depend on a low-level module, both should depend on its abstraction. Abstractions should not depend on details; details should depend on abstractions. (What people say is to make interfaces and rely on interfaces).

To put it simply: only call the interface, not the specific implementation.

Satisfying the Dependency Inversion Principle must satisfy the Liskov Substitutability Principle : because only methods are defined in the interface and no implementation is defined.

4. Single responsibility principle (radical)

A class has one and only one reason for its change, otherwise the class should be split.

Responsibility: Each business method assigns responsibility to an object.

5. Interface isolation principle (radical)

The client should not be forced to rely on methods it does not use. (People say: An interface cannot correspond to methods that it does not need. The interface should be split into multiple small interfaces, and then relied on one by one until an atomic and perfect pairing is formed.)

6. Demeter Principle (Radical)

Don’t talk to “strangers,” only talk to your immediate friends.

If two software entities do not need to communicate directly, direct calls to each other should not occur, and the calls can be forwarded through a third party.

7. Principle of synthesis and reuse (radical)

Priority is given to implementation of association relationships such as combination or aggregation, followed by inheritance relationships.

5. Region module

4.1 Usage mode:

Creator + Information Expert

4.2 Knowledge points:

— Caching is only done in service and dao objects, bo objects are not cached.

— The cache does not store the same thing.

— The dynamic model is the flesh and blood of object-oriented, the dynamic model is the sequence diagram, and the static model is the class diagram.

— The exception branch will not be tested, all branches must be tested. Test from a functional perspective.

4.3 Read the source code:

— 1. How to create objects. 2. How to add and check (createregion, findbyid). 3. See how the dao layer code is cached (regionservice, region(getparentregion, getancestor, changestatus)).

— Depends on knowledge of javaee cache

4.4 Module structure:

controller【dtp】【vo】

dao【bo】

mapper【po】

4.5 Flow chart analysis:

1, 2, 3, and 8 are function-oriented because there are no objects yet.

Service layer responsibility distribution, how to assign the functions to be implemented to different parts. The outside of the service is function-oriented, and the inside of the service is object-oriented. The first step to add, delete, modify, etc. is to change the object.

From now on, we will only draw from the service layer to the dao layer.

The dao layer provides objects.

Loop 10 represents the 10th level administrative district,

6. payment module

4.1 Usage mode:

Factory method + adapter pattern

4.2 Knowledge points:

— The standard for making judgment timing is that if there is enough information to make a judgment, then make a judgment.

— If you report red, you need to compile it.

— The operation of redis is under core/mapper/redisUtil

— openfeign borrows all the annotations in the controller and defines its own interface to adjust other platforms, using restful style.

— The controller defines what kind of restful style we should provide for others to adjust.

—Polymorphism: Put the common ones in the parent class, and put the individual ones in the subclass. (A class with subclasses is a parent class, and the parent class has attributes common to the subclasses).

— Value object: not a full health object, only a value.

4.3 Read the source code:

— 1. Read the login authorization code and pay attention to AOP. 2. The code of dao layer channeldao.

— It depends on the knowledge of javaee microservices.

4.4 Module structure:

config:

controller:【dto】【vo】

dao:【bo】【channel】

mapper:【generator】【manual】【openfeign】

service:

channel is a payment channel.

Generator is automatically generated code, and manual is code written by yourself.

openfeign (restful-based api) is the external interface.

4.5 Flow chart analysis:

The creator in step 3, and the adapter in step 6 is an adapter interface that satisfies indirection and polymorphism, is replaceable to achieve opening and closing, follows dependency inversion, and does not satisfy interface isolation (all interfaces combined). What is taken out in step 5 is Full health object.

7. shop module

4.1 Usage mode:

Strategy mode + bridge mode

4.2 Knowledge points:

— When it is required to insert data without duplication, you can directly use the unique index feature of mysql.

— Shops and templates were originally one-to-many, but now the object model has become one-to-one, and only the default template is remembered to calculate shipping costs.

— The parent class is white and the subclass is yellow. Split the object in half. Generally, it is stored in mysql and half is stored in mongo. When you get the freight template, you need to see all the regions below. Nosql only supports the primary key query function and you cannot directly see all the areas under the freight template. For primary keys, all primary keys in nosql must be recorded in mysql. Simply put the common attributes in mysql. The advantage of nosql is that it can maximize the amount of data.

— Order module The order magnitude is very large, so mongo is used for orders. Under the premise of large quantities, the query and insertion speed of mongo will be faster.

4.3 Read the source code:

1. The insert function in RegionTemplateDao. insert function of weightTemplateDao.

4.4 Module structure:

config

controller【dto】【vo】:

dao【bo】【openfeign】【template】

mapper【openfeign】【po】

service【listener】

The listener in the service stores the content of MQ. The bo object is divided into two packages, white is under the root directory, yellow is under template, and green is under divide; those related to mongo are placed under template, and those irrelevant are placed under root directory. Because openfeign has a region module, it is written under mapper.

4.5 Flow chart analysis:

A polymorphic method is used to support two template types, divided into freight templates and weight templates, and a virtual interface is defined:

8. product module

4.1 Usage mode:

4.2 Knowledge points:

— Discount promotions are a point of change and evolution.

— Category, Product, Onsale, various Activities and their relationships are cached.

4.3 Read the source code:

1.javaee bloom filter

4.4 Module structure:

config

controller【dto】【vo】

dao【activity】【bo】【onsale】【openfeign】

mapper【jpa】【mongo】【openfeign】【po】

model【strategy】

service【listener】

4.5 Flow chart analysis:

For 1, an OnSaleExecutor interface is set up so that Product and OnSale can be accessed through the interface when calling Product and OnSale, which satisfies the dependency inversion principle, thereby satisfying the Liskov replaceable principle, and thus satisfying the opening and closing principle. Different Excutors will get different Onsale objects.

For 2, ProductFactory is extracted from the build method in ProductDao to form an independent abstract class. For different Excutors underneath, when doing the build, the excute put in is different and different subclasses are made. Build different executors. Uses polymorphic design patterns.

Using the factory method design pattern, SpecOnSaleProductFactory, ValidSaleProductFactory, and NoOnSaleProductFactory are projects, and then SpecOnSaleExecutor, ValidOnSaleExecutor, and NoOnSaleExecutor are products.

9. Other contents

1. Ideas for writing code:

1. First clarify the optional part and the calling relationship between each module.

2. Start with something simpler and more isolated.

2. Learning experience:

— If you are object-oriented, you must create new objects.

— The integration test of the region module can be used as a case study.

— Using mysql to handle 400 requests in 10 seconds has been severely blocked. Using redis for caching will be slow for the first time, but will be faster later. In theory, bo and po can be saved, but redis generally only saves bo, and it is an anemic bo. It only saves attributes, but also does not save relationships. Saving dto is the fastest, but dto cannot be saved, because the attribute is renamed and cannot respond in time. .

— Blue is the API for adjusting other modules, yellow is mongodb, white is mysql, and green is redis.

3. Notes:

1.@PathVariable is used to bind variables in the URL to parameters of the controller processing method.

2.@RequestParam is used to map request parameters to parameters of the controller method.

3. The @Repository annotation indicates that this interface is a Spring Data Repository, which is an abstraction of the persistence layer and is used to access data in the data source.

4. @RestController is a special controller annotation, indicating that this class is a controller, and the returned data will be automatically converted to JSON or XML and other formats, and written to HttpResponse.

5.@RequestMapping is used to define the mapping relationship between requests and controller methods. It can be used on classes or methods to specify the requested URL, HTTP method, request parameters, headers and other information. An HTTP GET request can be mapped to a specific processing method.

6.@Autowired is used to automatically inject beans managed by the Spring container. When using @Autowired on fields, constructors, and methods, Spring will find and automatically provide matching bean instances in the container. ''

7.@GetMapping is used to process HTTP GET requests, corresponding to a method for processing GET requests.

4. redis statement:

redisUtil.hasKey (parameter): Check whether the specified key exists in Redis and return a Boolean value to indicate whether it exists.

redisUtil.decr (parameter): Decrement the value corresponding to the specified key by 1 and return the value minus 1.

redisUtil.set (parameter): Set the specified key-value pair to Redis, and you can set the expiration time of the key.

redisUtil.get (parameter): Get the value corresponding to the specified key from Redis.

redisUtil.del (parameter): Delete the specified key from Redis.

5. Configure redis and nacos locally

1. The startup path of redis in windows:

First enter redis-server redis.windows.conf,

Then reopen the page redis-server --service-install redis.windows.conf

Start the server: redis-server --service-start

Enter the redis server: redis-cli.exe

2. The startup path of nacos in windows: E:\nacos\Nacos\distribution\target\nacos-server-2.3.0-BETA\nacos\bin, enter startup.cmd -m standalone to start the server.

Research point 1: What is the relationship between dto, vo, bo, po, database fields, and entity classes? ?

Found the following rules:

1. In terms of the completeness and scale of attributes: PO>BO>DTO>VO (Po object contains almost all attributes of dto, vo, and bo objects. It is the largest.)

2. It is speculated that the attributes added later will serve the needs of the business.

Exploration point 2: What do the controller, service, dao, and mapper layers generally return?

Before:

controller -> ReturnObject (encapsulation class)

service -> Dto object

dao->Customer (Bo object)

mapper->Po object

Now

controller -> ReturnObject (encapsulation class)

service -> Bo object

Test experience:

1. The test tests the classes used in the test method. The coverage rate looks at how many methods are entered and how much code is executed.

2. Coverage depends on the proportion. There are 2 ways to improve coverage. 1. Delete irrelevant variables, get set methods, etc., and even annotations. 2. Write more test cases.

Test syntax:

 1. This line of code simulates a condition using the Mockito framework. When the method redisUtilof this simulated object is called hasKeyand any string is passed in, the simulation return result is false.

Mockito.when(redisUtil.set(Mockito.anyString(), Mockito.any(), Mockito.anyLong())).thenReturn(true);

Knowledge point 1: Mockito.anyString() is used to match the value of character parameters. Mockito.any() is used to match the type and value of any parameter. Mockito.anyLong() is used to match the value of a long integer parameter.

Knowledge point 2: .thenReturn(true) is part of the Mockito syntax, which defines the value that should be returned when the simulation condition is matched.

2. A JSON format string is defined here, which represents the data passed in when creating a customer, including username, password, name and mobile phone number.

String body = "{\"userName\":\"699275\",\"password\":\"123456\",\"name\":\"test\",\"mobile\":\"12345678900\"}";

Knowledge point 3: Backslash (\) is an escape character, used to allow quote characters (") to appear in string literals. In JSON, all strings need to be surrounded by double quotes, and Java strings Literals are also defined in double quotes, so the inner double quotes need to be escaped with backslashes to prevent them from being interpreted as string terminators.

3. Use the MockMvc object to perform an HTTP POST request. /customerRepresents the requested URL.

this.mockMvc.perform(MockMvcRequestBuilders.post("/customer");

Knowledge point 4: this.mockMvc.perform is part of the Spring MVC testing framework and is used to execute a simulated HTTP request.

Knowledge point 5: MockMvcRequestBuilders.post is a method used to build an HTTP POST request.

errno4. Set an expected condition and use a JSON path expression to check whether the value of the field in the returned JSON object is ReturnNo.CUSTOMER_NAMEEXIST.getErrNo()the same as the returned value.

.andExpect(MockMvcResultMatchers.jsonPath("$.errno", is(ReturnNo.CUSTOMER_NAMEEXIST.getErrNo())))

 MockMvcResultMatchers.content() is used to verify the content of the HTTP response. .andExpectBindings are used in test methods MockMvcResultMatchersto declare expectations for a response. If the response does not meet these expectations, the test will fail.

Knowledge point 6: The byte stream in .content used to load the body of the previously defined String type will be transmitted in the form of a method body.

.content(body.getBytes(StandardCharsets.UTF_8))

The test sample is as follows:

@Test
    public void updateCustomerById1() throws Exception{
        Mockito.when(redisUtil.hasKey(Mockito.anyString())).thenReturn(false);
        Mockito.when(redisUtil.set(Mockito.anyString(), Mockito.any(), Mockito.anyLong())).thenReturn(true);
        String body = "{\"name\":\"赵永波\",\"mobile\":\"13159235541\"}";
        this.mockMvc.perform(MockMvcRequestBuilders.post("/customers")
                        .header("authorization", customerToken)
                        .content(body.getBytes(StandardCharsets.UTF_8))
                        .contentType(MediaType.APPLICATION_JSON_VALUE))
                .andExpect(MockMvcResultMatchers.content().contentType("application/json;charset=UTF-8"))
                .andDo(MockMvcResultHandlers.print())
                .andReturn().getResponse().getContentAsString();
    }

Reading code experience:

1. Look at the hierarchy, from outside to inside, controller->service->dao->mapper

2. Look at the type of parameters passed in

3. Look at the type of return parameters

4. Look at the method of calling the inner layer

5. Look at the business logic

Experience in drawing timing diagram:

1. Pay attention to the length of the lifeline frame. The service layer lifeline frame is the longest and will not end until all subsequent steps are completed.

2. Customer in the box: Customer, the former is an object and the latter is an entity class.

3. What is written on the arrow is the method in the latter layer, which means that the former calls the method in the latter. 

Spring Data JPA database access interface experience:

 CustomerPoMapperThe interface inherits from JpaRepository, which means it inherits a series of standard CRUD operations, and you can customize queries by declaring method names.

  • findByUserName(String userName)

    • findByTell Spring Data JPA this is a query method.
    • UserNameIt is an attribute of the entity class CustomerPo(assuming there is userNamea field here), and Spring Data JPA will search according to this field.
    • The method parameter String userNameis the value of the query condition.
    • The final generated SQL is roughly SELECT * FROM customer_po WHERE user_name = ?.
  • findByUserNameAndMobile(String userName, String mobile)

    • findBySame as above.
    • UserNameAndMobileIndicates that the query is to be carried out based on the userNameand mobiletwo fields.
    • The two parameters of the method correspond to the query values ​​of these two fields respectively.
    • The final generated SQL is roughly SELECT * FROM customer_po WHERE user_name = ? AND mobile = ?.

Database and entity class naming experience:

In Java entity classes, CamelCase is usually used, in which the first letter of each word is capitalized and there is no underline. For example, creatorIdand creatorName.

In the database, underscore nomenclature (snake_case), where words are separated by underscores, such as creator_idand creator_name.

The reason is: most databases are not case-sensitive, and underscore naming can improve the readability of the database.

Annotations can be used to specify the mapping relationship between entity class attributes (fields in Java) and database table columns.

 @Column(name = "creator_id") // 指定数据库列名为 creator_id
 private Long creatorId;

Tips for importing databases and tables:

1.Open mysql

2.source .sql file

Non-empty processing experience:

Optional<CustomerPo>Is a return value type in Java, where Optionalis a container object used to contain non-null objects. Using Optional<CustomerPo>as a return value means that when you call a method that returns this type, you will get an Optionalobject back. The caller can use methods such as isPresent(), isEmpty(), get(), orElse()etc. to check whether the value exists and perform corresponding operations in different situations. get()The method is to obtain the CustomerPo object in the Optional container.

cloneFactory experience:

1. Delete the @Data annotation

2. Handwritten get set method of entity class

3.@CopyFrom(CustomerPo.class)

Guess you like

Origin blog.csdn.net/RuanFun/article/details/134867216