今天我们来看下违反设计原则的示例。
含义
单一职责原则(Single Responsibility Principle,SRP):一个类只负责一个功能领域中的相应职责或可以定义为:就一个类而言,应该只有一个引起它变化的原因。
违反SRP原则的示例
在这个示例中,Person类包含了一个名为Wallet的成员变量,并且该类还包含了两个方法来添加和删除钱包中的金额。
这违反了SRP原则,因为Person类应该只负责表示一个人的信息,而不应该与钱包的操作有关。应该将钱包的操作单独封装到一个Wallet类中,让Person类只负责人的信息。
符合SRP原则的示例
在这个示例中,Person类仅包含一个名为Wallet的成员变量,而不包含任何关于钱包的操作。这里将钱包的操作单独封装到Wallet类中,让Person类只负责人的信息。
这样,当需要修改钱包的操作时,只需修改Wallet类即可,而不会影响到Person类的实现。
意图
开闭原则就是说对扩展开放,对修改关闭。
违反OCP原则的示例
如果在一个类中使用了switch语句来判断不同的情况,当需要添加一个新的情况时,必须修改源代码,这是违反OCP的。
符合OCP原则的示例
那么为了满足开闭原则,需要怎么做呢?那就要对系统采用抽象化设计。抽象化是开闭原则的关键。
这个示例遵循OCP原则,因为它将支付方式的处理逻辑封装在不同的实现了Payment接口的类中。
当需要添加新的支付方式时,只需要创建一个新的实现了Payment接口的类即可,不需要修改任何现有的类。
PaymentProcessor类负责处理支付,它只需要知道传入的Payment实例,不需要知道具体的支付方式。
意图
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。里氏代换原 则中说,任何基类可以出现的地方,子类一定可以出现。
违反LSP原则的示例
在这个示例中,Square类继承自Rectangle类,但是在Square类中重写了setWidth和setHeight方法,从而违反了LSP原则,因为在Square类中,setWidth和setHeight方法的实现与Rectangle类中的实现不同。
在Rectangle类中,setWidth和setHeight方法应该只分别设置矩形的宽度和高度,但是在Square类中,这两个方法却同时设置了矩形的宽度和高度,导致Square类的行为与Rectangle类不一致。
符合LSP原则的示例
在这个示例中,Shape类是一个通用的形状类,Rectangle类和Square类都继承自Shape类,并且实现了各自的getArea方法。
这里没有让Square类继承自Rectangle类,而是让它们都继承自Shape类。
这样,当需要添加其他形状时,只需创建一个新的类继承自Shape类,并且实现自己的getArea方法即可,而不会对Rectangle类和Square类的实现造成影响。
意图
每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。
违反ISP原则的示例
在这个示例中,我们定义了一个Animal接口,它包含了三个方法:eat、sleep和fly。
我们有两个实现类Dog和Bird,它们都实现了Animal接口。
然而,Dog并不能飞,因此它的fly方法只是抛出了一个不支持的操作异常。
在这种情况下,我们违反了ISP原则,因为Animal接口强制实现所有的方法,包括不适用于某些实现类的方法。
符合ISP原则的示例
在这个示例中,我们将Animal接口拆分成了两个接口:Animal和Flyable。
Animal接口包含与动物相关的方法,Flyable接口包含与飞行相关的方法。
我们有两个实现类Dog和Bird,它们分别实现了需要的接口。这个设计符合ISP原则,因为每个接口只包含所需的方法,没有多余的方法。
这样,我们可以根据需要选择实现哪个接口,而不需要实现不需要的方法。同时,我们也避免了实现不适用于某些实现类的方法。
意图
面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。
违反DIP原则的示例
在这个示例中,EmailService类依赖于具体实现的SmtpClient类。当我们需要使用不同的邮件传输协议时,EmailService类就不能很好地适应变化。
这是因为EmailService类的实现细节与SmtpClient类的实现细节耦合在一起,导致难以修改。
符合DIP原则的示例
为了遵循DIP原则,我们需要对这个示例进行重构。一种解决方法是使用依赖注入,将SmtpClient对象作为构造函数参数传递给EmailService类。
这样,EmailService类不再依赖于具体实现,而是依赖于抽象。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。