项目初期:架构师不要炫技,3大设计原则你不懂

架构师避免过度设计的关键在于理解真实业务需求,采用迭代和敏捷开发方法,专注于核心功能实现。通过遵循SOLID和GRASP原则、适度使用设计模式、保持设计简洁(KISS原则)、避免过早优化,以及进行持续的代码重构,架构师可以确保系统的灵活性和可维护性。同时,建立快速反馈循环、管理技术债务、进行风险评估和原型验证,都是确保设计适度且实用的重要策略。

肖哥弹架构 跟大家"弹弹" 代码设计技巧,需要代码关注

欢迎 点赞,点赞,点赞。

关注公号Solomon肖哥弹架构获取更多精彩内容

历史热点文章

KISS原则(Keep It Simple, Stupid)

1. KISS原则设计图:

KISS原则因为它是一种设计哲学而非具体的设计模式。不过可以用以下简化的类图来说明遵循KISS原则的设计理念:

2. KISS原则解决什么:

KISS原则解决了过度设计的问题,帮助开发者避免创建过于复杂、难以理解和维护的系统。

3. KISS原则特点:

  • 简洁性:代码和设计应该尽可能简单。
  • 易于理解:新团队成员应该能够快速理解代码。
  • 易于维护:简单的设计更容易维护和扩展。

4. KISS原则案例

4.1 简化的电子邮件发送功能案例

考虑一个需要发送电子邮件的功能,重构前可能包含复杂的配置和多个类。

重构前:

java 复制代码
public class EmailService {
    private MailServerConfig config;
    
    public EmailService(MailServerConfig config) {
        this.config = config;
    }

    public void sendEmail(Email email) {
        // 复杂的邮件发送逻辑
    }
}

public class MailServerConfig {
    // 复杂的配置选项
}

重构后:

