开闭原则

开闭原则

软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的

  • 对扩展开放。模块对扩展开放,就意味着需求变化时,可以对模块扩展,使其具有满足那些改变的新行为。换句话说,模块通过扩展的方式去应对需求的变化。
  • 对修改关闭。模块对修改关闭,表示当需求变化时,关闭对模块源代码的修改,当然这里的“关闭”应该是尽可能不修改的意思,也就是说,应该尽量在不修改源代码的基础上面扩展组件。

优势

  1. 保持软件产品的稳定性
  2. 不影响原有测试代码的运行
  3. 使代码更具模块化,易于维护
  4. 提高开发效率

例子

  • 假设我们使用出售电脑为例,首选定义一个顶层接口Computer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 电脑信息
*/
interface Computer {
/**
* 价格
*/
fun getPrice(): Double

/**
* 颜色
*/
fun getColor(): String

/**
* 内存
*/
fun getMemory(): Int

/**
* 尺寸
*/
fun getSize(): Float
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* 华硕电脑
*/
class AsusComputer(
private var price: Double,
private var color: String,
private var memory: Int,
private var size: Float,
) : Computer {
override fun getComputerPrice(): Double = price

override fun getComputerColor(): String = color

override fun getComputerMemory(): Int = memory

override fun getComputerSize(): Float = size
}
/**
* 联想电脑
*/
class LenovoComputer(
private var price: Double,
private var color: String,
private var memory: Int,
private var size: Float,
) : Computer {
override fun getComputerPrice(): Double = price

override fun getComputerColor(): String = color

override fun getComputerMemory(): Int = memory

override fun getComputerSize(): Float = size
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fun main(args: Array<String>) {
val computer: Computer = AsusComputer(4888.88, "深蓝", 8, 14.0f)
println(
"电脑:${
if (computer is AsusComputer) {
"华硕"
} else if (computer is LenovoComputer) {
"联想"
} else {
"未知"
}
}\n售价:${computer.getComputerPrice()}\n颜色:${computer.getComputerColor()}\n内存:${computer.getComputerMemory()}\n尺寸:${computer.getComputerSize()}"
)
}

这是我们一开始的需求,但是随着软件发布运行,我们需求不可能一成不变,肯定要接轨市场。假设现在是双十一,需要搞促销活动。那么我们的代码肯定要添加新的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* 华硕电脑 折扣
*/
class AsusDiscountComputer(
/**
* 折扣
*/
private var discount: Float,
price: Double,
color: String,
memory: Int,
size: Float,
) : AsusComputer(price, color, memory, size) {
/**
* 折扣价
*/
fun getDiscountPrice(): Double = discount * getComputerPrice()
}

/**
* 华硕电脑
*/
open class AsusComputer(
private var price: Double,
private var color: String,
private var memory: Int,
private var size: Float,
) : Computer {
override fun getComputerPrice(): Double = price

override fun getComputerColor(): String = color

override fun getComputerMemory(): Int = memory

override fun getComputerSize(): Float = size
}

1
2
3
4
5
fun main(args: Array<String>) {
val computer = AsusDiscountComputer(0.7f, 4888.88, "深蓝", 8, 14.0f)
println("电脑:华硕\n原价:${computer.getComputerPrice()}\n售价:${computer.getDiscountPrice()}\n颜色:${computer.getComputerColor()}\n内存:${computer.getComputerMemory()}\n尺寸:${computer.getComputerSize()}"
)
}