spring笔记(1)|一个代码重构的例子

《Spring5核心原理与30个类手写实战》阅读笔记

目录

PART1 写在前面的废话

PART2 软件架构设计原则

PART3 一个重构代码的例子


PART1 写在前面的废话

文中例子改编简化于原文实例,初衷仅为辅助自己阅读理解,若有缘看到此文,有助则万幸,无助就下次再见。学了也学不懂但还是尝试看一下。

ps.本菜鸡的新系列《学了也学不懂》那啥,可恶啊,这次一定会坚持学下去。

PART2 软件架构设计原则

先简单理解

1、开闭原则:程序对修改关闭,对拓展开放。

2、依赖倒置原则:上层不依赖下层模块。

3、单一职责原则:一个类负责一件事。

4、接口隔离原则:接口不复杂,细化接口,方法尽量少(但不是越少越好)。

5、迪米特原则:最少知道原则,一个对象保持对一个对象最少的了解,只和自己相关的对象交流。

6、里氏替换原则:子类拓展符类功能,但不能改变父类原有功能。

7、合成服用原则:尽量使用对象组合/聚合,而不是继承关系达到软件复用

聚合:如汽车类中包含轮胎类,引擎类,聚合成一辆车

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

组合:部分共同构成整体,如鼻子眼睛等构成了脸,脸没了鼻子眼睛都没了

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

PART3 一个重构代码的例子

针对原书中对数据库操作例子的简化模拟

模拟数据库增删改操作

假设此段为平时写的代码,满足了需求但是不利于开发与维护,而且存在很多重复的代码。

@Service
public class CommonService {

    public void save(Student stu){
        //1.模拟加载数据库取动相关
        System.out.println("模拟数据库取动加载");
        //2.模拟创建数据库连接
        Map<String , Student> dataSource = new HashMap<>();
        //3.模拟保存数据
        String sql = "insert";
        System.out.println("模拟执行sql");
        dataSource.put(sql,stu);
        //4.模拟关闭数据源
        System.out.println("模拟数据源关闭");
    }

    public void delete(Student stu){
        //1.模拟加载数据库取动相关
        System.out.println("模拟数据库取动加载");
        //2.模拟创建数据库连接
        Map<String , Student> dataSource = new HashMap<>();
        //3.模拟删除数据
        String sql = "delete";
        System.out.println("模拟执行sql");
        dataSource.put(sql,stu);
        //4.模拟关闭数据源
        System.out.println("模拟数据源关闭");
    }

    public void update(Student stu){
        //1.模拟加载数据库取动相关
        System.out.println("模拟数据库取动加载");
        //2.模拟创建数据库连接
        Map<String , Student> dataSource = new HashMap<>();
        //3.模拟更新数据
        String sql = "update";
        System.out.println("模拟执行sql");
        dataSource.put(sql,stu);
        //4.模拟关闭数据源
        System.out.println("模拟数据源关闭");
    }
}

2.上述代码重复较多,进行重复代码提取,将重复的代码放入工具类DataUtils 中,实现类CommonService2可直接调用工具类中的方法。

//工具类
public class DataUtils {
    private DataUtils(){}
    static {
        //1.模拟加载数据库取动相关
        System.out.println("模拟数据库取动加载");
    }

    public static Map<String , Student> getDataSource(){
        //2.模拟创建数据库连接
        Map<String , Student> dataSource = new HashMap<>();
        return dataSource;
    }

    public static void close(){
        //模拟关闭数据源
        System.out.println("模拟数据源关闭");
    }

}

//实现类
@Service
public class CommonService2 {
     public void save(Student stu){
        //模拟加载数据库取动相关
        Map<String , Student> dataSource = DataUtils.getConnection();
        //模拟保存数据
        String sql = "insert";
        System.out.println("模拟执行sql");
        dataSource.put(sql,stu);
        //模拟关闭数据源
        DataUtils.close();
    }

    public void delete(Student stu){
        //模拟加载数据库取动相关
        Map<String , Student> dataSource = DataUtils.getConnection();
        //模拟删除数据
        String sql = "delete";
        System.out.println("模拟执行sql");
        dataSource.put(sql,stu);
        //模拟关闭数据源
        DataUtils.close();
    }

    public void update(Student stu){
        //模拟加载数据库取动相关
        Map<String , Student> dataSource = DataUtils.getConnection();
        //模拟更新数据
        String sql = "update";
        System.out.println("模拟执行sql");
        dataSource.put(sql,stu);
        //模拟关闭数据源
        DataUtils.close();
    }
}

4.第一阶段完成,但是实现类中仍然存在重复的代码,上个实现类CommonService2 中,除了模拟的需要执行的sql不同,其他对数据库相关的模拟操作都是相同的,故将对数据库相关的一些操作进行抽取,放入模板类中DataTemplate ,实现类直接调用对应的方法进行对数据库的操作。

public class DataTemplate {
    //对数据库操作统一处理
    public static List<Student> update(String sql, Student stu){
        List<Student> list = new ArrayList<>();
        //1.模拟加载数据库取动相关
        System.out.println("模拟数据库取动加载");
        //2.模拟创建数据库连接
        Map<String , Student> dataSource = new HashMap<>();
        //3.模拟sql执行
        String sqlStatement = sql;
        System.out.println(sqlStatement);
        //假设此步为执行sql方法
        dataSource.put(sql,stu);
        //模拟关闭数据源
        System.out.println("模拟数据源关闭");
        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.到此阶段,重复的代码基本处理好了,虽然做好了封装,但是此时只能处理student类,而不能处理其他类,并且实际情况中,不同类的类字段不同,结果集也不同,所以具体的类不应该出现在模板中,考虑将模板改造成通用的,不同类的处理交给对应DAO来处理,创建IDataMapper接口用于处理结果集。

public interface IDataMapper {
    //结果处理
    List dataMapper(Student stu);
}

public class StudentMapper implements IDataMapper {
    @Override
    public List dataMapper(Student stu) {
        //模拟处理student类型的结果
        List<Student> list = new ArrayList<>();
        list.add(stu);
        return list;
    }
}

public class DataTemplate {
    //对数据库操作统一处理
    public static List<Student> update2(String sql, IDataMapper mapper, Student stu){
        List<Student> list = new ArrayList<>();
        //1.模拟加载数据库取动相关
        System.out.println("模拟数据库取动加载");
        //2.模拟创建数据库连接
        Map<String , Student> dataSource = new HashMap<>();
        //3.模拟sql执行
        String sqlStatement = sql;
        System.out.println(sqlStatement);
        //假设此步为执行sql方法
        dataSource.put(sql,stu);
        //模拟关闭数据源
        System.out.println("模拟数据源关闭");
        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.再继续修改相关类型为泛型,从而实现可以对不同的类进行查询

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 { 

    //获取学生数据
    public List<Student> get(Student stu){
        String sql = "select";
        return DataTemplate.update2(sql,new StudentMapper(),stu);
    }

    //获取老师数据
    public List<Teacher> get(Teacher teacher){
        String sql = "select";
        return DataTemplate.update2(sql,new TeacherMapper(),teacher);
    }
}

到此重构完成。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值