2025-02-15
golang
00

目录

开闭原则的定义
解释
示例:开闭原则的应用
不符合开闭原则的设计
遵循开闭原则的设计

开闭原则的定义

开闭原则是面向对象设计中的一个核心原则,它的内容是:

软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。

也就是说,当需求变化时,我们应该能够通过扩展现有的代码来实现新的功能,而不是修改现有的代码。这样可以减少现有功能的变动,避免引入新的错误,并且能够提高代码的可维护性和可扩展性。

解释

对扩展开放:意味着我们可以通过添加新的代码来扩展现有功能,而不是修改原有的代码。扩展可以通过继承、实现接口等方式来实现。

对修改封闭:指的是已有的代码不应该被修改,因为修改现有代码容易引入错误,并且可能影响到系统的其他部分。相反,我们应该通过扩展的方式来增强功能。

示例:开闭原则的应用

假设我们有一个简单的图形绘制应用,支持绘制不同的形状(比如圆形和矩形)。如果不遵循开闭原则,当我们需要添加新的形状(例如三角形)时,我们可能需要修改现有的代码,这样会违背开闭原则。

不符合开闭原则的设计

go
package main import "fmt" // 不符合开闭原则的设计 type Shape struct { Type string } func (s *Shape) Draw() { if s.Type == "circle" { fmt.Println("Drawing a circle") } else if s.Type == "rectangle" { fmt.Println("Drawing a rectangle") } } func main() { circle := &Shape{Type: "circle"} rectangle := &Shape{Type: "rectangle"} circle.Draw() rectangle.Draw() }

在上面的代码中,Shape 类在绘制不同类型的形状时,硬编码了具体的形状类型。当我们要添加一个新的形状(比如三角形)时,我们需要修改 Shape 类的 Draw 方法,加入三角形的逻辑。这样做的问题是,每当需要新增功能时,我们都会修改现有代码,增加了潜在的风险,且容易引入错误。

遵循开闭原则的设计

为了解决这个问题,我们可以利用接口和多态来扩展功能,而不修改原有的代码。每个具体的形状(如 Circle 和 Rectangle)都实现一个公共的 Shape 接口,通过这种方式,我们可以为每个形状提供不同的实现。

go
package main import "fmt" // 定义一个接口,所有形状都要实现它 type Shape interface { Draw() } // 圆形 type Circle struct {} func (c *Circle) Draw() { fmt.Println("Drawing a circle") } // 矩形 type Rectangle struct {} func (r *Rectangle) Draw() { fmt.Println("Drawing a rectangle") } // 三角形 type Triangle struct {} func (t *Triangle) Draw() { fmt.Println("Drawing a triangle") } // 高层模块,依赖于接口而不是具体的实现 type DrawingApp struct {} func (d *DrawingApp) DrawShape(s Shape) { s.Draw() } func main() { // 不需要修改任何已有代码,我们只需实现新的形状类型 circle := &Circle{} rectangle := &Rectangle{} triangle := &Triangle{} app := &DrawingApp{} app.DrawShape(circle) app.DrawShape(rectangle) app.DrawShape(triangle) }

本文作者:曹子昂

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!