当前位置: 首页> 健康> 美食 > 动漫设计培训机构哪里好_下载手机商城app_站长工具网_站内推广方案

动漫设计培训机构哪里好_下载手机商城app_站长工具网_站内推广方案

时间:2025/7/19 22:58:13来源:https://blog.csdn.net/qq_36894378/article/details/147230849 浏览次数:0次
动漫设计培训机构哪里好_下载手机商城app_站长工具网_站内推广方案

前言

关于设计原则SOLID具体指的是什么,怎么理解这些设计原则,我觉得有必要记录一笔,毕竟这个设计原则确实经常在关键技术文档中提及,在编程思想中提及,在日常的开发中使用,但是对我来说,似乎知道但又不那么明确,我希望自己对设计原则的思想有一个更加准确和全面的理解,也想明确如果没有这个设计原则会如何?此设计原则的亮点和优势是什么?我在日常开发中怎么使用到这些设计原则的?
本文就是基于以上问题的总结归纳,方便自己日后复盘。
说明:汇总风格和内容借助AI工具

一、什么是SOLID?

SOLID是面向对象编程和软件设计的五个基本原则的首字母缩写,这些原则帮助我们编写更易于维护、扩展和理解的代码。

  1. S - 单一职责原则 (Single Responsibility Principle)
  2. O - 开闭原则 (Open/Closed Principle)
  3. L - 里氏替换原则 (Liskov Substitution Principle)
  4. I - 接口隔离原则 (Interface Segregation Principle)
  5. D - 依赖倒置原则 (Dependency Inversion Principle)

1. 单一职责原则(SRP)

  • 核心:一个类应该只有一个引起它变化的原因(即只有一个职责)。
  • 关键点
    • 方法层面:一个方法只做一件事(如saveStudent()不应同时包含验证和存储逻辑)。
    • 类层面:Student类管理学生属性,若需日志记录,应拆分出StudentLogger类。
  • 优势:降低复杂度、提高可维护性,修改一个功能时不会意外影响其他功能。
  • 现实类比:就像餐厅里厨师负责烹饪,服务员负责上菜,收银员负责结账,各司其职,而不是一个人做所有事情。

日常开发中的问题:忽视SRP会导致"上帝类"(God Class),修改一处可能影响多处功能,测试困难,代码难以复用。

  • 反例:
    class Student {void saveToDatabase() { /* 数据库操作 */ }void generateReport() { /* 生成PDF */ } // 违反SRP
    }
    

2. 开闭原则(OCP)

  • 核心:通过扩展(继承/组合)添加新功能,而非修改已有代码。
  • 关键点
    • 多态是手段之一,但OCP更强调抽象(接口/抽象类)的设计。
    • 示例:支付系统支持新支付方式时,应实现Payment接口,而非修改原有代码。
    interface Payment { void pay(); }
    class CreditCard implements Payment { /* 无需修改现有类 */ }
    
  • 优势:减少回归测试风险,提高系统可扩展性。
  • 现实类比:USB接口设计 - 你可以插入各种设备(扩展开放),而不需要修改电脑的USB接口本身(修改关闭)。

日常开发中的问题:忽视OCP会导致每次需求变更都要修改核心类,增加回归测试负担,引入新bug的风险高。

  • 反例:
class Shape {private String type;public double calculateArea() {if (type.equals("circle")) {// 计算圆形面积} else if (type.equals("rectangle")) {// 计算矩形面积}// 每添加一个新形状都要修改这个方法}
}

3. 里氏替换原则(LSP)

  • 核心:子类必须能够替换父类而不破坏程序逻辑(行为一致性)。
  • 关键点:
    • 子类可扩展父类功能,但不能改变父类的契约(如输入/输出约束)。
  • 优势:保证继承体系的健壮性,避免运行时意外错误。
  • 现实类比:正方形是长方形的特例,但如果长方形有设置不同长宽的方法,正方形继承长方形就会有问题,因为正方形长宽必须相同。

日常开发中的问题:忽视LSP会导致在使用多态时出现意外行为,子类无法真正替代父类,增加了代码的脆弱性。

