Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
wangbjun committed Dec 15, 2021
1 parent 8e9f952 commit 93efe74
Show file tree
Hide file tree
Showing 28 changed files with 225 additions and 31 deletions.
2 changes: 1 addition & 1 deletion source/_posts/coding/bit-byte.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: KiB、MiB与KB、MB那些事
date: 2020-08-21 22:02:00
tags: 计量单位
tags: 编程
category: Coding
---
众所周知,1024在程序员里面有一种特殊的含义,以至于现在每年10月24号都变成了程序员节,这是为什么呢?
Expand Down
3 changes: 1 addition & 2 deletions source/_posts/coding/golang/crypt.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ title: Golang常见加密算法实现
date: 2020-03-08 17:02:00
tags:
- Golang
- RSA
- AES
- 编程
category: Golang
---
说完Go里面的md5的用法,这篇文章咱说说用的比较多的加密方式在Go里面如何实现。首先,科普一下,一般待加密的内容被叫作明文,加密使用的关键元素被称为秘钥,加密的结果被称为密文,当然其中还有一个非常关键的加密算法。
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/coding/golang/event-bus.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Golang事件系统Event Bus
date: 2021-06-18 00:58:03
tags: 事件
tags: Golang
category: Golang
---
最近在学习开源项目```Grafana```的代码,发现作者实现了一个事件总线的机制,在项目里面大量应用,效果也非常好,代码也比较简单,介绍给大家看看。
Expand Down
188 changes: 188 additions & 0 deletions source/_posts/coding/golang/golang-oop-interface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
---
title: Golang面向对象接口编程
date: 2021-12-15 22:00:00
tags: Golang
category: Golang
---

说起面向对象(OOP),很多人都听说过封装、继承、多态这些特性,本质上面向对象只是一种软件编程思想。由此衍生到面向对象语言这个概念,其中Java是最典型的代表,在语言层面就有类和对象的设计。

严格来说Go不是一门面向对象的语言,但是在某种层面上也可以实现面向对象的部分特性,说白了,任何软件工程的主要目标都是为了实现重用性、灵活性和扩展性,Go也不例外。

举个例子:假设你需要把一个大象放到冰箱里面,需要几步?

- 第一步.打开冰箱

- 第二步.把大象放进冰箱

- 第三步,关上冰箱

这3个步骤用面向过程的方式去实现可能就是3个函数,比如openFridge、placeElephant、closeFridge,我们只需要依次调用即可。

但是从面向对象的思维来看,冰箱作为一个对象,它应该有2个函数:open、close,而大象作为一个对象应该有一个函数:walk,我们只需要组合这2个对象的函数就完成这些步骤。

## 1.Go的面向对象
Go里面没有类这个概念,只有结构体struct,结构体可以有属性,如:
```go
type Fridge struct {
Name string
Status string
}
```
虽然结构体里面并不能定义函数,但是我们可以给这个结构体定义方法,通过这种形式:
```go
func (i Fridge) Open() {
// open
}

func (i Fridge) Close() {
// close
}
```
通过这种方式我们认为Open和Close是属于Fridge这个结构体的方法,这些加在一起可以比作是面向对象语言里面类、类变量、类方法的概念。非常简单易懂,没有其它面向对象语言里面比如静态类、静态属性等等其它特性。

## 2.函数还是方法?
函数英文是function,方法英文是method,很多人对这2个概念不是非常理解,往往都是混着叫,函数方法不分,虽然本质上都是一段代码块。

严格来说,方法是面向对象的概念,它必须属于一个对象,比如Java是一门完全面向对象的语言,所以只有方法,没有函数。 而函数则是很传统的概念,比如C语言里面函数是一等公民,所以C里面只有函数

回到Go里面,其实也应该区分一下,一般我们说函数,指的是这种不属于任何结构体的函数,可以直接调用:
```go
func Open() {
// open
}
```
而方法则是属于某个结构体的,不能直接调,你得先New一个对象出来,然后再调用这个对象的方法。

很多语言,比如PHP,既有函数,也有方法,非常灵活,所以最好还是区分一下,虽然意思大家都懂。

