01_Spring开胃菜

embedded/2024/11/18 8:21:26/

一、 为什么是Spring?

在正式进入Spring内容前我们先看看我们以往经典的程序设计。

当我们去登录时,会调用后端的Controller,Controller接收到用户的请求后会调用业务层的Service进行登录的业务处理,Service业务处理过程中会调用Dao层向DB获取数进行判断。

接下来我们用代码来模拟实现这个逻辑

Controller中,我们需要有一个方法来接收用户发起的请求

java">public class UserController {private UserService userService = new UserServiceImpl();// 登录public void login() {String username = "admin";String password = "123456";boolean success = userService.login(username, password);System.out.println(success ? "登录成功" : "登录失败");}
}

Service中要进行用户校验的业务逻辑处理,定义Service接口以及实现类

java">public interface UserService {boolean login(String username, String password);
}
java">public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoImplForMySQL();@Overridepublic boolean login(String username, String password) {User user = userDao.findUserByUsernameAndPassword(username, password);return user != null;}
}

Dao中我们要使用用户传过来的用户名和密码去数据库查询是否存在,定义Dao接口及实现类

java">public interface UserDao {User findUserByUsernameAndPassword(String username, String password);
}
java">public class UserDaoImplMySQL implements UserDao {@Overridepublic User findUserByUsernameAndPassword(String username, String password) {// 省略具体的实现过程...return null;}
}

看上去这个模拟的实现没有什么问题,但是有一天项目组说我们现在数据从MySQL迁移到了Oracel,怎么办??你得考虑它用户数据未来还会不会迁移回来呢!

所以此时我们就会对于Dao的实现再加一个

java">// 使用Oracle数据库实现UserDao
public class UserDaoImplForOracle implements UserDao {@Overridepublic User findUserByUsernameAndPassword(String username, String password) {// 省略具体实现过程...return null;}
}

不同的数据库实现有不同的处理方式,感觉逻辑正常,但是这时我们还得要反回去修改Service的实现,让它引用的是新的Dao实现。

java">public class UserServiceImpl implements UserService {// private UserDao userDao = new UserDaoImpl();private UserDao userDao = new UserDaoImplForOracle();    @Overridepublic boolean login(String username, String password) {User user = userDao.findUserByUsernameAndPassword(username, password);return user != null;}
}

以上的这个设计好吗?实际是不好的,因为每次底层的变化都会要求上层进行代码的变更,其实这里违背软件开发中的开闭原则!

什么是开闭原则?

在软件开发过程中应对扩展开放,对修改关闭。也就是说,如果进行功能扩展时,添加额外的类是没有问题的,但是如果因为功能扩展而修改之前运行正常的程序,这时忌讳,是不被允许的。

从上图可以看出,上层是依赖下层的。UserController依赖UserServiceImpl,则UserServiceImpl依赖UserDaoImplForMySQL,这样就会导致一旦下层的改动,上层必然受到影响也需要进行改动,这也同时违背了另一个开发原则:依赖倒置原则  

什么是依赖倒置原则?

依赖倒置原则,简称DIP,主要倡导的是面向抽象编程、面向接口编程,不要面向具体编程,让上层不再依赖下层,这样的话下面改动了,上面代码也不会受到牵连。这可以大大地降低程序的耦合度,耦合度低了扩展性就强了,同时代码的复用性也会增强。

在前面


http://www.ppmy.cn/embedded/138481.html

相关文章

软考教材重点内容 信息安全工程师 第 3 章 密码学基本理论

(本章相对老版本极大的简化,所有与算法相关的计算全部删除,因此考试需要了解各个常 用算法的基本参数以及考试中可能存在的古典密码算法的计算,典型的例子是 2021 和 2022 年分别考了 DES 算法中的 S 盒计算,RSA 中的已…

c ++零基础可视化——数组

c 零基础可视化 数组 一些知识: 关于给数组赋值,一个函数为memset,其在cplusplus.com中的描述如下: void * memset ( void * ptr, int value, size_t num );Sets the first num bytes of the block of memory pointed by ptr to…

爬虫策略与反爬机制——爬虫常见策略

随着网络爬虫技术的日益发展,反爬机制也变得越来越复杂,网站和服务商不断加强对爬虫行为的监控和限制,开发者需要采取一系列有效的爬虫策略来提高爬虫的效率并规避反爬措施。本章将介绍一些常见的爬虫策略,帮助开发者应对不同情况…

POUF: Prompt-oriented unsupervised fine-tuning for large pre-trained models

Motivation 通过提示,大规模预训练模型变得更具表现力和强大,近年来引起了人们的极大关注。虽然这些大型模型具有zero-shot能力,但一般来说,仍然需要标记数据来使它们适应下游任务。为了克服这一关键限制,我们提出了一个无监督微调框架,直接对模型进行微调或对未标记的目…

python核心语法(二)

第三节 类型转换 0.布尔值转换 使⽤⼀个内置函数bool()。 # 以下值都为True bool(2) bool(-1) bool(255) bool(0.1000001) bool(-99.99888) # 下⾯的值为False bool(0) bool(0.0)对于数值类型,所有的⾮零值转换为True, 只有零值才转换为False.字符串也可以转换为…

flutter打包签名问题

总结 build.gradle只配置了release签名,没有配置debug签名的前提下 flutter build apk --debug或者flutter run 使用的都是系统下的默认签名文件 flutter build apk --release或者AS Build->Flutter->Build APK使用的是release签名 build.gradle配置了rel…

【linux】(12)进程实时信息-top

top 是一个用于显示系统任务和进程实时信息的命令行工具,在 Unix 和 Linux 系统中非常常用。 基本用法 top启动 top 命令后,默认情况下显示当前系统中所有正在运行的进程,并实时更新。您可以通过交互式键盘命令和选项来控制 top 的显示和行…

用正则表达式检查是IP否为内网地址

用正则表达式检查是ip否为内网地址 PHP function isIntranet($ip) {/* IPV4内网地址A 类10.0.0.0~10.255.255.255B 类172.16.0.0~172.31.255.255C 类192.168.0.0~192.168.255.255*/// 检查是否为 IPv4 内网地址if (preg_match(/^10\./, $ip…