设计模式
文章目录
前言
设计模式只是解决问题的一种思想,它可以提高代码的复用性,可维护性,可读性,稳健性,安全性。
六大原则
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