## 3.Go的接口
这里说的接口不是指API接口,而是面向对象里面的接口,也叫interface,如上所说Go虽然不是一个完全面向对象的语言,但是依然提供了接口,虽然Go的接口和其它语言接口不太一样。

Go的接口一般被称为是```Duck Type```,当你看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,关注点在于对象的行为,能作什么,而不是关注对象所属的类型。

在很多面向对象的语言里面,如果你要实现一个接口你就必须实现其所有定义的抽象方法,这是强制要求,而Go则不是这样,Go甚至连implement这个关键字都没有,你不能“实现”!
```go
type Duck interface {
Walk()
Swim()
}
```
只要一个结构体实现了接口定义的所有方法,我们就认为实现了这个接口
```go
type Dog struct {
}

func (i Dog) Walk() {
}

func (i Dog) Swim() {
}
```
## 4.为什么需要接口?
其实这个问题也困扰我很久,很多时候我们在写业务代码几乎用不到接口,大多数都是一些方法和函数的调用,但是在看一些底层库源码的时候却发现处处是接口。

到底什么时候该用接口? 这是一个非常值得思考的问题

因为接口这种设计,本质上还是为了灵活性和扩展性,什么时候去用还是得看具体情况,比如一个配置文件库,需要支持json、yaml、ini等多种格式,一个日志库需要支持console、file、api各种输出方法。

而过多的使用interface也会导致代码过于冗余,阅读难度增加,变相增加了后续维护成本,实际工作中,公司开发人员水平层次不齐,最简单直白的代码反而更容易被其它人接手维护。

在我看来,在实际业务开发中,接口最实际的意义其实在于方便写单测,配置依赖注入这种实现模式,可以分割不同层之间的依赖,单独对每一层做单测,从而提高代码质量。

比如在开发中,一个模块依赖另一个模块去实现功能,如果不使用接口做隔离,就很难单独的去做测试:
```go
type ArticleService struct{}

func NewArticleService() ArticleService {
return ArticleService{}
}

func (i *ArticleService) GetArticles() ([]byte, error) {
articles, err := NewApi().GetArticles()
if err != nil {
return nil, err
}
return articles, err
}
```
在这段代码里面,ArticleService是依赖Api去获取测试的,他们之间是耦合的,这样写就很难去单独测试ArticleService的逻辑。
```go
type Api struct{}

func NewApi() Api {
return Api{}
}

func (i Api) GetArticles() ([]byte, error) {
get, err := http.Get("https://www.baidu.com")
if err != nil {
return nil, err
}
defer get.Body.Close()
all, err := ioutil.ReadAll(get.Body)
if err != nil {
return nil, err
}
return all, nil
}
```

如果用依赖注入加上接口的方式去改造,可以这么写:
```go
// 定义一个接口
type ApiInterface interface {
GetArticles() ([]byte, error)
}

type ArticleService struct {
api ApiInterface
}

func NewArticleService(api ApiInterface) ArticleService {
return ArticleService{api}
}

func (i *ArticleService) GetArticles() ([]byte, error) {
articles, err := i.api.GetArticles()
if err != nil {
return nil, err
}
return articles, err
}
```
我们定义一个接口,它有一个方法,然后ArticleService依赖这个接口,并且我们在New方法里面通过参数的方式注入这个依赖。

