设计模式的六大原则分析

设计模式就是在软件开发过程中所总结形成的一系列准则。当我们遇到一些场景的时候,使用恰当的设计模式可以使得软件设计更加健壮,增强程序的扩展性。

设计模式的六大原则如下:

开闭原则
依赖倒置原则
单一职责原则
接口隔离原则
里氏替换原则
迪米特法则

一、开闭原则(Open Close Principle,OCP):
开闭原则是指一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。用抽象构建框架,用实现扩展细节。也就是说,通过开闭原则,我们可以通过扩展行为来实现新的功能,而不是通过修改已有的代码。开闭原则可以提高软件系统的可复用性和可维护性。

代码讲解:
假设课程接口如下:

public interface ICourse {
    Integer getId();
    String getName();
    Double getPrice();
}

JavaCourse实现ICourse接口:

public class JavaCourse implements ICourse{
    private Integer Id;
    private String name;
    private Double price;
    public JavaCourse(Integer id, String name, Double price) {
        this.Id = id;
        this.name = name;
        this.price = price;
    }
    public Integer getId() {
        return this.Id;
    }
    public String getName() {
        return this.name;
    }
    public Double getPrice() {
        return this.price;
    }
}

此时,若我们有打折活动,对ICourse接口增加方法:

public interface ICourse {
    Integer getId();
    String getName();
    Double getPrice();
    Double getDiscountPrice();
}

那么,实现类也增加对应实现方法:

  public Double getDiscountPrice(){
        return this.price * 0.8;
    }

看起来是实现了功能,但在开发过程中,假设我们的课程很多,那么所有的课程实现类都要实现该方法,课程很多就会很麻烦,而且我们的接口应该是不经常变化的,是稳定且可靠的,否则接口作为契约这个作用就失去了。

所以我们换一种思路,用一个具有java课程打折功能的类继承JavaCourse类:

public class JavaDiscountCourse extends JavaCourse {

    public JavaDiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }
    public Double getDiscountPrice(){
        return super.getPrice()*0.8;
    }
}

在这里插入图片描述
我们修改的是比较偏应用级的代码,底层的接口并没有修改,防止了风险的扩散,也就是说,我们的接口如果方法很多,实现类里面逻辑很非常复杂,增加功能时如果直接修改接口,实现类也跟着变化,就会很容易引起bug,所以我们应该对扩展开放,对修改关闭。

二、依赖倒置原则(Dependence Inversion Principle,DIP):
依赖倒置原则是指高层模块不应该依赖于底层模块,二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。在Java中,接口和抽象类都是抽象,而其实现类就是细节。也就是说,我们应该做到面向接口编程,而非面向实现编程
依赖倒置原则,可以减少类间的耦合性、提高系统的稳定性,提高代码的可读性和可维护性,可降低修改程序所造成的风险。

我们来看一个讲述学习课程的例子。

public class Wen {
    public  void studyJavaCourse(){
        System.out.println("Wen在学习Java课程");
    }
    public  void studyFECourse(){
        System.out.println("Wen在学习FE课程");
    }
}

测试用例:

public class Test {
    public static void main(String[] args) {
        Wen wen = new Wen();
        wen.studyJavaCourse();
        wen.studyFECourse();
    }
}  

Test类属于高层模块,Wen类属于低层模块,高层次模块的实现依赖低层次模块的实现,是不符合依赖倒置原则的。所以我们换一种思路:
添加ICourse接口:

public interface ICourse {
    void studyCourse();
}

两个实现接口ICourse的类:

public class JavaCourse implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("Wen在学习Java课程");
    }
}
public class FECourse implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("Wen在学习FE课程");
    }
}

Wen类:

public class Wen {
    public void studyCourse(){
        iCourse.studyCourse();
    }
}

Test类:

public class Test {
    public static void main(String[] args) {
        Wen wen = new Wen();
        wen.studyCourse(new JavaCourse());
        wen.studyCourse(new FECourse());
    }
}

