Java—设计模式

本文深入探讨了设计模式的六大原则,包括开闭原则、里氏替换原则、依赖倒置原则、单一职责原则、接口隔离原则和迪米特法则,旨在提高代码的复用性、可维护性和可读性。通过具体实例解释了各原则的应用和重要性。
摘要由CSDN通过智能技术生成

设计模式

前言

设计模式只是解决问题的一种思想,它可以提高代码的复用性,可维护性,可读性,稳健性,安全性。

六大原则


1. 开闭原则( OCP )

当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。也就是对扩展开放,对修改关闭。

开闭原则实例

定义接口 Cup

/**
 * 可以通过“抽象约束、封装变化”来实现开闭原则,
 * 即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。
 * 列:
 *      我们需要一个保温杯和一个茶杯。
 *      保温杯的特点是保温。
 *      茶杯的特点是可以过滤茶叶。
 *      而他们相同的属性是可以装水。
 */
public interface Cup {
   
    void water();
}

定义保温杯 ThermsCup,实现 Cup 接口

/**
 * 定义茶杯,实现Cup接口,新增功能过滤茶叶
 */
public class TeaCup implements Cup{
   
    @Override
    public void water() {
   
        System.out.println("接一杯热水");
    }

    /**
     * 新增的过滤茶叶功能
     */
    public void filterTea(){
   
        System.out.println("过滤茶叶");
    }
}

定义茶杯接口 TeaCup ,实现接口 Cup

/**
 * 定义保温杯,实现Cup接口,并且新增保温功能。
 */
public class ThermsCup implements Cup{
   
    @Override
    public void water() {
   
        System.out.println("接一杯热水");
    }

    /**
     * 新增的保温功能
     */
    public void therm(){
   
        System.out.println("新增保温功能");
    }
}

首先定义了杯子的公共属性,找到公共属性,然后在原有的公共属性上进行扩展而不修改原有属性。

开闭原则总结:

1. 对扩展开放,对修改关闭。满足新需求时通过扩展而不修改原来的代码。

2. 里氏替换原则( LSP )

里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。子类可以扩展父类的方法,但不能修改父类原有的功能。在继承父类时,除了新添加的方法,尽量不要重写父类的方法。

如果通过重写父类方法来新增功能,这样的复用性会变得特别差,而且程序出错的概率也会增加。

实例

分析:鸟基本上都会飞行,如燕子的飞行速度大概是每小时 120 千米。但是鸵鸟不会飞。假如要设计一个实例,计算这两种鸟飞行300千米需要多长时间。拿燕子测试结果正确,可以测试出飞行时间。拿鸵鸟结果会发生“除零异常”或是“无穷大”,明显不符合预期。

public class LSPTest {
   
    public static void main(String[] args) {
   
        Swallow swallow = new Swallow();
        Ostrich ostrich = new Ostrich();
        swallow.setFlySpeed(120);
        ostrich.setFlySpeed(120);
        System.out.println("如果飞行300公里");
        try {
   
            System.out.println("燕子飞行"+swallow.getFlyTime(300)+"小时");
            System.out.println("鸵鸟飞行"+ostrich.getFlyTime(300)+"小时");
        }catch (Exception e){
   
            e.printStackTrace();
        }
    }
}

/**
 * 定义鸟类,可以设置鸟的速度和飞行距离。
 */
public class Bird {
   
    double flySpeed;

    /**
     * 设置鸟的飞行速度
     * @param flySpeed 飞行速度
     */
    public void setFlySpeed(double flySpeed) {
   
        this.flySpeed = flySpeed;
    }

    /**
     * 获取鸟的飞行时间
     * @param distance 飞行距离
     * @return 所需时间
     */
    public double getFlyTime(double distance){
   
        return (distance / flySpeed);
    }
}

/**
 * 定义燕子类,继承鸟类Bird计算飞行时间。
 */
public class Swallow extends Bird{
   
}

/**
 * 定义鸵鸟类,继承鸟类Bird。计算飞行时间
 */
public class Ostrich extends Bird{
   

    /**
     * 鸵鸟不会飞,设置每小时飞行速度为0
     * @param flySpeed 飞行速度
     */
    @Override
    public void setFlySpeed(double flySpeed) {
   
        super.flySpeed = 0;
    }
}

打印结果

如果飞行300公里
燕子飞行2.5小时
鸵鸟飞行Infinity小时

程序运行错误的原因是:鸵鸟类重写了鸟类的 setSpeed(double speed) 方法,这违背了里氏替换原则。正确的做法是:取消鸵鸟原来的继承关系,定义鸟和鸵鸟的更一般的父类,如动物类,它们都有奔跑的能力。几维鸟的飞行速度虽然为 0,但奔跑速度不为 0,可以计算出其奔跑 300 千米所要花费的时间。

public class LSPTest {
   
    public static void main(String[] args) {
   
        Swallow swallow = new Swallow
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值