在使用的时候区别并不大,我们只需要先初始化Api对象,而且作为参数传入ArticleService内部,然后调用就行了。
```go
func main() {
articleService := service.NewArticleService(service.NewApi())
res, err := articleService.GetArticles()
if err != nil {
panic(err)
}
fmt.Printf("%s\n", res)
}
```
但是其实际意义也不仅如此,一个是ArticleService依赖的是一个接口,不是一个具体的对象,这就是所谓的“面向接口编程,而不是实现”。另外,我们可以单独针对ArticleService做测试,可以Mock一个Api对象,实现解耦。
```go
type mockApi struct {
}

func (mockApi) GetArticles() ([]byte, error) {
return []byte(""), nil
}

func TestGetArticles(t *testing.T) {
service := NewArticleService(mockApi{})
articles, err := service.GetArticles()

if err != nil {
t.Fatal("should be nil")
}
if len(articles) > 0 {
t.Fatal("should be 0")
}
}
```
这种写法可以屏蔽依赖对象对测试结果的影响,专注于自身逻辑的测试,这里只是简单的展示这种用法,实际开发中可以使用一些mock库更加方便的测试各种情况。
1 change: 0 additions & 1 deletion source/_posts/coding/golang/http-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ title: Golang的HttpServer解析
date: 2020-06-07 22:00:00
tags:
- Golang
- Http
category: Golang
---
Golang之所以非常适合用于网络编程的原因之一就是其自带网络库可以非常简单快速的建立一个基于http或者tcp的服务应用,以http服务为例,只需几行代码:
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/coding/golang/locker.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: 浅谈Golang锁的应用(sync包)
date: 2020-07-02 22:00:00
tags:
- Golang
-
- 编程
category: Golang
---
今天谈一下锁,以及Go里面Sync包里面自带的各种锁,说到锁这个概念,在日常生活中,锁是为了保护一些东西,比如门锁、密码箱锁,可以理解对资源的保护。在编程里面,锁也是为了保护资源,比如说对文件加锁,同一时间只也许一个用户修改,这种锁一般叫作文件锁。
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/coding/golang/make-slice.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Golang里面slice初始化的坑
date: 2020-06-06 23:42:22
tags:
- Golang
- Slice
- 编程
category: Golang
---
相信很多人对Golang里面的数组都不陌生,但实际上99%的场景我们使用的都是slice,原因很简单,Go里面的数组类似C数组长度是固定的,局限太多,而slice则是一个变长的数组,可以自动扩容,类似JS、PHP等弱类型语言里面的数组。
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/coding/php/php-array.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ date: 2016-02-05 19:00:03
category: PHP
tags:
- PHP
- 数组
- 编程
---

在PHP里面使用最多的数据结构恐怕就是数组了,不过PHP的数组和我们传统意义上的数组区别很大,PHP的数组功能上相当于其它语言里面array+list+map数据结构的集合体,这就是动态语言的强大之处。在PHP里面有2种数组,一种是传统的索引数组,另一种是关联数组,其实就是其它语言里面map数据结构。
Expand Down
1 change: 0 additions & 1 deletion source/_posts/coding/php/php-priority-queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ date: 2017-06-05 15:00:00
category: PHP
tags:
- PHP
- Queue
---

## 1.什么是优先队列?
Expand Down
1 change: 0 additions & 1 deletion source/_posts/coding/php/php-socket-programing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ date: 2018-04-05 19:00:03
category: PHP
tags:
- PHP
- Socket
---

## 前言
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/coding/project-manager.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 漫谈IT项目开发流程
date: 2021-08-24 20:30:00
tags: 编程开发
tags: 编程
category: Coding
---
本人工作多年,干倒不少公司,待过十几个人的团队,也进过上百人的团队,也算是项目开发经验丰富。今天我就来说说互联网公司项目开发的常见流程,主要来自于本人经验总结,结合了我这么多年来不同公司的实践所得。对于平时个人开发或者参与多人项目开发,大家可以参考一下,不一定适合所有公司,采取其中部分流程也是可行。
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/coding/where-is-variable-value.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 变量名存放在哪里?
date: 2018-06-07 17:08:41
tags: 变量名
tags: 编程
category: Coding
---

Expand Down
2 changes: 1 addition & 1 deletion source/_posts/life/how-to-learn.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 如何高效的学习编程?
date: 2020-03-03 12:48:37
tags: 学习
tags: 编程
category: Life
keywords: 编程,学习
---
Expand Down
3 changes: 1 addition & 2 deletions source/_posts/os/deepin-wine-qq-bug.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
title: 解决Deepin-Wine-QQ或微信图标Bug
date: 2018-12-01 12:11:08
category: OS
tags:
- Deepin-Wine
tags: linux
---

