spring notes learned but not understood

Keywords: Java Spring Back-end UML

Reading notes on the core principles of spring 5 and handwriting practice of 30 classes

catalogue

PART1 is written in front of the nonsense

PART2 software architecture design principles

PART3 is an example of refactoring code

PART1 is written in front of the nonsense

The example in the article is adapted and simplified to the original example. The original intention is only to assist yourself in reading and understanding. If you are lucky to see this article, it will help. If you are helpless, see you next time. I can't understand it, but I still try to see it.

ps. the new series of chicken with this dish "I can't understand after learning". Damn it, I'll stick to it this time.

PART2 software architecture design principles

First, simply understand

1. Opening and closing principle: the program is closed to modification and open to expansion.

2. Dependency Inversion Principle: the upper layer does not depend on the lower module.

3. Single responsibility principle: one class is responsible for one thing.

4. Interface isolation principle: the interface is not complex, the interface is refined, and the methods are as few as possible (but the less the better).

5. Dimitri's principle: the principle of least knowledge. An object keeps the least understanding of an object and communicates only with its own related objects.

6. Richter's substitution principle: the subclass expands the function of the symbol class, but cannot change the original function of the parent class.

7. Composition principle: try to use object composition / aggregation instead of inheritance relationship to achieve software reuse

Aggregation: for example, the automobile category includes tires and engines, which are aggregated into one vehicle

public class Car
{
    private Engine engine;
    private Wheel wheel;
    
    public Car(Engine engine, Wheel wheel)
    {
        this.engine = engine;
        this.wheel = wheel;
    }       
}

Combination: some parts together form a whole, such as nose and eyes, which form the face. Without the face, the nose and eyes are gone

public class Face
{
    private Eyes eyes;
    private Nose nose;
    public Face()
    {
        eyes = new Eyes();
        nose = new Nose();
    }
}

PART3 is an example of refactoring code

Simplified simulation of database operation examples in the original book

Simulate database addition, deletion and modification

It is assumed that this section is the code written at ordinary times, which meets the requirements, but is not conducive to development and maintenance, and there are many duplicate codes.

@Service
public class CommonService {

    public void save(Student stu){
        //1. Simulation loading database fetching
        System.out.println("Simulate database fetching and loading");
        //2. Simulate creating database connection
        Map<String , Student> dataSource = new HashMap<>();
        //3. Save simulation data
        String sql = "insert";
        System.out.println("Simulated execution sql");
        dataSource.put(sql,stu);
        //4. Simulate closing the data source
        System.out.println("Analog data source shutdown");
    }

    public void delete(Student stu){
        //1. Simulation loading database fetching
        System.out.println("Simulate database fetching and loading");
        //2. Simulate creating database connection
        Map<String , Student> dataSource = new HashMap<>();
        //3. Simulate deletion of data
        String sql = "delete";
        System.out.println("Simulated execution sql");
        dataSource.put(sql,stu);
        //4. Simulate closing the data source
        System.out.println("Analog data source shutdown");
    }

    public void update(Student stu){
        //1. Simulation loading database fetching
        System.out.println("Simulate database fetching and loading");
        //2. Simulate creating database connection
        Map<String , Student> dataSource = new HashMap<>();
        //3. Simulation update data
        String sql = "update";
        System.out.println("Simulated execution sql");
        dataSource.put(sql,stu);
        //4. Simulate closing the data source
        System.out.println("Analog data source shutdown");
    }
}

2. The above codes are repeated frequently. Extract the repeated codes and put the repeated codes into the tool class DataUtils   In, the implementation class CommonService2 can directly call the methods in the tool class.

//Tool class
public class DataUtils {
    private DataUtils(){}
    static {
        //1. Simulation loading database fetching
        System.out.println("Simulate database fetching and loading");
    }

    public static Map<String , Student> getDataSource(){
        //2. Simulate creating database connection
        Map<String , Student> dataSource = new HashMap<>();
        return dataSource;
    }

    public static void close(){
        //Analog shutdown data source
        System.out.println("Analog data source shutdown");
    }

}

//Implementation class
@Service
public class CommonService2 {
     public void save(Student stu){
        //Simulation loading database fetching related
        Map<String , Student> dataSource = DataUtils.getConnection();
        //Simulation save data
        String sql = "insert";
        System.out.println("Simulated execution sql");
        dataSource.put(sql,stu);
        //Analog shutdown data source
        DataUtils.close();
    }

