面向对象七大设计原则,看了必会(代码详细版)(上)

简介: 面向对象七大设计原则,看了必会(代码详细版)(上)

咱们首先了解一个单词

solid

这个单词和咱们今天要讲述的七大原则有什么关系?

咱们首先要了解七大原则都有什么?

  1. 单一职责原则 (Single Responsibility Principle)
  2. 开放-关闭原则 (Open-Closed Principle)
  3. 里氏替换原则 (Liskov Substitution Principle)
  4. 接口隔离原则 (Interface Segregation Principle)
  5. 依赖倒转原则 (Dependence Inversion Principle)
  6. 迪米特法则(Law Of Demeter)
  7. 组合/聚合复用原则 (Composite/Aggregate Reuse Principle)

咱们来进行详细的讲解。

1、单一职责原则

定义:

单一职责原则(Single Responsibility Principle,SRP)又称单一功能原则,由罗伯特·C.马丁(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中提出的。这里的职责是指类变化的原因,单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分(There should never be more than one reason for a class to change)。

优点:

单一职责原则的核心就是控制类的粒度大小、将对象解耦、提高其内聚性。如果遵循单一职责原则将有以下优点。

1、降低类的复杂度。一个类只负责一项职责,其逻辑肯定要比负责多项职责简单得多。

2、提高类的可读性。复杂性降低,自然其可读性会提高。

3、提高系统的可维护性。可读性提高,那自然更容易维护了。

4、变更引起的风险降低。变更是必然的,如果单一职责原则遵守得好,当修改一个功能时,可以显著降低对其他功能的影响。

类层面:

错误示范:

public class SingleResponsibility1 {
    public static 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 class SingleResponsibility2 {
    public static void main(String[] args) {
        RoadVehicle roadVehicle = new RoadVehicle();
        roadVehicle.run("汽车");
        AirVehicle airVehicle = new AirVehicle();
        airVehicle.run("飞机");
        WaterVehicle waterVehicle = new WaterVehicle();
        waterVehicle.run("轮船");
    }
}
class RoadVehicle {
    public void run(String vehicle) {
        System.out.println(vehicle + " 在公路运行...");
    }
}
class AirVehicle {
    public void run(String vehicle) {
        System.out.println(vehicle + " 在天空运行...");
    }
}
class WaterVehicle {
    public void run(String vehicle) {
        System.out.println(vehicle + " 在水上运行...");
    }
}
汽车 在公路运行...
飞机 在天空运行...
轮船 在水上运行...

接口层面:

我们假设一个场景, 大家一起做家务, 张三扫地, 李四买菜. 李四买完菜回来还得做饭. 这个逻辑怎么实现呢?

错误示范:

/**
 * 做家务
 */
public interface HouseWork {
    // 扫地
    void sweepFloor();
    // 购物
    void shopping();
}
public class Zhangsan implements HouseWork{
    @Override
    public void sweepFloor() {
        // 扫地
    }
    @Override
    public void shopping() {
    }
}
public class Lisi implements HouseWork{
    @Override
    public void sweepFloor() {
    }
    @Override
    public void shopping() {
        // 购物
    }
}

首先定义了一个做家务的接口, 定义两个方法扫地和买菜. 张三扫地, 就实现扫地接口. 李四买菜, 就实现买菜接口. 然后李四买完菜回来还要做饭, 于是就要在接口类中增加一个方法cooking. 张三和李四都重写这个方法, 但只有李四有具体实现.

这样设计本身就是不合理的. 首先: 张三只扫地, 但是他需要重写买菜方法, 李四不需要扫地, 但是李四也要重写扫地方法. 第二: 这也不符合开闭原则. 增加一种类型做饭, 要修改3个类. 这样当逻辑很复杂的时候, 很容易引起意外错误.

上面这种设计不符合单一职责原则, 修改一个地方, 影响了其他不需要修改的地方.

正确示范:

/**
 * 做家务
 */
public interface Hoursework {
}
public interface Shopping extends Hoursework{
    // 购物
    void shopping();
}
public interface SweepFloor extends Hoursework{
    // 扫地
    void sweepFlooring();
}
public class Zhangsan implements SweepFloor{
    @Override
    public void sweepFlooring() {
        // 张三扫地
    }
}
public class Lisi implements Shopping{
    @Override
    public void shopping() {
        // 李四购物
    }
}

上面做家务不是定义成一个接口, 而是将扫地和做家务分开了. 张三扫地, 那么张三就实现扫地的接口. 李四购物, 李四就实现购物的接口. 后面李四要增加一个功能做饭. 那么就新增一个做饭接口, 这次只需要李四实现做饭接口就可以了.

public interface Cooking extends Hoursework{ 
    void cooking();
}
public class Lisi implements Shopping, Cooking{
    @Override
    public void shopping() {
        // 李四购物
    }
    @Override
    public void cooking() {
        // 李四做饭
    }
}

如上, 我们看到张三没有实现多余的接口, 李四也没有. 而且当新增功能的时候, 只影响了李四, 并没有影响张三. 这就是符合单一职责原则. 一个类只做一件事. 并且他的修改不会带来其他的变化.

2、开放-关闭原则 (Open-Closed Principle)

定义

开放封闭原则(OCP,Open Closed Principle)是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。其他的设计原则,很多时候是为实现这一目标服务的.

具体描述

● 对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。

● 对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对已有代码进行任何修改

为了满足开闭原则,需要对系统进行抽象化设计,抽象化是开闭原则的关键。

示例

错误实例:

public class OpenClosed1 {
    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Triangle());//+新增绘制三角形
    }
}
//这是一个用于绘图的类
class GraphicEditor {
    //接收 Shape 对象,然后根据 type 来绘制不同的图形
    public void drawShape(Shape s) {
        if (s.m_type == 1)
            drawRectangle(s);
        else if (s.m_type == 2)
            drawCircle(s);
        else if (s.m_type == 3)//+新增绘制三角形
            drawTriangle(s);
    }
    //绘制矩形
    public void drawRectangle(Shape r) {
        System.out.println("绘制矩形");
    }
    //绘制圆形
    public void drawCircle(Shape r) {
        System.out.println("绘制圆形");
    }
    //+新增绘制三角形
    public void drawTriangle(Shape r) {
        System.out.println("绘制三角形");
    }
}
class Shape {
    int m_type;
}
//以前就写好的
class Rectangle extends Shape {
    Rectangle() {
        super.m_type = 1;
    }
}
//以前就写好的
class Circle extends Shape {
    Circle() {
        super.m_type = 2;
    }
}
//+新增绘制三角形
class Triangle extends Shape {
    Triangle() {
        super.m_type = 3;
    }
}
绘制矩形
绘制圆形
绘制三角形


