Skip to content

本文由 简悦 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
    }
}
  1. 复用性低

  2. 可维护性差

  3. 可拓展性差

  4. 单元测试难落地

  5. 一味的追求实现功能

  6. 层次的混乱

  7. 模糊的职责

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==

Released under the MIT License.