本文由 简悦 SimpRead 转码, 原文地址 www.bilibili.com
万能的 Service 层对于很多时候,经常发现没有什么事情是 Service 解决不掉的,如果有,那就用两个 Service。
对于很多时候,经常发现没有什么事情是 Service 解决不掉的,如果有,那就用两个 Service。
他更像是导演,所有角色演员要有明确的分工,导演应该只完成场景的协调与拍摄。
每个业务功能就像是一个场景,在拍摄之前,先需要让各个角色到位,然后导演通过调度各角色的参演顺序与行为完成拍摄,每个角色都有自己的定位,而不是只是一个空壳,各个角色不能完全依靠导演来派遣调度,导演的职责是 “导”,而不是 “演”。
![][img-0]
Service 的成了 SQL 的组装类了:
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
@Service
public class UserService {
private QueryRunner queryRunner;
public UserService(DataSource dataSource) {
this.queryRunner = new QueryRunner(dataSource);
}
public List<User> getUsers(String name) {
String sql = "SELECT * FROM users WHERE name = ?";
try {
return queryRunner.query(sql, new BeanListHandler<>(User.class), name);
} catch (SQLException e) {
// Handle exceptions
return null;
}
}
public void createUser(String userName, String email) {
String sql = "INSERT INTO users (userName, email) VALUES (?, ?)";
try {
queryRunner.update(sql, userName, email);
} catch (SQLException e) {
// Handle exceptions
}
}
}
Service 对业务逻辑混乱且高度聚合
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
@Service
public class OrderService {
private QueryRunner queryRunner;
public OrderService(DataSource dataSource) {
this.queryRunner = new QueryRunner(dataSource);
}
public String placeOrder(String customerId, String productId, int quantity) {
// Validate product availability
String sql = "SELECT quantity FROM products WHERE id = ?";
try {
Product product = queryRunner.query(sql, new BeanHandler<>(Product.class), productId);
if (product.getQuantity() < quantity) {
return "Product out of stock";
}
} catch (SQLException e) {
// Handle exceptions
}
// Place the order
sql = "INSERT INTO orders (customerId, productId, quantity) VALUES (?, ?, ?)";
try {
queryRunner.update(sql, customerId, productId, quantity);
} catch (SQLException e) {
// Handle exceptions
}
// Update product quantity
sql = "UPDATE products SET quantity = quantity - ? WHERE id = ?";
try {
queryRunner.update(sql, quantity, productId);
} catch (SQLException e) {
// Handle exceptions
}
// Send notification email to customer
sendEmail(customerId, "Your order has been placed");
// Log the action
logAction("Order placed", customerId);
return "Order placed successfully";
}
private void sendEmail(String customerId, String message) {
// Code to send email
}
private void logAction(String action, String customerId) {
// Code to log the action
}
}
Serivice 将三层的职责全部做了
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
@Service
public class FileService {
public ResponseEntity<String> uploadFile(HttpServletRequest request) {
MultipartFile file = (MultipartFile) request.getAttribute("file");
// Validate the file
if (file == null || file.isEmpty()) {
return ResponseEntity.badRequest().body("Invalid file");
}
// Save the file
try {
String fileName = file.getOriginalFilename();
File dest = new File("uploads/" + fileName);
file.transferTo(dest);
} catch (IOException e) {
// Handle exception
return ResponseEntity.status(500).body("File upload failed");
}
return ResponseEntity.ok("File uploaded successfully");
}
}
有时候以 Controller 命名:
import org.springframework.stereotype.Service;
@Service
public class UserControllerService {
public void processUserRegistration(String userName, String email) {
// This method is expected to handle user registration
// However, it also sends email notifications and logs actions which are unrelated to user registration
registerUserInDatabase(userName, email);
sendEmailNotification(email, "Registration successful");
logAction("User registration", userName);
}
public void purchaseProductService(String userName, String productId) {
// This method is expected to handle purchasing a product
// However, it also updates user activity and sends email notifications which are unrelated to product purchase
purchaseProductInDatabase(userName, productId);
updateUserActivity(userName, "Purchased product");
sendEmailNotification(userName, "Purchase successful");
}
private void registerUserInDatabase(String userName, String email) {
// Registration logic
}
private void sendEmailNotification(String email, String message) {
// Send email logic
}
private void logAction(String action, String userName) {
// Logging logic
}
private void purchaseProductInDatabase(String userName, String productId) {
// Purchase product logic
}
private void updateUserActivity(String userName, String action) {
// Update user activity logic
}
}
有时候以 entity 命名
import org.springframework.stereotype.Service;
@Service
public class OrderService {
public void placeOrder(String customerId, String productId, int quantity) {
// This method is expected to handle placing an order
// However, it also verifies the user's account status and updates the product's stock quantity
if (!verifyUserAccountStatus(customerId)) {
throw new RuntimeException("User account is not active");
}
if (!checkProductAvailability(productId, quantity)) {
throw new RuntimeException("Product is not available");
}
createOrderInDatabase(customerId, productId, quantity);
updateProductStock(productId, -quantity);
}
private boolean verifyUserAccountStatus(String customerId) {
// Verify user account status logic, this should be handled in UserService
return true;
}
private boolean checkProductAvailability(String productId, int quantity) {
// Check product availability logic, this should be handled in ProductService
return true;
}
private void createOrderInDatabase(String customerId, String productId, int quantity) {
// Create order in database logic
}
private void updateProductStock(String productId, int quantityChange) {
// Update product stock logic, this should be handled in ProductService
}
}
复用性低
可维护性差
可拓展性差
单元测试难落地
一味的追求实现功能
层次的混乱
模糊的职责
char *log = "\
_oo0oo_\r\n\
o8888888o\r\n\
88\" . \"88\r\n\
(| -_- |)\r\n\
0\\ = /0\r\n\
___/`---'\\___\r\n\
.' \\\\| |// '.\r\n\
/ \\\\||| : |||// \r\n\
/ _||||| -:- |||||- \r\n\
| | \\\\\\ - /// | |\r\n\
| \\_| ''\\---/'' |_/ |\r\n\
\\ .-\\__ '-' ___/-. /\r\n\
___'. .' /--.--\\ `. .'___\r\n\
.\"\" '< `.___\\_<|>_/___.' >' \"\".\r\n\
| | : `- \\`.;`\\ _ /`;.`/ - ` : | |\r\n\
\\ \\ `_. \\_ __\\ /__ _/ .-` / /\r\n\
=====`-.____`.___ \\_____/___.-`___.-'=====\r\n\
`=---='\r\n\
\r\n\
~~~~~~~~~~~~~~~~~~~~XCMD~~~~~~~~~~~~~~~~~~~\r\n\
\xE4\xBD\x9B\xE7\xA5\x96\xE4\xBF\x9D\xE4\xBD\x91 \xE6\xB0\xB8\xE4\xB8\x8D\xE5\xAE\x95\xE6\x9C\xBA \xE6\xB0\xB8\xE6\x97\xA0\x42\x55\x47\r\n ";
求人不如求己,让我们一块开始学习架构设计吧
[img-0]:data:text/plain;base64,dW5rbm93biBwYXJhbXM6IHdlYi1hcnRpY2xlLXBpYw==