SOLID准则:Java开发者最佳实践

迷南。 2023-10-09 19:48 130阅读 0赞

SOLID 原则是软件世界中一些最古老的规则。

微信搜索关注《Java学研大本营》,加入读者群,分享更多精彩

SOLID 原则是软件世界中一些最古老的规则。它们使我们能够编写可维护、可读、可重用的代码。在本文中,试图完成一个遵守SOLID原则的现实例子。

396bb4780379affe123936c70b9f1f9c.png

1.单一职责

每个类都应该只有一个目的,而不是充满过多的功能。考虑以下示例:

  1. public class PasswordHasher
  2. {
  3. public String hashAndSavePassword(String password)
  4. {
  5. hashPassword();
  6. savePassword();
  7. }
  8. public void hashPassword()
  9. {
  10. //hashing implementation
  11. }
  12. public void savePassword()
  13. {
  14. //save to the db
  15. }
  16. }

顾名思义,这个类是为散列密码实现的。将它们保存到数据库中不应该是它的责任。每个班级应该有一个单一的责任来履行。

不应该有功能繁多的“神级”,需要完成的任务太多。相反,我们应该尽可能模块化地编写我们的类。在另一个类中实现保存操作。

2.开闭原则

类应该对扩展开放,对修改关闭。

换句话说,您不必重写现有类来实现新功能。

让我们继续我们的密码哈希示例。假设我们希望我们的类能够使用各种算法选项进行散列。

  1. public String hashPassword(String password, HashingType hashingType)
  2. {
  3. if(HashingType.BASE64.equals(hashingType))
  4. {
  5. hashedPassword="hashed with Base64";
  6. }
  7. else if(HashingType.MD5.equals(hashingType))
  8. {
  9. hashedPassword="hashed with MD5";
  10. }
  11. return hashedPassword;
  12. }

如果我们以这种方式实现,我们将破坏 SOLID 中的 O 非常糟糕。每次实现一个新的算法,我们都需要修改已有的类,而且看起来很丑。

感谢 OOP,我们有了抽象。我们应该使我们的初始类成为接口/抽象类,并在具体类中实现算法。

  1. public class Base64Hasher implements PasswordHasher
  2. {
  3. @Override
  4. public String hashPassword(String password)
  5. {
  6. return "hashed with 64";
  7. }
  8. }
  9. public interface PasswordHasher
  10. {
  11. String hashPassword(String password);
  12. }
  13. public class MD5Hasher implements PasswordHasher
  14. {
  15. @Override
  16. public String hashPassword(String password)
  17. {
  18. return "hashed with SHA256";
  19. }
  20. }

类的顺序可能会很奇怪,不幸的是,当它们被放在一起时,它们会按字母顺序排列。

通过这种方式,我们可以在不触及现有代码库的情况下添加新算法。

3. Liskov-替代原则

子类应该能够实现其父类的每个功能,并且可以被视为其父类。

为了演示我们的示例,让我们创建模型(数据)类以使用我们的散列算法。

  1. public abstract class Hashed
  2. {
  3. PasswordHasher passwordHasher;
  4. String hash;
  5. public void generateHash(String password)
  6. {
  7. hash = passwordHasher.hashPassword(password);
  8. }
  9. }
  10. public class Base64 extends Hashed
  11. {
  12. public Base64()
  13. {
  14. this.passwordHasher = new Base64Hasher();
  15. }
  16. }

我们为其他编码实现了相同的…

为了满足 Liskov 规则,Hashed 的每个其他扩展都应该使用有效的散列函数实现并返回一个散列。

例如,如果我们用一个名为“NoHash”的类扩展 Hashed 类,该类使用返回完全相同的密码而不进行任何编码的实现将违反规则,因为 Hashed 的子类应该具有密码的哈希值。

4、接口隔离原则

接口不应该强制类实现它们不能做的事情。大接口应该分成小接口。

考虑我们向接口添加解码功能。

  1. public interface PasswordHasher
  2. {
  3. String hashPassword(String password);
  4. String decodePasswordFromHash(String hash);
  5. }

这将违反该定律,因为我们的一种算法 SHA256 实际上是不可解密的(它是单向函数)。相反,我们可以向适用的类添加另一个接口来实现它们的解码算法。

  1. public interface Decryptable
  2. {
  3. String decodePasswordFromHash(String hash);
  4. }
  5. public class Base64Hasher implements PasswordHasher, Decryptable
  6. {
  7. @Override
  8. public String hashPassword(String password)
  9. {
  10. return "hashed with base64";
  11. }
  12. @Override
  13. public String decodePasswordFromHash(String hash)
  14. {
  15. return "decoded from base64";
  16. }
  17. }

5.依赖倒置原则

组件应该依赖于抽象,而不是具体化。

我们有如下密码服务:

  1. public class PasswordService
  2. {
  3. private Base64Hasher hasher = new Base64Hasher();
  4. void hashPassword(String password)
  5. {
  6. hasher.hashPassword(password);
  7. }
  8. }

我们违反了原则,因为我们将Base64Hasher以及紧密耦合在一起PasswordService

让我们将它们解耦,让客户端通过构造函数注入所需的哈希服务。

  1. public class PasswordService
  2. {
  3. private PasswordHasher passwordHasher;
  4. public PasswordService(PasswordHasher passwordHasher)
  5. {
  6. this.passwordHasher = passwordHasher;
  7. }
  8. void hashPassword(String password)
  9. {
  10. this.passwordHasher.hashPassword(password);
  11. }
  12. }

我们可以很容易地改变散列算法。我们的服务不关心算法,由客户选择它。我们不依赖于具体的实现,而是抽象。

推荐书单

《项目驱动零起点学Java》

d76a05de1409e9059c9e815ac5cc9045.png

《项目驱动零起点学Java》共分 13 章,围绕 6 个项目和 258 个代码示例,分别介绍了走进Java 的世界、变量与数据类型、运算符、流程控制、方法、数组、面向对象、异常、常用类、集合、I/O流、多线程、网络编程相关内容。《项目驱动零起点学Java》总结了马士兵老师从事Java培训十余年来经受了市场检验的教研成果,通过6 个项目以及每章的示例和习题,可以帮助读者快速掌握Java 编程的语法以及算法实现。扫描每章提供的二维码可观看相应章节内容的视频讲解。

《项目驱动零起点学Java》贯穿6个完整项目,经过作者多年教学经验提炼而得,项目从小到大、从短到长,可以让读者在练习项目的过程中,快速掌握一系列知识点。

马士兵,马士兵教育创始人,毕业于清华大学,著名IT讲师,所讲课程广受欢迎,学生遍布全球大厂,擅长用简单的语言讲授复杂的问题,擅长项目驱动知识的综合学习。马士兵教育获得在线教育“名课堂”奖、“最受欢迎机构”奖。

赵珊珊,从事多年一线开发,曾为国税、地税税务系统工作。拥有7年一线教学经验,多年线上、线下教育的积累沉淀,培养学员数万名,讲解细致,脉络清晰。

购买链接:https://u.jd.com/XwJWF2r

精彩回顾

部署Spring Boot应用程序

Java Spring Boot 3.0.0 RC1 震撼登场!

微信搜索关注《Java学研大本营》

访问【IT今日热榜】,发现每日技术热点

发表评论

表情:
评论列表 (有 0 条评论,130人围观)

还没有评论,来说两句吧...

相关阅读