面试题答案
一键面试1. 接口与抽象类在各层的作用
表现层(Presentation Layer)
- 接口:用于定义视图(View)与控制器(Controller)之间的交互协议。例如,在MVC架构中,视图可能需要向控制器发送用户交互事件,通过定义接口可以规范这种交互方式,使得不同的视图实现类都能以统一的方式与控制器进行协作。如定义一个
UserInteractionListener
接口,视图类实现该接口来处理用户点击按钮等操作。 - 抽象类:较少直接在表现层使用,但可以作为视图组件的基类,定义一些通用的属性和行为,如视图的初始化方法、基本的绘制方法等,为具体的视图类提供一个通用的基础框架。
业务逻辑层(Business Logic Layer)
- 接口:是业务逻辑层与其他层解耦的关键。定义业务接口,使得表现层可以通过接口调用业务逻辑,而不依赖具体的业务实现类。例如,定义一个
UserService
接口,包含registerUser(User user)
、loginUser(String username, String password)
等方法,业务逻辑层的实现类实现该接口,这样表现层只需调用接口方法,无需关心具体实现细节,实现了层与层之间的解耦。 - 抽象类:可以用于抽取业务逻辑实现类中的公共部分,例如一些通用的业务验证逻辑、数据预处理逻辑等可以放在抽象类中。具体的业务实现类继承抽象类,既复用了公共逻辑,又可以根据自身需求实现特定的业务方法。比如定义一个
BaseService
抽象类,包含validateUserInput(User user)
等通用验证方法,UserService
的具体实现类继承BaseService
。
数据访问层(Data Access Layer)
- 接口:定义数据访问的标准操作,如数据库的增删改查操作。例如,定义
UserDao
接口,包含saveUser(User user)
、findUserById(int id)
等方法,数据访问层的不同实现类(如基于JDBC、Hibernate、MyBatis等)实现该接口,这样业务逻辑层可以通过接口调用数据访问方法,而不依赖于具体的数据访问技术。 - 抽象类:可以作为数据访问实现类的基类,封装一些通用的数据访问操作,如数据库连接的获取与释放等。具体的数据访问类继承抽象类,实现特定的数据访问逻辑。比如定义
BaseDao
抽象类,包含获取数据库连接的getConnection()
方法,UserDao
的实现类继承BaseDao
。
2. 实现解耦和协作的方式及举例
解耦
- 接口:通过面向接口编程,上层依赖接口而非具体实现类,使得底层实现的变更不会影响到上层。例如,在业务逻辑层使用
UserService
接口,当数据访问层从使用JDBC切换到MyBatis时,只需让新的UserDao
实现类实现UserDao
接口,业务逻辑层调用UserService
接口的代码无需改变。 - 抽象类:抽象类将通用逻辑提取出来,使得具体实现类只关注自身特有的逻辑,降低了代码的耦合度。例如,
BaseService
抽象类将通用验证逻辑提取出来,UserService
实现类只需关注用户相关的业务逻辑,无需重复编写验证代码。
协作
- 接口:不同层通过实现相同的接口进行协作。例如,表现层的视图类实现
UserInteractionListener
接口,控制器类通过该接口接收视图传来的用户交互事件,实现了表现层内部的协作。在不同层之间,业务逻辑层实现UserService
接口,表现层通过调用UserService
接口方法来调用业务逻辑,实现了表现层与业务逻辑层的协作。 - 抽象类:通过继承关系实现协作。具体实现类继承抽象类,复用抽象类的方法,同时也可以扩展抽象类的功能。例如,
UserDao
实现类继承BaseDao
,复用BaseDao
中获取数据库连接的方法,同时实现自己的增删改查方法,实现了数据访问层内部的协作。