相关文章
面向对象七大设计原则,看了必会(代码详细版)(中)
面向对象七大设计原则,看了必会(代码详细版)(中)
|
4月前
|
设计模式 存储 自然语言处理
Java面向对象设计七大原则
Java面向对象设计七大原则
70 0
面向对象七大设计原则,看了必会(代码详细版)(下)
面向对象七大设计原则,看了必会(代码详细版)(下)
|
10月前
|
设计模式 数据库
面向对象的七大设计原则
面向对象的七大设计原则
264 0
|
设计模式 Java 关系型数据库
面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
|
设计模式 算法 Java
六大原则之外的设计原则|设计原则
在前面的几篇设计原则文章中,我们分别讲述了经典的六大设计原则。但是事实上,我们在开发中还有几个重要的设计原则,在这篇文章中,一并给大家讲述。
|
设计模式 前端开发 Java
面向对象设计的六大设计原则 (通俗易懂的版本)
六大原则虽说是原则,但它们并不是强制性的,更多的是建议。
面向对象的设计的7大原则
面向对象的设计的7大原则
191 0
|
设计模式 消息中间件 IDE
设计模式之美(一)——设计原则、规范与重构
  《设计模式之美》是极客时间上的一个代码学习系列,在学习之后特在此做记录和总结。
设计模式之美(一)——设计原则、规范与重构
|
设计模式 Java
面向对象的设计原则最终篇(一)
关于面向对象的设计原则我之前已经解释过四种了,分别是单一职责原则,开放关闭原则,里式替换原则,依赖倒置原则而接下来我们要解释的就是最后的三种原则了,分别是接口隔离原则, 迪米特法则, 组合复用原则。
面向对象的设计原则最终篇(一)