    public void delete(Student stu){
        //Simulation loading database fetching related
        Map<String , Student> dataSource = DataUtils.getConnection();
        //Simulate deletion of data
        String sql = "delete";
        System.out.println("Simulated execution sql");
        dataSource.put(sql,stu);
        //Analog shutdown data source
        DataUtils.close();
    }

    public void update(Student stu){
        //Simulation loading database fetching related
        Map<String , Student> dataSource = DataUtils.getConnection();
        //Simulation update data
        String sql = "update";
        System.out.println("Simulated execution sql");
        dataSource.put(sql,stu);
        //Analog shutdown data source
        DataUtils.close();
    }
}

4. The first stage is completed, but there are still duplicate codes in the implementation class. In the previous implementation class CommonService2, except for the sql to be executed for simulation, other simulation operations related to the database are the same. Therefore, some operations related to the database will be extracted and put into DataTemplate in the template class, The implementation class directly calls the corresponding method to operate the database.

public class DataTemplate {
    //Unified processing of database operations
    public static List<Student> update(String sql, Student stu){
        List<Student> list = new ArrayList<>();
        //1. Simulation loading database fetching
        System.out.println("Simulate database fetching and loading");
        //2. Simulate creating database connection
        Map<String , Student> dataSource = new HashMap<>();
        //3. Simulate sql execution
        String sqlStatement = sql;
        System.out.println(sqlStatement);
        //Suppose this step is to execute the sql method
        dataSource.put(sql,stu);
        //Analog shutdown data source
        System.out.println("Analog data source shutdown");
        list.add(stu);
        return list;
    }
}

@Service
public class CommonService3 {

    public void save(Student stu){
        String sql = "insert";
        DataTemplate.update(sql,stu);
    }

    public void delete(Student stu){
        String sql = "delete";
        DataTemplate.update(sql,stu);
    }

    public void update(Student stu){
        String sql = "update";
        DataTemplate.update(sql,stu);
    }
}

5. At this stage, the repeated code is basically handled. Although it is encapsulated, at this time, only student classes can be processed, not other classes. In fact, the class fields of different classes are different, and the result sets are also different. Therefore, specific classes should not appear in the template. Consider transforming the template into a general one, and handing over the processing of different classes to the corresponding DAO, Create the IDataMapper interface to process the result set.

public interface IDataMapper {
    //Result processing
    List dataMapper(Student stu);
}

public class StudentMapper implements IDataMapper {
    @Override
    public List dataMapper(Student stu) {
        //Simulate the results of processing student types
        List<Student> list = new ArrayList<>();
        list.add(stu);
        return list;
    }
}

public class DataTemplate {
    //Unified processing of database operations
    public static List<Student> update2(String sql, IDataMapper mapper, Student stu){
        List<Student> list = new ArrayList<>();
        //1. Simulation loading database fetching
        System.out.println("Simulate database fetching and loading");
        //2. Simulate creating database connection
        Map<String , Student> dataSource = new HashMap<>();
        //3. Simulate sql execution
        String sqlStatement = sql;
        System.out.println(sqlStatement);
        //Suppose this step is to execute the sql method
        dataSource.put(sql,stu);
        //Analog shutdown data source
        System.out.println("Analog data source shutdown");
        return mapper.dataMapper(stu);
    }
}

@Service
public class CommonService4 {
    public List<Student> get(Student stu){
        String sql = "select";
        return DataTemplate.update2(sql,new StudentMapper(),stu);
    }
}

6. Continue to modify the relevant type to generic, so that different classes can be queried

public class Teacher {
    private String id;
    private String course;
}

public class TeacherMapper implements IDataMapper<Teacher> {
    @Override
    public List<Teacher> dataMapper(Teacher teacher) {
        List<Teacher> list = new ArrayList<>();
        list.add(teacher);
        return list;
    }
}

@Service
public class CommonService5 { 

    //Get student data
    public List<Student> get(Student stu){
        String sql = "select";
        return DataTemplate.update2(sql,new StudentMapper(),stu);
    }

    //Get teacher data
    public List<Teacher> get(Teacher teacher){
        String sql = "select";
        return DataTemplate.update2(sql,new TeacherMapper(),teacher);
    }
}

This completes the refactoring.

Posted by netrepsa on Fri, 29 Oct 2021 03:26:52 -0700