java 复制代码
    public class EmailService {
        // 私有属性,用于存储邮件服务器配置
        private String host;
        private int port;
        private String username;
        private String password;

        // 构造器,用于初始化邮件服务器配置
        public EmailService(String host, int port, String username, String password) {
            this.host = host;
            this.port = port;
            this.username = username;
            this.password = password;
        }

        // 发送邮件的方法,参数包括收件人、主题和邮件正文
        public boolean sendEmail(String to, String subject, String body) {
            try {
                // 邮件发送逻辑(使用Java Mail API)
                MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
                message.setFrom(new InternetAddress(username));
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
                message.setSubject(subject);
                message.setText(body);

                // 实际的邮件发送代码会在这里
                System.out.println("Sending email to " + to);

                // 邮件发送成功
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    }
    
    public class Client {
    public static void main(String[] args) {
        // 创建邮件服务实例
        EmailService emailService = new EmailService("smtp.example.com", 587, "user@example.com", "password");

        // 使用邮件服务发送邮件
        boolean success = emailService.sendEmail("recipient@example.com", "Test Subject", "This is a test email body.");
        if (success) {
            System.out.println("Email sent successfully!");
        } else {
            System.out.println("Email sending failed.");
        }
    }
}

YAGNI(You Aren't Gonna Need It)原则

1. YAGNI原则设计图:

YAGNI原则鼓励开发者专注于当前的需求,避免浪费时间和资源在可能永远不会用到的特性上。这种哲学有助于保持项目的敏捷性和灵活性。

2. YAGNI原则解决什么:

YAGNI原则解决了过度设计和过早优化的问题,这些问题可能会导致项目延期、成本超支以及功能膨胀。

3. YAGNI原则特点:

  • 专注需求:只实现当前明确需要的功能。
  • 避免预测:不基于对未来的预测进行设计和开发。
  • 提高效率:通过减少不必要的工作提高开发效率。

4. YAGNI原则案例

4.1 避免过度设计的订单管理系统

考虑一个订单管理系统,初期需求仅包括基本的订单处理流程。

实现前:

java 复制代码
public class OrderManagementSystem {
    public void placeOrder(Order order) {
        // 高度复杂的订单放置逻辑
    }
    
    public void processPayment(Order order) {
        // 高度复杂的支付处理逻辑
    }
    
    // 可能永远不会用到的额外功能
    public void configureAdvancedOrderSettings(Order order) {
        // ...
    }
    
    public void manageInventoryLevels(Order order) {
        // ...
    }
}

实现后:

java 复制代码
public class OrderManagementSystem {
    public boolean placeOrder(Order order) {
        // 核心订单放置逻辑
        return true;
    }
    
    public boolean processPayment(Order order) {
        // 核心支付处理逻辑
        return true;
    }
    
    // 额外功能被移除,直到需求明确
}

public class Order {
    private String orderDetails;
    
    // 订单相关的其他属性和方法
}

DRY(Don't Repeat Yourself)原则

警告: 避免代码重复,但也要注意不要过早优化。

4. DRY原则案例

一个电子商务平台中,我们有两个不同的服务类 OrderServiceUserService,它们都需要向客户发送通知。

重构前:

java 复制代码
public class OrderService {
    public void placeOrder(Order order) {
        // 订单处理逻辑
        sendNotificationToCustomer(order.getCustomer());
    }

    private void sendNotificationToCustomer(Customer customer) {
        // 发送通知逻辑
    }
}

public class UserService {
    public void updateProfile(User user) {
        // 用户资料更新逻辑
        sendNotificationToCustomer(user);
    }

    private void sendNotificationToCustomer(User user) {
        // 发送通知逻辑
    }
}

在上述代码中,OrderServiceUserService 都包含一个私有方法 sendNotificationToCustomer,这导致了代码重复。

避免代码重复:

我们可以创建一个通用的服务类来处理通知发送,避免在每个服务中重复相同的逻辑。

java 复制代码
public class NotificationService {
    public void sendNotification(Customer customer) {
        // 发送通知逻辑
    }
}

然后,我们更新 OrderServiceUserService 以使用 NotificationService

java 复制代码
public class OrderService {
    private NotificationService notificationService;

    public OrderService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }

    public void placeOrder(Order order) {
        // 订单处理逻辑
        notificationService.sendNotification(order.getCustomer());
    }
}

public class UserService {
    private NotificationService notificationService;

    public UserService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }

    public void updateProfile(User user) {
        // 用户资料更新逻辑
        notificationService.sendNotification(user);
    }
}

避免过早优化:

在上述重构中,我们避免了过早优化,因为我们没有对 NotificationService 进行任何假设或为未来可能的需求做出设计。例如,我们没有:

  • 为不同类型的通知创建复杂的接口或抽象类。
  • 实现多种通知方式(如电子邮件、短信、应用推送)而当前只需要电子邮件。
  • 添加额外的配置选项或依赖注入,除非它们是立即需要的。

通过这种方式,我们简化了设计,消除了重复代码,并保持了系统的灵活性,以便在未来根据实际需求进行扩展。

其他设计注意点:

  1. 理解业务需求
    • 深入理解业务目标和需求,确保设计满足实际业务场景。
  2. 采用迭代开发
    • 通过敏捷开发方法,分阶段迭代地开发和交付软件。
  3. 关注核心功能
    • 专注于实现系统的核心功能,避免在非核心特性上花费过多时间。
  4. 应用DRY原则
    • 避免代码重复,但同时避免过早优化。
  5. 设计模式的谨慎使用
    • 只在确实需要时才使用设计模式,避免过度应用。
  6. 避免过度抽象
    • 避免创建过多的抽象层,这可能会增加系统的复杂性。
  7. 接口设计
    • 设计小而具体的接口,避免创建过于宽泛的接口。
  8. 依赖管理
    • 确保高层模块不依赖低层模块,而是依赖于抽象。
  9. 技术债务意识
    • 识别和管理技术债务,避免过度设计导致的债务积累。
  10. 持续重构
    • 定期审查和重构代码,以提高代码质量和可维护性。
  11. 性能优化的适度关注
    • 在不影响系统稳定性和可维护性的前提下进行性能优化。
  12. 风险评估
    • 评估设计决策的潜在风险,避免过度设计可能带来的风险。
  13. 技术选型
    • 选择成熟、稳定并且广泛支持的技术,避免采用未经验证的新技术。
相关推荐
张极是大帅哥几秒前
cpu的架构指什么
stm32·嵌入式硬件·架构
工业甲酰苯胺8 分钟前
Springboot中自定义监听器
java·spring boot·spring
1.01^100027 分钟前
第15-05章:获取运行时类的完整结构
java
jingling55528 分钟前
后端开发刷题 | 兑换零钱(动态规划)
java·开发语言·数据结构·算法·动态规划
一粟1021 小时前
Spring Boot:现代化Java应用开发的艺术
java·spring boot·后端
码农小伙1 小时前
Spring-bean的生命周期-尾篇
java·后端·spring
sanzk1 小时前
sql格式化工具
java·数据库·sql
IT研究室1 小时前
计算机毕业设计选题推荐-校园车辆管理系统-Java/Python项目实战(亮点:数据可视化分析、账号锁定)
java·spring boot·python·django·毕业设计·源码·课程设计
Marchwho1 小时前
面试—MySQL
java·数据库·mysql
MinIO官方账号1 小时前
对象存储上的数据库--新常态
大数据·数据库·hadoop·分布式·架构·kafka