golang架构设计开闭原则手写实现
作者:ioly 发布时间:2023-07-21 22:01:36
缘起
最近复习设计模式
拜读谭勇德的<<设计模式就该这样学>>
该书以java语言演绎了常见设计模式
本系列笔记拟采用golang练习之
开闭原则
开闭原则(Open-Closed Principle, OCP)指一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。所谓开闭,也正是对扩展和修改两个行为的一个原则。
实现开闭原则的核心思想就是面向抽象编程。
场景
某线上学习平台, 提供系列课程产品(接口: ICourse)
每个课程有id,name,price等属性
现在平台搞促销, golang课程(GolangCourse)打六折
如何上架打折课程? 是直接修改原golang课程的价格, 还是增加折后golang课程?
思路
开闭原则, 就是尽量避免修改, 改以扩展的方式, 实现系统功能的增加
增加"优惠折扣"接口 - IDiscount
增加"折后golang课程" - DiscountedGolangCourse, 同时实现课程接口和折扣接口
DiscountedGolangCourse继承自GolangCourse, 添加实现折扣接口, 并覆盖ICourse.price()方法
ICourse.go
principles/open_close/ICourse.go
课程接口
package open_close
type ICourse interface {
ID() int
Name() string
Price() float64
}
GolangCourse.go
principles/open_close/GolangCourse.go
golang课程类, 实现ICourse接口
package open_close
type GolangCourse struct {
iID int
sName string
fPrice float64
}
func NewGolangCourse(id int, name string, price float64) ICourse {
return &GolangCourse{
iID: id,
sName: name,
fPrice: price,
}
}
func (me *GolangCourse) ID() int {
return me.iID
}
func (me *GolangCourse) Name() string {
return me.sName
}
func (me *GolangCourse) Price() float64 {
return me.fPrice
}
IDiscount.go
principles/open_close/IDiscount.go
折扣接口
package open_close
type IDiscount interface {
Discount() float64
}
DiscountedGolangCourse.go
principles/open_close/DiscountedGolangCourse.go
该课程同时实现ICourse和IDiscount接口
package open_close
type DiscountedGolangCourse struct {
GolangCourse
fDiscount float64
}
func NewDiscountedGolangCourse(id int, name string, price float64, discount float64) ICourse {
return &DiscountedGolangCourse{
GolangCourse: GolangCourse{
iID: id,
sName: name,
fPrice: price,
},
fDiscount : discount,
}
}
// implements IDiscount.Discount
func (me *DiscountedGolangCourse) Discount() float64 {
return me.fDiscount
}
// overwrite ICourse.Price
func (me *DiscountedGolangCourse) Price() float64 {
return me.fDiscount * me.GolangCourse.Price()
}
open_close_test.go
main/open_close_test.go
课程接口测试用例
package main
import (
"testing"
)
import (ocp "learning/gooop/principles/open_close")
func Test_open_close(t *testing.T) {
fnShowCourse := func(it ocp.ICourse) {
t.Logf("id=%v, name=%v, price=%v\n", it.ID(), it.Name(), it.Price())
}
c1 := ocp.NewGolangCourse(1, "golang课程", 100)
fnShowCourse(c1)
c2 := ocp.NewDiscountedGolangCourse(2, "golang优惠课程", 100, 0.6)
fnShowCourse(c2)
}
测试
$> go test -v main/open_close_test.go
=== RUN Test_open_close
open_close_test.go:10: id=1, name=golang课程, price=100
open_close_test.go:10: id=2, name=golang优惠课程, price=60
--- PASS: Test_open_close (0.00s)
PASS
ok command-line-arguments 0.001s
来源:https://segmentfault.com/a/1190000039148996
猜你喜欢
- 使用OpenCV和Python查找图片差异flyfish方法1 均方误差的算法(Mean Squared Error , MSE)下面的一些
- 1. 引言今天来给小伙伴推荐两款实用的便于调试Python代码的工具,可以方便展示我们调试代码的中间状态,提升大家的编码效率。2. 动机在日
- 前言每个页面按照结构可以分成三部分:window page tabbar.其中window和tabbar一般比较固定,page是平常业务开展
- 如何开始 C#学习过程中有一集讲的是如何查看类图,看完视频后自己就学习如何在VS 2019中查看类图,但是找了好长时间都没有找到查看类图这
- python 实现文件查找和某些项输出本文是基于给定一文件(students.txt),查找其中GPA分数最高的 输出,同时输出其对应的姓名
- 先给大家看一看美化之后的效果图:CSS:.div-select{ border: solid 1px #999; h
- 1、序列(拆包)*用作序列拆包:*可对字符串、列表、集合、元组、字典、数字元素等序列进行拆包print(*(1,2,3,4,5,6))#1
- 前几天,使用python时遇到这么一个需求,删除一个列表中值为1的元素。我寻思着使用remove方法,但是remove方法只会删除第一个,于
- 官网资料:loc :https://pandas.pydata.org/pandas-docs/stable/reference
- 本文实例为大家分享了原生js实现波浪导航效果的具体代码,供大家参考,具体内容如下展示效果:源码展示:<!doctype html>
- cvtColor函数这个函数有两个参数1,src 要进行变换的原图像2,code 转换代码标识例子:import cv2image=cv2.
- 1、环境1、python 3.72、pyinstaller2、下载方式:2.1 python安装(略)2.2 安装pyinstaller打开
- 检测自己当前系统环境中python是否已经安装该module,若未安装请自行安装检测自己的pycharm使用的环境变量是否与当前环境一致若不
- Canal是阿里巴巴旗下的一款开源项目,利用Java开发。主要用途是基于MySQL数据库增量日志解析,提供增量数据订阅和消费,目前主要支持M
- 1. A List Apart CSS TopicsA List Apart是一个CSS优秀文章的收集网站,从1999年开始收集文章,关注最
- 如下所示:#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2018/7/13 1
- 前言GitHub就是一个免费托管开源代码的远程仓库。但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护
- 今天从网上看到这个功能,不错啊,以后就可以在文章中,增加这个功能了var re = /<a h
- 1. Django: Python Web应用开发框架Django 应该是最出名的Python框架,GAE甚至Erlang都有框架受它影响。
- 目标学习读取视频,显示视频和保存视频。学习从相机捕捉并显示它。你将学习以下功能:cv.VideoCapture(),cv.VideoWrit