  • 反例:
    父类Birdfly()方法,子类Penguin重写为空方法——违反LSP。
class Bird {public void fly() {System.out.println("Flying");}
}class Ostrich extends Bird {@Overridepublic void fly() {throw new UnsupportedOperationException("鸵鸟不会飞!");}
}public class Main {public static void makeBirdFly(Bird bird) {bird.fly();  // 对于鸵鸟,这会抛出异常}
}

4. 接口隔离原则(ISP)

  • 核心:客户端不应被迫依赖它不需要的接口方法。
  • 关键点
    • 将庞大接口拆分为更小、更具体的接口(如PrinterScanner分开,而非合并为MultiFunctionDevice)。
    • 示例:
      interface Printable { void print(); }
      interface Scannable { void scan(); }
      class SimplePrinter implements Printable { ... } // 无需实现scan()
      
  • 优势:减少接口污染,降低依赖耦合。
  • 现实类比:多功能工具 vs 专用工具 ,你不会用瑞士军刀上的剪刀功能来剪头发(虽然可以,但不合适)。

日常开发中的问题:忽视ISP会导致"胖接口",实现类被迫提供空实现或抛出异常,接口变得难以理解和维护。

  • 反例:
interface Worker {void work();void eat();void sleep();
}class HumanWorker implements Worker {// 实现所有方法
}class RobotWorker implements Worker {public void work() {// 机器人可以工作}public void eat() {throw new UnsupportedOperationException("机器人不需要吃饭");}public void sleep() {throw new UnsupportedOperationException("机器人不需要睡觉");}
}

5. 依赖倒置原则(DIP)

  • 核心
    高层模块不应直接依赖低层模块,二者都应依赖抽象(接口或抽象类)。
    抽象不应依赖细节(具体实现),细节应依赖抽象。
  • 关键点
    “反转”传统的依赖关系方向,使得软件的设计更加灵活、可复用,并且更容易应对变化。
  • 现实类比:电源插座提供标准接口(抽象),各种电器(具体实现)只要符合接口标准就能使用,插座不需要知道具体是什么电器。

日常开发中的问题:忽视DIP会导致高层模块与低层模块紧耦合,难以替换实现,单元测试困难(因为难以mock依赖)。

  • 反例:
class LightBulb {public void turnOn() {// 开灯}public void turnOff() {// 关灯}
}class Switch {private LightBulb bulb;public Switch(LightBulb bulb) {this.bulb = bulb;}public void operate() {// 直接依赖具体实现bulb.turnOn();}
}

二、SpringBoot+MyBatis后台系统中的SOLID原则实践

1. 单一职责原则(SRP)在SpringBoot中的体现

反面案例(违反SRP)

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;// 用户CRUDpublic User getUserById(Long id) { /*...*/ }public void saveUser(User user) { /*...*/ }// 密码加密public String encryptPassword(String raw) { /*...*/ }// 权限检查public boolean checkPermission(User user) { /*...*/ }// 日志记录public void writeLog(User user, String action) { /*...*/ }
}

问题:这个Service类做了太多事情,违反了SRP。如果密码加密算法或日志记录方式需要修改,都要改这个类。

正面案例(遵循SRP)

// 用户CRUD服务
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate PermissionChecker permissionChecker;@Autowiredprivate UserActionLogger actionLogger;public User getUserById(Long id) { /*...*/ }public void saveUser(User user) { user.setPassword(passwordEncoder.encode(user.getPassword()));userMapper.insert(user);actionLogger.log(user, "CREATE");}
}// 密码加密组件
@Component
public class BCryptPasswordEncoder implements PasswordEncoder {public String encode(String raw) { /* 使用BCrypt加密 */ }
}// 权限检查组件
@Component
public class PermissionChecker {public boolean check(User user) { /*...*/ }
}// 日志记录组件
@Component
public class UserActionLogger {public void log(User user, String action) { /*...*/ }
}

SpringBoot中的体现

  • Controller只处理HTTP请求和响应
  • Service只处理业务逻辑
  • Mapper只负责数据库操作
  • 各种Util/Helper类各司其职

2. 开闭原则(OCP)在MyBatis中的体现

场景:我们需要支持多种数据库查询方式(ID查询、姓名查询、条件组合查询)

反面案例(违反OCP)

@Mapper
public interface UserMapper {@Select("SELECT * FROM user WHERE ${condition}") List<User> findByCondition(String condition); // 危险!SQL注入风险// 每新增一种查询方式都要添加新方法
}

正面案例(遵循OCP)

使用MyBatis-Plus,它的Wrapper设计就符合OCP:

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;// 使用条件构造器,不需要修改原有代码就能扩展新查询方式public List<User> findUsers(String name, Integer age) {QueryWrapper<User> wrapper = new QueryWrapper<>();if (name != null) {wrapper.like("name", name);}if (age != null) {wrapper.eq("age", age);}return userMapper.selectList(wrapper);}
}

MP的设计

  • 通过Wrapper可以灵活组合查询条件
  • 新增查询条件不需要修改Mapper接口
  • 符合"对扩展开放,对修改关闭"

3. 里氏替换原则(LSP)在权限系统中的应用

场景:我们有普通用户和管理员用户

反面案例(违反LSP)

class User {public void deletePost(Post post) {// 基础权限检查}
}class Admin extends User {@Overridepublic void deletePost(Post post) {throw new UnsupportedOperationException("管理员应该用adminDeletePost方法");}public void adminDeletePost(Post post) {// 跳过权限检查}
}

问题:Admin无法替换User,因为重写的方法抛出了异常。

正面案例(遵循LSP)

interface PostDeleter {void deletePost(Post post);
}class UserPostDeleter implements PostDeleter {public void deletePost(Post post) {// 基础权限检查}
}class AdminPostDeleter implements PostDeleter {public void deletePost(Post post) {// 管理员有特殊处理,但不抛出异常}
}// 使用时
@Autowired
private Map<String, PostDeleter> deleterMap; // Spring会自动注入所有实现public void deletePost(Post post, String userType) {PostDeleter deleter = deleterMap.get(userType + "PostDeleter");deleter.deletePost(post); // 无论什么用户类型都能安全调用
}

4. 接口隔离原则(ISP)在Service层设计中的应用

场景:用户操作有读操作和写操作,有些客户端只需要读功能

反面案例(违反ISP)

public interface UserService {User getById(Long id);List<User> findAll();void save(User user);void delete(Long id);void resetPassword(Long id);// 很多方法...
}// 报表系统只需要读功能,但被迫实现所有方法

正面案例(遵循ISP)

// 拆分接口
public interface UserReadService {User getById(Long id);List<User> findAll();
}public interface UserWriteService {void save(User user);void delete(Long id);void resetPassword(Long id);
}@Service
public class UserServiceImpl implements UserReadService, UserWriteService {// 实现所有方法
}// 报表系统只需要注入UserReadService
@Autowired
private UserReadService userReadService;

5. 依赖倒置原则(DIP)在SpringBoot中的体现

场景:用户数据存储可能使用MySQL或Redis

反面案例(违反DIP)

@Service
public class UserService {// 直接依赖具体实现private UserMySQLRepository userRepository = new UserMySQLRepository();// 如果改用Redis需要修改代码
}

正面案例(遵循DIP)

// 定义抽象接口
public interface UserRepository {User findById(Long id);void save(User user);
}// MySQL实现
@Repository
public class UserMySQLRepository implements UserRepository {// 实现方法
}// Redis实现
@Repository
public class UserRedisRepository implements UserRepository {// 实现方法
}@Service
public class UserService {@Autowiredprivate UserRepository userRepository; // 依赖抽象// 可以通过@Qualifier或Profile决定注入哪个实现
}

SpringBoot天生支持DIP

  • 通过@Autowired注入接口
  • 具体实现由Spring容器管理
  • 轻松替换实现而不修改业务代码

三、实际应用建议

(1)实际应用

  • Spring框架:依赖注入(DI)是DIP的典型实现。
  • Java集合框架List接口(抽象)与ArrayList/LinkedList(实现)遵循DIP和OCP。
  • 日志库:SLF4J是抽象,Logback/Log4j是具体实现,符合DIP。

(2)实际编程中的选择

  • 写业务代码时:优先用 SRPDIP(拆分职责+依赖接口)。
  • 设计架构时:重点考虑 OCPISP(方便扩展+接口精简)。
  • review代码时:检查 LSP(子类是否破坏父类行为)。

后记

SOLID不是教条,而是帮助写出更健壮代码的工具。在SpringBoot项目中,很多设计已经遵循了这些原则,我们只需要有意识地应用它们。

参考链接

SOLID,面向对象设计五大基本原则

关键字:动漫设计培训机构哪里好_下载手机商城app_站长工具网_站内推广方案

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: