首页 新闻 会员 周边

一个关于java编程规范的问题

0
悬赏园豆:10 [已解决问题] 解决于 2023-05-24 09:07

各位前辈,我有一个疑惑,一直以来我都觉得只有controller返回Result对象是很合适的,但是对于一个service它返回实体类的对象同时如果我现在有一个判断需要返回给controller一个string字符串,或者有时候我直接返回一个null给controller,我还要在controller层去进行判断本次请求是success还是error,这样就反而麻烦了,倒不如我直接在service层直接返回result给controller,然后由controller返回给前端。但是我的老师它义正言辞的告诉我result只能在controller返回,就搞得我有点迷惑,希望各位前辈帮我答疑解惑。

*三井寿*的主页 *三井寿* | 初学一级 | 园豆:35
提问于:2023-05-23 00:40
< >
分享
最佳答案
0

既然是一个规范问题。呢这么做的目的就是为了解耦。controller为前端控制层,service为服务层。如果service层返回了前端需要的数据,实际上是在耦合,controller层和service层的职责重合。如果突然要换一种返回的类型,你就要改变service层和controller层的代码。
还有一个小问题:“我还要在controller层去进行判断本次请求是success还是error”。虽然不知道你的需求,但我很少在controller层去判断service是否成功。如果逻辑失败service可以抛出异常由controller去处理,而不是返回失败

收获园豆:10
mowen285 | 小虾三级 |园豆:660 | 2023-05-23 09:38

public Shop queryById(Long id) throws JsonProcessingException {
/**
* 1.从redis中查询缓存
* 2.命中的话直接返回shop
* 2.1 未命中
* 2.1.1 在数据库中查找
* 2.1.2 命中的话
* 2.1.2.1 返回shop
* 2.1.2.2 写入redis,用id做key,shop为value
* 2.1.3 未命中的话
* 缓存中存入空串
*/
ValueOperations<String, String> str = stringRedisTemplate.opsForValue();
//这是shop的键值对集合比较容易转为对象
String shopKey = CACHE_SHOP_KEY + id;
//如果命中
if (stringRedisTemplate.hasKey(shopKey)) {
String shopJson = str.get(shopKey);
if (shopJson == null){
return null; //这里其实应该返回字符串
}
return JSONUtil.toBean(shopJson,Shop.class);
}
//未命中,去mysql找
Shop shop = getById(id);
//使用空值缓存解决缓存穿透
if (shop == null){
str.set(shopKey,"",Duration.ofMinutes(5));
return null;
}
//存入redis
str.set(shopKey, JSONUtil.toJsonStr(shop), Duration.ofMinutes(30));
//返回
return shop;

}

我懂您的意思,是用自定义异常然后在全局异常处理那里去解决这种问题吗,我觉得您的这种思路很对,我的需求就是上面这段代码,我又要返回null,又要返回shop,还想返回字符串,如果可以直接在这里面用result包装一下的话,就方便很多,主要是我看的网课的视频它是在service返回result,我就觉得不太好,然后问了我们老师,老师说只有controller能返回result。

*三井寿* | 园豆:35 (初学一级) | 2023-05-23 10:56
其他回答(3)
0

涉及到 架构设计 方面的东西了。
去了解下 MDD、DDD 吧
说服你的老师,走上超越、成为架构师之路。

快乐的凡人721 | 园豆:3918 (老鸟四级) | 2023-05-23 09:12
0

controller层去进行判断本次请求是success还是error? 不就是在control中判断是返回code 200 还是返回其它的code吗?
我的理解:controller层的逻辑方法非常简单,所有处理在service处理,然后再在controller层做简要逻辑处理

人间春风意 | 园豆:2335 (老鸟四级) | 2023-05-23 10:45

public Shop queryById(Long id) throws JsonProcessingException {
/**
* 1.从redis中查询缓存
* 2.命中的话直接返回shop
* 2.1 未命中
* 2.1.1 在数据库中查找
* 2.1.2 命中的话
* 2.1.2.1 返回shop
* 2.1.2.2 写入redis,用id做key,shop为value
* 2.1.3 未命中的话
* 缓存中存入空串
*/
ValueOperations<String, String> str = stringRedisTemplate.opsForValue();
//这是shop的键值对集合比较容易转为对象
String shopKey = CACHE_SHOP_KEY + id;
//如果命中
if (stringRedisTemplate.hasKey(shopKey)) {
String shopJson = str.get(shopKey);
if (shopJson == null){
return null;
}
return JSONUtil.toBean(shopJson,Shop.class);
}
//未命中,去mysql找
Shop shop = getById(id);
//使用空值缓存解决缓存穿透
if (shop == null){
str.set(shopKey,"",Duration.ofMinutes(5));
return null;
}
//存入redis
str.set(shopKey, JSONUtil.toJsonStr(shop), Duration.ofMinutes(30));
//返回
return shop;
}
您好 我的需求就是昨天写上面这部分代码的时候,然后有了这个问题。
目前我看了大家的评论后我的理解就是service层不能返回Result,然后controller做逻辑判断,然后我看了上面那个兄弟的评论,我觉得他说的挺对的,就是把这种空值情况直接抛出在全局异常处理那部分解决。
您看我理解的对不对。

支持(0) 反对(0) *三井寿* | 园豆:35 (初学一级) | 2023-05-23 11:07
0

在Java编程中,关于将何种类型的对象返回给控制器(Controller)以及处理结果的方式,并没有一个固定的规范。最佳实践通常会因项目需求、团队约定和个人偏好而有所不同。以下是一些常见的实践方式,供你参考:

返回实体类对象:这是最常见的做法,服务层(Service)返回实体类对象,控制器(Controller)根据实体类对象进行进一步的处理和响应。这种方式可以将业务逻辑与控制器解耦,使服务层专注于业务处理。

返回自定义结果对象:有时候,服务层可能需要返回更多的信息给控制器,此时可以定义一个自定义的结果对象,包含响应状态、消息、数据等字段。服务层返回该结果对象,控制器根据结果对象进行处理。这种方式可以提供更灵活的响应信息,并减少控制器层的判断逻辑。

返回字符串或枚举类型:如果某些场景下,服务层只需要返回一个简单的消息或状态标识,可以直接返回字符串或者使用枚举类型表示不同的状态。控制器根据返回值进行相应的判断和处理。这种方式简单直接,适用于简单的场景。

总体而言,控制器(Controller)负责接收请求、调用服务层处理业务,并根据实际情况选择适合的方式将结果返回给前端。如果你认为在服务层直接返回Result对象更方便,可以与团队成员或者老师进行进一步讨论,理清项目的设计思路和约定,以便做出统一的决策。

在实际开发中,团队间的规范和约定非常重要,因此最好与团队一起讨论并制定适合自己团队的最佳实践。这样可以确保整个项目的代码风格一致,并提高代码的可读性和维护性。

Technologyforgood | 园豆:5633 (大侠五级) | 2023-05-23 21:52
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册