简述solid原则

SOLID Principles是面向对象设计中的五个重要原则,这个SOLID就代表 (当然不是固体)

SRP 单一职责原则

OCP 开闭原则

LSP Liskov替换原则

ISP 接口隔离原则

DIP 依赖倒置原则

单一职责原则(Single Responsibility)

一个类只应该有一个职责,也就是说他的变更只能由一个原因。

所以这个原则怎么帮助我们呢?

1.测试——只有一个职责的类就无需过多的测试用例

2.更低的耦合——一个类的功能越少,依赖程度越低

3.更易管理——更小的类相比于庞大的更容易与管理

举个例子:

这是一个Book类

public class Book {

    private String name;

    private String author;

    private String text;

    //省略构造方法,getter,setter

}

 

我们再添加一些方法

public class Book {



    private String name;

    private String author;

    private String text;



     //省略构造方法,getter,setter



    // 和属性有直接关联的方法

    public String replaceWordInText(String word){

        return text.replaceAll(word, text);

    }



    public boolean isWordInText(String word){

        return text.contains(word);

    }

}

再添加一个输出方法

public class Book {

    //...

    void printTextToConsole(){

        // 输出到控制台的代码

    }

}

这时候,就违反了我们的单一职责原则,我们应该建立一个专注于输出的类

public class BookPrinter {



    //输出方法

    void printTextToConsole(String text){

        //输出到控制台的代码    }



    void printTextToAnotherMedium(String text){

        // 输出代码到其他地方的代码

    }

}

这样,我们不仅遵循了单一职责,而且获得一个可以把内容输出到任意媒介的类。

 

开放封闭原则(open-close principle)

顾名思义,对功能扩展开放,对内部修改封闭。这样做我们就不对已有代码修改,不会造成潜在的新漏洞。当然,在我们修复bug时要修改代码。

举个例子:

假设我们有一个很厉害的吉他

public class Guitar {



    private String make;

    private String model;

    private int volume;

 

    //构造方法,getter,setter

}

但是过了几个月,我们觉得他有点无聊,有些单调,就想给他加一个火焰贴纸,让他更酷炫一点,但是谁知道这样会不会带来bug呢?这时候,就要遵循开闭原则。

public class SuperCoolGuitarWithFlames extends Guitar {



    private String flameColor;



    //构造方法,getter,setter

}

通过继承Guiltar类,我们可以确定已有的代码不会受影响。

 

Liskov替换原则(LisKov Substitution)

这个原则是SOLID里面最复杂的一个,简单的来说,如果类A是类B的一个子类,那么我们就应该在不干扰程序行为的情况下用类A替换类B。

让我们直接看代码:

我们定义一个汽车接口

public interface Car {



    void turnOnEngine();

    void accelerate();

}

让一辆车实现这个接口

 

public class MotorCar implements Car {


    private Engine engine;

    //构造方法,getter,setter

    public void turnOnEngine() {

        //启动引擎

        engine.on();

    }
    public void accelerate() {

        //前进

        engine.powerOn(1000);

    }
}

顺便一说,我们还有新能源汽车。

public class ElectricCar implements Car {

    public void turnOnEngine() {

        throw new AssertionError("我不需要引擎!");

    }

    public void accelerate() {

        //加速很快啊啊啊
    }
}

 

很好,这个例子完美的违反了我们的Liksov替换原则,所以我们应该做的是,在定义接口的时候,把电动车不需要引擎的情况也考虑进去。

 

接口隔离原则(Interface Segregation Principle)

简而言之,就是比较大的接口应该被拆分成更小的。这样就能确保要实现接口的类只需要专注于他们需要用的方法。

那么,假设我们是动物管理员,被分配了熊的领地 ; (   ,我们要清理熊,喂它,抚摸它

public interface BearKeeper {

    void washTheBear();
    void feedTheBear();
    void petTheBear();

}

作为一名敬业的动物管理员,我们并不是很热衷于抚摸熊,这样太危险了。但是我们没有选择的余地,只能实现全部方法。

public interface BearCleaner {

    void washTheBear();

}

public interface BearFeeder {

    void feedTheBear();

}

public interface BearPetter {

    void petTheBear();

}

感谢接口隔离原则,我们把这个接口拆分开来,这样就可以只实现我们想做的事情。

public class CrazyPerson implements BearPetter {

    public void petTheBear() {

        //祝你好运!!!

    }

}

最后,这件危险的工作留给别人做吧。顺便一提,在第一个例子(单一职责)中,我们可以把printer接口拆分成两个功能的接口,这也是接口隔离原则的应用。

 

依赖倒置原则 (Dependency Inversion Principle)

依赖倒置原则就是把我们的模块解耦,不再是高等级模块依赖低等级模块,它们都将依赖抽象。

假如我们有一台老旧的win98电脑

public class Windows98Machine {}

但是没有显示器和键盘又有什么用呢?

public class Windows98Machine {

    private final StandardKeyboard keyboard;

    private final Monitor monitor;

    public Windows98Machine() {

        monitor = new Monitor();

        keyboard = new StandardKeyboard();

    }

}

现在我们有了一台完整的电脑,但是我们在98类中声明了StandardKeyboard和Monitor,这就把3个类耦合在一起了,我们也因此失去了切换键盘/显示器的能力。

那么我们把他们解耦

public interface Keyboard { }

先定义一个键盘接口

public class Windows98Machine{

    private final Keyboard keyboard;

    private final Monitor monitor;

    public Windows98Machine(Keyboard keyboard, Monitor monitor) {

        this.keyboard = keyboard;

        this.monitor = monitor;

    }

}

我们使用了依赖注入方式来添加键盘依赖。还有StrandardKeyboard类要实现Keyboard接口才能注入。显示器类也是同理。

public class StandardKeyboard implements Keyboard { }

现在,我们就能自由的切换键盘和显示器了。

 

你可能感兴趣的:(面向对象设计,ood,solid,principle)