单一职责、依赖倒转原则、里氏替换原则理解

本文探讨软件设计中的单一职责原则与依赖倒置原则,强调每个类应仅负责单一功能,减少变更风险,以及高层模块应依赖抽象而非具体实现,确保系统扩展性和维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单一原则:

就一个类而言,应该仅有一个引起它变化的原因。如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。

可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
提高类的可读性,提高系统的可维护性;
变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。

以下就违反了单一原则:

/*
* @Author: Jack Li
* @Date: 2019-7-25
* */
public class SingleResponsibility {
    public void main(String []args){
         Vehicle vehicle = new Vehicle();
         //违反了单一职责原则
         vehicle.run("摩托车");
        vehicle.run("汽车");
        vehicle.run("飞机");
    }
}

/*
* 这个虽然没有在类这个级别上遵守单一职责原则(一个类可以做到海陆空三种行驶),但在方法级别上遵守
* */
class Vehicle{
    public void run(String vehicle){
        System.out.println(vehicle+"在公路上行驶");
    }

    public void runAir(String vehicle){
        System.out.println(vehicle+"在天空上行驶");
    }

    public void runWater(String vehicle){
        System.out.println(vehicle+"在水中上行驶");
    }
}

那怎么修改呢:

   可以定义一个交通方式接口,然后用海陆空三个类去实现这个接口,这样就不违反单一原则

依赖倒转原则:

依赖倒置原则的包含如下的三层含义:

    高层模块不应该依赖低层模块,两者都应该依赖其抽象
    抽象不应该依赖细节
    细节应该依赖抽象

每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块(一般是接口,抽象类),原子逻辑的组装就是高层模块。在Java语言中,抽象就是指接口和或抽象类,两者都不能被直接实例化。细节就是实现类,实现接口或继承抽象类而产生的类就是细节,可以被直接实例化。下面是依赖倒置原则在Java语言中的表现:

    模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的
    接口或抽象类不依赖于实现类
    实现类依赖于接口或抽象类
其实就我的理解:给调用者提供接口,而实现则封装

以下代码依赖倒转原则,Email类与Person类直接发生依赖

/*
@Author: Jack Li
@Date:  2019-7-25 
*/
//不利于程序扩展
public class Main{
    public static void main(String[] args){
        Person person = new Person();
        person.receive(new Email());
    }
}

class Email{
    public String getInfo(){
        return "电子邮件";
    }
}
/*
1.如果获取的对象是微信、短信等等,则新增类,这样Person类与接口IReceiver发生依赖
2.解决思路:引入一个抽象的接口,则扩展只需要实现接口即可
*/
public Person{
    public void receive(Email email){
        
    }
}

修改后:

/*
@Author: Jack Li
@Date:  2019-7-25 
*/
public class Main{
    public static void main(String[] args){
        Person person = new Person();
        person.receive(new Email());
    }
}
interface IReceiver{
     public String getInfo();   
}

class Email implements IReceiver{
    public String getInfo(){
        return "电子邮件";
    }
}
/*
1.如果获取的对象是微信、短信等等,则新增类,这样Person类与接口IReceiver发生依赖
2.解决思路:引入一个抽象的接口,则扩展只需要实现接口即可
*/
public Person{
    public void receive(IReceiver receiver){
        System.out.println(receiver.getInfo());
    }
}

里氏替换原则:

    

总的来说:就是为了防止子类去重写父类,所以可以把一个基类抽出来给子类继承,然后通过聚合、组合

/*
@Author: Jack Li
@Date: 2019-7-25
*/
public class Main{
    public static void main(String[] args){
        
    }
}

class A{
    public int func1(int num1,int num2){
        return num1-num2;
    }
}


//如果外界调用B 的func1,本来以为是相减,但其实被B重写后变成相加
class B extends A{
    public int func1(int num1,int num2){
        return num1+num2;
    }
    
    public int func2(int num1,int num2){
        return num1-num2;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值