java 常见的设计原则

1. 接口隔离原则

定义:用多个专门的接口,而不是使用单一的总接口,客户端不应该依赖他不需要的接口

注意:

  1. 一个类对应一个类的依赖应该建立在最小的接口上,就是跟这个类没有用的接口我们就不要去实现它
  2. 建立单一接口,不要建立庞大臃肿的解耦
  3. 尽量细化接口,接口中的方法尽量少,跟这个接口没有关联的方法我们就不用写(不要太少,适度)
  4. 注意适度原则,一定要适度

在我们设计接口的时候要多花一点时间去思考,要考虑业务模型,包括以后有可能发生变更的地方都要做到一些预判,所以对于抽象、对于业务模型的理解也是非常重要的

1.1. 接口隔离原则案例

以动物为案例,抽象一个动物类接口,动物具有吃、游泳、飞等行为。

狗实现动物接口,游泳、飞是猫不能实现的;

鱼实现动物类接口,飞是鱼是不能实现的;

鸟实现动物类接口,飞是游泳是不能实现的;

不能实现的行为在代码里就显得多余了。

public interface IAnimal {
    void eat();
    void swim();
    void fly();
}
//狗
public class Dog implements IAnimal {
    @Override
    public void eat() {
        System.out.println("Dog is eating.");
    }

    @Override
    public void swim() {
    }

    @Override
    public void fly() {
    }
}

这样的一个动物类里的游泳和飞对于狗来说就显得多余了,按照接口单一职责原则,我们将接口按职责划分,例如

public interface IEat {
    void eat();
}
public interface IFly {
    void fly();
}
public interface ISwim {
    public void swim();
}

这时候,狗只需要实现吃的行为类就可以了

public class Dog implements IEat{
    @Override
    public void eat() {

    }
}

通过接口隔离原则,就可以将职责非常明确的分割开来,在接口中,方法尽可能哟啊少,只实现跟这个接口有关的方法。

最核心的点在于去掉与我本身无关的代码

2. 迪米特法则

定义:一个对象一个对其他对象保持最少的了解。又叫最少知道原则

尽量减低类与类之间的耦合。

所以迪米特法则强调的是只和朋友交流,不和陌生人说话。

朋友和陌生人:出现在成员变量、方法的输入、输出参数中的类成为朋友类,而出现在方法体内部的类不属实朋友类。

什么是朋友类呢,就是业务有关联的才会出现在成员变量、方法输入、输出上,如果与业务往来没有关系的类就不应该出现在成员变量、方法的输入、输出参数。

3. 里氏替换原则

定义:

如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。

定义扩展:

一个软件实体如果适用一个父类的话,那么一定适用于其子类,所有引用父类的地方必须能够透明地使用其子类的对象,子类对象能够替换父类对象,而程序逻辑不变。

还是有点抽象,对此在进行引申意义

引申意义:子类可以扩展父类的功能,但不能改变父类原有的功能。

含义1:子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。

含义2:子类中可以增加自己特有的方法

含义3:当子类的方法重载父类的方法时,方法的前置条件(即方法的输入、入参)要比父类方法的输入参数更宽松。

含义4:当子类的方法实现父类的方法时(重写、重载或实现抽象方法),方法的后置条件(即方法的输出、返回值)要比父类更加严格或相等。

4. 合成复用原则

定义:

尽量使用对象组合、聚合,而不是继承关系型来达到软件的复用。

优点:

一个类的变化对其它类的影响变小。

继承:相关关系是比较强的,比如动物和马,所有动物都具有的一些抽象特性放在动物类中,马可以继承动物类。

组合:将相互独立的个体放在一起,让它们具备相同的生命周期。比如身体有头、脚、手,缺少就会导致生命周期不完整。

聚合:比如说U盘和电脑,把它们分开也能独立存在工作,不受影响,不具备相同的生命周期。(可以用抽象类的形式进行关联,比如数据库mysql连接、oracle连接,通过抽象类方式继承方法)

5. 开闭原则

定义:一个软件实体如类、模块和函数应该对扩展开发,对修改关闭。用抽象构建框架,用实现扩展细节。

优点:提高软件系统的课复用性、可维护性。

具体理解:

在开发业务时,根据不同业务代码是有不同的改变,和策略模式一样,对于原先的代码不要改变,对于扩展功能重新写一个实现。

例如商品价格:

平时价格----原价

中秋节价格---原价*0.6

双11价格---原价满到达200-50

对于价格这个功能,我们不能在原来的价格代码里修改,如果在原来的价格修改,会导致后续活动中,每一次价格变动,都会对原来代码进行修改,这是不可以的。

针对这种情况,面对每一次价格变动,继承原来的商品类,重写价格方法。即中秋节,有中秋节类;双十一有双十一的类方法,这样就避免对原来代码的修改。这就是对修改关闭,对扩展开放。

6. 依赖倒置原则

定义:高层模块不应该依赖底层模块,二者都应该依赖其抽象。抽象不应该依赖细节;细节应该依赖抽象

针对接口编程,不要针对实现编程

优点:可以减少类间的耦合度、提高系统稳定性,提高代码可读性和可维护性,可降低程序所造成的风险。

7. 单一职责原则

定义:不要存在多于一个导致类变更的原因

在编写代码时需要注意,一个类、接口、方法只负责一项职责,只做一件事。

优点:

  • 降低类的复杂度
  • 提高类的可读性
  • 提高系统的可维护性
  • 降低变更引起的风险

8. 总结

在我写代码时,一般的步骤为:类->接口->方法,即首先想有一个实体,对实体的行为进行抽象,根据不同情况对抽象行为进行具体实现。

在这个过程中,我们遵从一定的规范,才能使得这个实体活过来,并按照自己的意识活动。对此:

类的规范就有迪米特法则、合成复用原则,里氏替换原则,让手为手,衣服为身外物;里氏替换原则则是父类可以做的,子类都可以做。

对于接口的规范就有接口隔离原则、依赖倒置原则,接口隔离就是多余的东西不要,比如眼睛是用来看的没有吃饭的功能,就眼睛有吃饭功能的实现。依赖倒置原则,依赖于抽象实现,不是具体业务实现。

其实呢,这些原则综合起来,就差不多等于单一职责原则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值