之前写过一篇文章说在Linux下面使用deepin的wine QQ和微信, 虽然这个版本挺好用,但是一直以来有个bug困扰我:QQ和微信的图标都是wine的小图标,一模一样不说,还重叠在一起,当你使用 **ctrl+tab** 切换应用的时候很头疼,用过的人应该生有感受!
Expand Down
5 changes: 3 additions & 2 deletions source/_posts/os/do-you-need-linux.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
title: 你是否真的需要使用Linux?
date: 2020-02-10 09:52:44
tags: Linux
category: OS
keywords: Linux,Ubuntu,操作系统
tags:
- Linux
- Ubuntu
---

自从跨入IT编程行业一直都在使用Linux桌面系统办公(尝试过挺多发行版,最终选择Ubuntu),平时生活也在用,不知不觉已经4年多了,也安利了身边很多人使用Linux,从最早的疯狂折腾到现在追求稳定,其实也颇有感触,闲来无事聊一聊。
Expand Down
5 changes: 3 additions & 2 deletions source/_posts/os/fix-screen-scale.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
title: Ubuntu休眠后屏幕缩放恢复
date: 2021-06-20 11:33:10
category: OS
tags:
- Ubuntu
tags:
- Linux
- Ubuntu
---
现在很多人都使用高分屏,比如2k、4k的显示器,在Ubuntu上面一般都需要设置缩放比率,之前我写过一篇文章介绍过 [Ubuntu 4K显示器缩放设置](https://wangbjun.site/2019/linux/ubuntu-4k-scale.html)

Expand Down
3 changes: 1 addition & 2 deletions source/_posts/os/free-jetbrains-ide.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ title: 如何免费使用Jetbrains的IDE(GoLand、PhpStorm、WebStorm)
date: 2020-12-31 13:01:02
category: OS
tags:
- Jetbrains
- IDE
- Goland
- Phpstorm
---

## 1.前言
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/os/kali-metasploit.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Kali-Metasploit制作简易木马
date: 2015-08-05 12:01:00
category: OS
tags:
- Kali
- Linux
---

相信很多人都有这种感觉,觉得那些会做木马病毒的人非常牛逼,当然会自己完全写出来木马病毒的肯定非常牛逼,但是实际上,大部分人都是在前人的基础上修改,很多则是用工具生成,出于兴趣,研究了一段时间"黑"科技,也实践了一下!
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/os/kali-wifi-password.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Kali系统下WiFi密码破解
date: 2015-11-01 11:01:00
category: OS
tags:
- Kali
- Linux
---

在网络渗透中,能够接入被攻击者的网络至关重要,只要黑客接入你的网络,利用DNS欺骗,arp攻击等各种钓鱼技术,基本上就能获取一切信息,WIFI网络的安全性重要性不言而喻!
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/os/linux-proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: 详解Linux环境下各种代理设置
date: 2020-05-30 20:31:02
category: OS
tags: Proxy
tags: Linux
---
做技术的人都知道,有时候为了查询一些信息,必须访问一些国外资源,由于这些资源的服务器位于国外,速度较慢,有时候甚至是根本无法访问(你们懂的),这时候拥有一个VPN或者是代理就非常重要了,这也就是国内大部分人使用代理的主要目的,当然代理还有其它很多好处,比如隐藏自己的IP地址和来源。

Expand Down
1 change: 1 addition & 0 deletions source/_posts/os/linux-tools-software.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ date: 2018-12-08 10:03:09
category: OS
tags:
- Linux
- Ubuntu
---

## 前言
Expand Down
2 changes: 1 addition & 1 deletion source/_posts/os/socks-to-http.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 科学上网之socks代理转http(s)
date: 2018-11-03 19:02:46
tags: Socks
tags: 网络
category: OS
---

Expand Down
3 changes: 2 additions & 1 deletion source/_posts/os/sudo-command-not-found.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ title: 解决sudo command not found 报错
date: 2019-06-02 11:29:06
category: OS
tags:
- Sudo
- Linux
- Ubuntu
---

偶尔发现的一个问题,平时主要使用 **Ubuntu** 操作系统,有时候安装一些软件会用加一些自定义PATH,往往为了方便都会把配置写到 **/etc/environment** 里面,这样所有用户包括root都有效:
Expand Down
Loading

0 comments on commit 93efe74

Please sign in to comment.