此时,课程的拓展类编程是面向接口ICourse编程的,而不是面向Wen这个具体的实现类,这样做到了Test类和Wen类是解耦的,同时Wen类和具体的课程实现是解耦的。面向接口编程之后,我们可以定义多种课程,只要该课程实现ICourse接口即可。
以抽象为基础搭建起来的架构比以细节为基础搭建起来的稳定得多。

三、单一职责原则(Single responsibility principle,SRP):
单一职责规定了一个类应该只有一个发生变化的原因。如果一个类承担了多个职责,则会导致多个职责耦合在一起。但部分职责发生变化的时候,可能会导致其余职责跟着受到影响,也就是说我们的程序耦合性太强,不利于变化。单一职责原则降低类的复杂程度、提高类的可读性,提高系统的可维护性,降低业务逻辑变化导致的风险,一个接口的修改只对相应的实现类有影响,对其他接口无影响。

举个例子,我们来看下边的一个接口ICourse:

public interface ICourse {
    String getCourseName();
    byte[] getCourseVideo();

    void studyCourse();
    void refundCourse();
}

ICourse类中拥有获取课程名字和视频的方法,还有学习课程和退款课程的功能。那么,ICourse类其实就是违反了单一职责原则。我们可以将其拥有到职责进行划分,一类是关于课程内容的接口,另一类是关于课程管理的接口。

public interface ICourseContent {
    String getCourseName();
    byte[] getCourseVideo();
}
public interface ICourseManager {
    void studyCourse();
    void refundCourse();
}

这样就符合单一职责原则。

四、接口隔离原则(Interface Segregation Principle, ISP):
接口隔离原则是指客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上

接口隔离原则的使用原则:

根据接口隔离原则拆分接口时,首先必须满足单一职责原则。
接口需要高内聚,提高接口,类和模块的处理能力,减少对外的交互。
定制服务,单独为一个个体提供优良服务(只提供访问者需要的方法)。
接口设计要有限度,接口设计的太小,容易造成开发难度增加或者可维护性降低。

接口隔离原则和单一职责原则很相似,它们的区别在于观察角度不一样。单一职责是从模块、类或方法自身的角度来看的,强调的是职责,接口隔离原则是从调用者的角度来看的。

五、迪米特法则(Law of Demeter,LoD):
迪米特法则也叫最少知道原则,是指一个对象应该对其依赖的对象有最少的了解。该类不需要知道其依赖类的具体实现,只需要依赖类给其提供一个公开对外的public方法即可,其余一概不需要了解。

迪米特法则的核心就是解耦合,减弱类间的各个耦合,提高类的复用率。

六、里氏替换原则(Liskov Substitution Principle,LSP):
里氏替换是指所有父类可以出现的地方,子类就都可以出现,使用子类来替换父类,调用方不需要关心目前传递的父类还是子类。

通过里氏替换原则,我们可以将子类对象做为父类对象来使用,屏蔽了不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。里氏替换之后,父类的对象就可以根据当前赋值给它的子类对象的特性以不同的方式运作。

接下来,我们一起看一个Demo:

public class LiSiTest {
    public static void main(String[] args) {
        // 通过传入子类对象来替换父类
        eat(new Dog());
        eat(new Cat());
    }
    private static void eat(Animals animal){
        animal.eat();
    }
}

abstract class Animals{
    abstract void eat();
}

class Dog extends Animals{
    @Override
    void eat() {
        System.out.println("我是小狗,喜欢吃大肉");
    }
}
 
class Cat extends Animals{
    @Override
    void eat() {
        System.out.println("我是小猫,喜欢吃小鱼干");
    }
}

里氏替换原则可以增强程序的健壮性,子类可以任意增加和缩减,我们都不需要修改接口参数。在实际开发中,实现了传递不同的子类来完成不同的业务逻辑。

接下来,我们对六大设计原则做一个简单的总结。

单一职责原则:类或者接口要实现职责单一
里氏替换原则:使用子类来替换父类,做出通用的编程
依赖倒置原则:面向接口编程
接口隔离原则:接口的设计需要精简单一
迪米特法则:降低依赖之间耦合
开闭原则:对扩展开放,对修改关闭

python023基于Python旅游景点推荐系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
JSP基于SSM网上医院预约挂号系统毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值