博客
关于我
Java设计模式的7种设计原则还有很多人不知道
阅读量:373 次
发布时间:2019-03-05

本文共 2635 字,大约阅读时间需要 8 分钟。

开闭原则

开闭原则是软件设计中最基本且重要的原则之一。它的核心思想是:一个软件模型实体(如类、模块或函数)应该对扩展开放,对修改关闭。也就是说,系统应该能够轻松地在不改变系统结构和行为的情况下进行扩展。但一旦需要对现有功能进行修改时,系统应该能够以最小的代价进行调整。

举个例子,假设我们有一个4S店的销售系统。销售员的主要职责是卖车。系统最初的设计可能只有一个sellCar方法,直接返回车辆的价格。然而,随着双十一促销活动的到来,销售员需要在卖车时应用折扣。直接在sellCar方法中增加折扣逻辑显然不够灵活,会导致整个销售流程难以维护。

为了应对这种需求,我们可以引入一个DiscountCar类继承自Car,并在其中实现特定的折扣逻辑。这样,原来的销售系统只需要调用Car接口的sellCar方法,就能自动使用DiscountCar的实现,从而支持折扣功能,而不会对原有的系统产生影响。

依赖倒置原则

依赖倒置原则(Dependency Inversion Principle, DIP)强调的是:一个软件单元应尽可能依赖于抽象而非具体的实现。具体来说,高层次的模块不应该直接依赖于低层次的模块,而是应该依赖于抽象的接口或类。

回到4S店的例子,假设销售不仅需要卖车,还需要销售其他商品。直接在sellCar方法中增加卖玻璃水或防冻液的功能,会让方法过于臃肿,难以维护。为了解决这个问题,我们可以引入一个Any接口,定义一个sell方法,参数类型为Any。具体的商品实现可以通过不同的类(如CarGlassAntifreeze等)来实现Any接口的sell方法。

这样一来,销售系统只需要调用any.sell()方法,就能根据具体的商品类型执行相应的业务逻辑,而不需要关心商品的具体实现细节。

职责单一原则

职责单一原则(Single Responsibility Principle, SRP)指出,每个类或模块应该只有一个明确的职责。一个类或模块不应该承担多个不同的职责。

在4S店的例子中,销售员不仅需要卖车,还需要唱歌、跳舞、说rap等多种技能。我们可以通过接口的方式将这些技能独立出来,并让销售员实现多个接口。例如,SingJumpRap等接口,每个接口代表一种不同的技能。销售员类Seller则需要实现这些接口。

这样一来,系统的结构会更加清晰,技能的组合也更加灵活。例如,可以有不同的销售员类型,如只唱歌的销售员,只跳舞的销售员,或者同时会唱、跳、rap的销售员。

迪米特法则

迪米特法则(Demeter Law, DML)提倡的是:一个对象 shouldn't expose its internal details to other objects. 即一个类不应该直接暴露其内部属性或方法。类与类之间应该保持尽可能低的耦合度。

在4S店的例子中,老板希望查看销售报表。我们可以设计一个Boss类,直接持有SellerReport对象,并调用report方法。然而,这种设计会导致Boss类对Report类的实现产生直接依赖,这种耦合度很高,不易于维护。

为了遵循迪米特法则,我们可以重新设计Boss类,使其只与Seller类有关,而Seller类再与Report类交互。具体来说,Boss类可以调用seller.apply()方法,而Seller类持有Report对象,并在需要时调用report方法。这样,Boss类与Report类之间隔离了耦合度。

接口隔离原则

接口隔离原则(Interface Segregation Principle, ISP)指出:不应该存在一个接口,一个类依赖于它不需要的接口。类与类之间的依赖应该建立在最小的接口上。

在4S店的例子中,销售员需要卖车,同时还需要具备唱歌、跳舞、说rap等技能。我们可以设计一个总接口Skills,包含所有可能的技能方法(如sing()jump()rap()等)。然而,这样的设计会导致接口过于庞大,难以维护。

为了遵循接口隔离原则,我们可以将接口细化为多个独立的接口。例如,SingJumpRap等接口各自独立,销售员类只需要实现它需要的接口。这样,系统的设计更加灵活,维护性也更高。

里氏代换原则

里氏代换原则(Liskov Substitution Principle, LSP)指出:如果一个对象类型为S,另一个对象类型为T,且TS的子类型,那么在T对象的所有行为中代替S对象时,程序的行为不会发生改变。

在4S店的例子中,老板认为新来的销售员只需要具备销售汽车的能力,就可以像资深销售员一样工作。我们可以设计一个NewSeller类继承自Salesman类,且在NewSeller类中实现Salesman类的所有方法。这样,当系统需要销售汽车时,可以直接使用NewSeller对象代替Salesman对象,从而确保行为的一致性。

此外,里氏代换原则还规定,子类可以有自己的个性定义。例如,NewSeller类可以在Salesman类的基础上增加一些额外的功能,如销售额统计、客户关系管理等。

合成/复用原则

合成/复用原则(Composition/Reuse Principle, CRP)强调在软件复用时,应该优先使用组合或聚合关系,而不是继承关系。只有在无法通过组合实现时,才使用继承关系。

在4S店的例子中,假设我们需要支持多种不同的销售场景,如线上销售、线下销售、促销销售等。我们可以通过引入一个SalesChannel接口,定义不同的销售场景方法(如online()offline()promotion()等)。然后,每个具体的销售场景类(如OnlineSalesOfflineSalesPromotionSales)都实现SalesChannel接口的相应方法。

这样一来,销售系统的结构更加灵活,新增销售场景只需要实现相应的接口,而不需要修改现有的代码。

总结

以上七种设计原则是软件设计中必须遵循的基本原则。它们共同构成了软件设计的基础框架,帮助开发者构建出高效、可维护、灵活的软件系统。在实际开发中,我们需要根据具体的业务需求来选择和应用这些原则。同时,也要注意不要过分追求设计模式的使用,否则可能会增加系统的复杂性,降低开发效率。

如果你对这些设计原则有任何疑问,或者需要更深入的了解,欢迎在评论区留言,我会尽力解答!

转载地址:http://elvg.baihongyu.com/

你可能感兴趣的文章
Nginx配置TCP代理指南
查看>>
Nginx配置——不记录指定文件类型日志
查看>>
nginx配置一、二级域名、多域名对应(api接口、前端网站、后台管理网站)
查看>>
Nginx配置代理解决本地html进行ajax请求接口跨域问题
查看>>
nginx配置全解
查看>>
Nginx配置参数中文说明
查看>>
nginx配置域名和ip同时访问、开放多端口
查看>>
Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
查看>>
Nginx配置如何一键生成
查看>>
Nginx配置实例-负载均衡实例:平均访问多台服务器
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Nginx配置负载均衡到后台网关集群
查看>>
ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
查看>>
NHibernate学习[1]
查看>>
NHibernate异常:No persister for的解决办法
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
查看>>