0
点赞
收藏
分享

微信扫一扫

软件架构设计原则

止止_8fc8 2022-01-31 阅读 125
java

文章目录

软件架构设计原则

开闭性原则

什么是开闭性原则?就是我们已经写好的代码,对修改关闭,对扩展开放。

你就比如,公司是九点半上班,晚上六点半下班,你可以早来,可以晚走,这是可以扩展的。但是你不能晚来,早走,你不能在原有的逻辑上进行修改。

依赖倒置原则

细节通过传参进行控制,大的行为通过一个方法进行控制。你比如,现在有一个Tom类,如下

public class Tom{
    public void study(ICourse course){
        course.study();
    }
}

Tom的大的行为就是学习课程,这个大的行为我们使用一个方法study进行控制,而学习课程的一些细节,就是你学习的到底是什么课程,比方说你是学习java,还是学习python,又或者是学习AI算法,都可以通过传递不同的参数进行控制。我们只需要写一些实现类JavaCourse,PythonCourse,AICourse,让这些实现类都实现ICourse接口,然后把这些实现类当做参数传递给study方法就行了。

这样无论Tom想要学习什么课程,都可以通过传递不同的实现类参数给study来实现。这就叫做依赖倒置原则。

如果没有这个依赖倒置原则,你想一下会出现什么后果,就是如果Tom的学习兴趣很浓烈的话,那么每学习一门课程,你就需要要在Tom类里面定义一个方法,比如上面的这个例子,需要在Tom类里面定义三个方法,分别是JavaCourseStudy方法,PythonCourseStudy方法,AICourse方法,这样是不是就显得Tom这个类里面显得特别臃肿,所以这就是依赖倒置原则的好处。

单一职责原则

单一职责原则意思就是:一个类,接口,方法只负责一项职责。

先来说一下方法只负责一项职责是什么意思,就是一个方法中只能有一项功能,如果这个方法中的某一段很长的代码可以被单独抽离成一个功能,那么我们就需要把这段代码单独封装成一个功能。

接口只负责一项职责是什么意思,就是一个接口里面的抽象方法必须要属于同一个大类的功能。比如有专门获取信息的接口,有专门管理信息的接口,我们要写成两个接口,不能把它们写在一个接口里面。

类只负责一项职责是什么意思,我们的类实现了只负责一项职责的接口,那么它肯定也是只负责一项职责。

接口隔离原则

接口隔离原则的意思就是每一个接口必须要是一个最小单位,什么意思呢?

你就比如现在有三个接口:

//可以吃的动物接口
public interface IEatAnimal{
    void eat();
}

//可以飞的动物接口
public interface IFlyAnimal{
    void fly();
}

//可以游泳的动物接口
public interface ISwimAnimal{
    void swim();
}

如果我们现在有一个小鸟Bird,这个小鸟既可以飞又可以吃,但是不可以游泳,那么我们就可以写成这种格式:

public class Bird implements IEatAnimal,IFlyAnimal{
    @Override
    void eat(){}
    @Override
    void fly(){}
}

上面定义的三个接口就是最小单位的接口。

那怎么判断接口不是最小单位的接口呢?你就想一下,如果一个实体类实现了一个接口,这个接口中的抽象方法会不会有得不到继承的。比如现在有一个动物接口,如下:

public interface IAnimal{
    void eat();
    void fly();
    void swim();
}

然后一个小鸟Bird来实现这个接口,那么就会出现一个问题,因为swim()小鸟是做不到的,所以就会出现一个用不着实现的多余方法,那么IAnimal这个接口就不是最小单位的接口。

迪米特原则

迪米特原则的意思就是:只和熟悉的人交流,不和陌生人交流。

其实也就是不要跨层管理,上层就只负责它的直属下层就行了,不要负责它的直属下层的直属下层。

你比如,现在有一个Boss要统计课程的数量,它需要去问TeamLeader,然后TeamLeader会去统计课程的数量。如果Boss不仅要管他的直属下层TeamLeader还要管它的直属下层的直属下层,就会出现下面的这个情况,如下:

//Boss类的代码如下
public class Boss{
    public void commandCheckNumber(TeamLeader teamLeader){
        //模拟Boss一页一页往下翻页,TeamLeader实时统计
        List<Course> courseList = new ArrayList<Course>();
        for(int i=0; i<20; i++){
            courseList.add(new Course());
        }
        teamLeader.checkNumberOfCourse(courseList);
    }
}

//TeamLeader类的代码如下
public class TeamLeader{
    public void checkNumberOfCourse(List<Course> courseList){
        System.out.println("目前已经发布的课程数量是:"+courseList);
    }
}

乍一看上面的代码是没有问题的,但是你仔细分析可以发现,Boss类它不仅和它的直属下层TeamLeader进行了交流,还和它的直属下层的下层Course进行了交流,这样就不符合迪米特原则了。我们可以进行一些修改,让Boss类只和它的直属下层TeamLeader进行交流,不要和Course进行交流,至于和Course进行交流的工作应该分给TeamLeader,如下:

//Boss类的代码如下
public class Boss{
    public void commandCheckNumber(TeamLeader teamLeader){
        teamLeader.checkNumberOfCourse(courseList);
    }
}

//TeamLeader类的代码如下
public class TeamLeader{
    public void checkNumberOfCourse(List<Course> courseList){
        List<Course> courseList = new ArrayList<Course>();
        for(int i=0; i<20; i++){
            courseList.add(new Course());
        }
        System.out.println("目前已经发布的课程数量是:"+courseList);
    }
}

对应到我们的项目中就是,我现在能想到的就是一个三层架构,上层直接去调用它的下层,但不能出现即调用它的下层又调用它的下下层的情况。

里式替换原则

什么是里式替换原则呢?意思就是所有用到父类的地方,都可以用它的子类替换。引申含义其实是:子类可以扩展父类的功能,但不可以改变父类原有的功能。有两个规范:

1.子类可以实现父类中的抽象方法,但是不能重写父类中的非抽象方法,父类中的非抽象方法,子类中必须要保持父类中原有的非抽象方法的完整性。

2.子类中可以增加自己特有的方法。

比如,如果子类中重写了父类的非抽象方法,当用子类替换父类的时候,可能就出现异常了,如下:

因此,根据里式替换原则,子类一定不能覆盖父类的原有的方法,但子类可以增加自己独有的方法。

所以像上面的这种,正方形,长方形的例子,我们要重新写一个接口,把正方形和长方形共有的东西给抽象出去,然后再让正方形,长方形分别重写这个接口,然后实现不同的方法逻辑,如下:

举报

相关推荐

0 条评论