博客
关于我
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/

你可能感兴趣的文章
NLP项目:维基百科文章爬虫和分类【02】 - 语料库转换管道
查看>>
NLP:使用 SciKit Learn 的文本矢量化方法
查看>>
nmap 使用方法详细介绍
查看>>
Nmap扫描教程之Nmap基础知识
查看>>
nmap指纹识别要点以及又快又准之方法
查看>>
Nmap渗透测试指南之指纹识别与探测、伺机而动
查看>>
Nmap端口扫描工具Windows安装和命令大全(非常详细)零基础入门到精通,收藏这篇就够了
查看>>
NMAP网络扫描工具的安装与使用
查看>>
NMF(非负矩阵分解)
查看>>
nmon_x86_64_centos7工具如何使用
查看>>
NN&DL4.1 Deep L-layer neural network简介
查看>>
NN&DL4.3 Getting your matrix dimensions right
查看>>
NN&DL4.7 Parameters vs Hyperparameters
查看>>
NN&DL4.8 What does this have to do with the brain?
查看>>
nnU-Net 终极指南
查看>>
No 'Access-Control-Allow-Origin' header is present on the requested resource.
查看>>
NO 157 去掉禅道访问地址中的zentao
查看>>
no available service ‘default‘ found, please make sure registry config corre seata
查看>>
No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
查看>>
no connection could be made because the target machine actively refused it.问题解决
查看>>