抽象工厂设计模式Golang

抽象方法设计

抽象工厂提供了一些列相关活相互依赖对象的接口, 而无需指定他们具体的类, 具体的工厂负责实现具体的产品实例.
用一组抽象的对象创建产品, 而不需要关心内部做了什么处理.

抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,
一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个
产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
type Factory interface {
CreateProduct() Product
}

type Product interface {
Describe()
}

//具体的产品
type ConcreteProduct struct {
Name string
}

func (conproduct *ConcreteProduct) Describe() {
fmt.Println(conproduct.Name)
}

//具体工厂
type ConCreteFactory struct {}

func (confactory *ConCreteFactory) CreateProduct() Product {
return &ConcreteProduct{Name: "KG"}
}

造者模式Golang

造者模式(Builder Pattern)

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
抽象建造者类中定义了产品的创建方法和返回方法.
建造者模式的结构中还引入了一个指挥者类Director,该类的作用主要有两个:一方面它隔离了客户与生产过程;
另一方面它负责控制产品的生成过程。指挥者针对抽象建造者编程,客户端只需要知道具体建造者的类型,
即可通过指挥者类调用建造者的相关方法,返回一个完整的产品对象.

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
38
39
40
41
42
43
44
45
46
47
48
49
type Wheel int
type Vehicle struct {
Wheels Wheel
Seats int
Structure string
}

//builder interface
type Builder interface {
SetWheels() Builder
SetSeats() Builder
SetStructure() Builder
GetVehicle() Vehicle
}

//Director
type Director struct {
builder Builder
}

func (director *Director) Construct() {
director.builder.SetWheels().SetSeats().SetStructure() //链式调用
}

func (director *Director) SetBuilder(builder Builder) {
director.builder = builder
}

//car struct
type Car struct {
vehicle Vehicle
}

func (car *Car) SetWheels() Builder {
car.vehicle.Wheels = 4
return car
}
func (car *Car) SetSeats() Builder {
car.vehicle.Seats = 4
return car
}
func (car *Car) SetStructure() Builder {
car.vehicle.Structure = "Car"
return car
}
func (car *Car) GetVehicle() Vehicle {
return car.vehicle
}

简单工厂设计模式Golang

简单工厂设计模式(Simple Factory Pattern)

简单工厂设计模式(Simple Factory Patten): 根据参数的不同返回不同类的实例. 简单工厂模式专门定义一个类来负责创建其他的实例,被创建的实例
通常含有相同的父类.

优点 和 缺点

– 优点

  1. 只需要传递参数就可以创建产品的类.
  2. 创建的对象跟业务代码进行分离.
  3. 可以通过引入配置文件, 可以增加系统的灵活性.

– 缺点

  1. 工厂类中含有大量的逻辑代码. 如果出现问题会影响系统
  2. 会增加类的个数
  3. 系统扩展困难, 需要修改工厂逻辑代码
简单工厂 角色
  1. Factory(工厂类)用来生产产品, 是整个简单工厂模式的核心. 通过工厂类传入想要生产产品的参数, 然后生产产品.
  2. Product(抽象产品类)用来定义具体产品所应实现的接口
  3. ConcreteProduct(具体产品类), 实现抽象产品的接口, 不同的具体产品, 对于同一种方法可能具有不同的实现方式,经由工厂类进行实例化。
UML

代码实现
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
type Car interface {
Drive()
}
type BMW struct{}

func (b *BMW) Drive() {
fmt.Println("Drive BMW")
}

type Audi struct{}

func (a *Audi) Drive() {
fmt.Println("Drive Auti")
}
func Factory(name string) Car {
switch strings.ToLower(name) {
case "audi":
return &Audi{}
case "bmw":
return &BMW{}
default:
fmt.Printf("Not Support %s\n", name)
return nil
}
}

信息流广告算法等

信息流广告-区别

属性 - 受众 - 资源

推广类型 受众原理 媒体资源 流量属性 终端 人群定位
信息流 广告-人 自家媒体, 资源多样化, 质量好 原生性强, 用户体验好 移动端较多, PC端较少 标签, 行为等(大数据)
SEM 人-广告 资源单一, 精准度高 用户需求强烈, 接受度较高 从PC端逐渐转移到移动端 关键词, 搜索行为
DSP 广告-人 整合别人家媒体,资源多样,质量较差 原生性强, 用户体验较好, 剩余流量 移动端较多 标签, 行为(大数据)
联盟广告 广告-人 资源多样,质量较差 强行植入, 用户体验差 PC端较多 关键词搜索,搜索行为
信息流广告-样式

大图
单图
组图

行业占比分析

电扇 40%
游戏 25%
非企 25%
实体 10%

计费模式

CPC: 点击 CPT: 时长
CPM: 展现 CPD: 按天
CPA: 行为 CPR: 反馈
CPS: 销售 CPL: 潜在
OCPC: 目标转化价格

信息流广告-竞价机制

**eCPM = CTR x 出价 x 1000 **

CTR = 点击量 / 曝光量

eCPM = 广告收入 x 1000 / 曝光量
= 出价 x 点击量 x 1000 / 曝光量
= 出价 x 1000 x 点击量 / 曝光量
= 出价 x 1000 x CTR

CPR: 点击率
eCPM: 预估曝光几率

举例

创意A: 出价1.5元, CTR 3.5%
创意B: 出价2.1元, CTR 1.2%

信息流广告 - 暗拍

cpc成交价 = 下一位的出价 x 下一位的质量度 / 你得质量度 + 0.01

广告A的CTR为5%, 而排在其后的广告B的CTR为1%, 那么最终:

A的成交价 = B的出价 x (B的质量/A的质量) + 0.01
= B的价格 x (1% / 5%) + 0.01
= B的出价*0.2 + 0.01

注意误区: 信息流广告, 每个位置都是单独的, 随机展现, 没有排名而言, 脱离SEM广告排名误区.

CPD (cost per download):

适用场景: 一般为应用产品, 如游戏, 软件等. 每次下载的费用请求.

SERP (搜索引擎结果页面)

广告用语

主要广告用语

广告主 advertiser 显然是指想为自己的品牌或者产品做广告的人

媒体 publisher 则是提供广告位置的载体,例如电视台、网站、杂志、楼宇…

广告商 agency 本质上其实就是中介,帮广告主找媒体广告位,帮媒体找广告主。

受众 audience “消费”广告的人

广告位置 inventory 广告的位置

Ad Exchange 广告交换平台
Ad Exchange 广告交换平台不仅仅联合publishers, 它同样把Ad Network联合起来, 这些拥有广告位的,
被统一用 供应方 (Supply side) 一词代替. 广告主的广告.

Ad Exchange,则是一个真正意义上按照供需关系来运转的“市场经济”。

Ad Exchange为每一个商品(广告位置)提供了价高者得的机制. Ad Exchange 则更像是Nashdaq, 广告位置就是股票. 股民就是广告主. 哪些广告位置更有价值, 就会被广告主追逐的更多. 价格就会更高.

RTB (Real Time bidding) 实时竞价 模式

实时竞价一般是按照 CPM 或者 CPC 出价的. 简单说是按照广告被展现的在受众面前的次数出价. 或者按照广告被点击的次数出价.

DSP (Demand Side Platform)需求方平台

它看起来就是帮助广告主玩转Ad Exchange的中介(agency). DSP把Ad Exchange中的广告位的展示做成了一个巨大的改变. 在DSP中广告位这个概念被淡化了, 目标受众(Targe Audience) 的概念则被提出来.

每一个广告背后, 都是一部分受众(audience), 广告主购买广告的位的目的, 实际上就是看中了广告位背后的用户.

DSP就成了一边连接Ad Exchange, 另外一遍服务于广告主的中介. DSP通过请打的受众数据和数学能力, 帮助广告主实时决策, 合理花钱. 所以需要受众数据, 准确的, 海量的. 其二, 强大的自动化算法, 保证最合理的竞价.

DMP (Data Management Platform) 数据管理平台

DSP自己有自己的受众数据, 数据管理平台, 简单讲, 他们手中握有受众数据, 并且能够让DSP连接他们这里, 利用他的数据
DMP为了获取受众数据, 它必须做两件事情, 其一, 它需要为所有受众每一个做一个标记, 这个标记在目前的技术下, 通过cookie实现. 其二, 它还需要能够实现跨域追中

SSP (Supply Side Platform) 供应方平台

供应方(publishers 和 Ad Networks) 有一个呗成为SSP, 他们是大点各个Ad Exchange 的关系. 提供使用体验更一直集成的广告库存管理环境. 为各媒体提供一致、集成的广告位库存管理环境.

策略设计模式Golang

Strategy 策略

该模式定义一些列算法, 并将算法封装到一起.

优点:

  1. 多重条件语句不易维护, 而使用策略模式可以避免使用多重条件语句.
  2. 策略模式提供一些列的重用算法组, 恰当使用继承可以吧算法组公用代码转移到父类里面. 从而避免代码的重复.
  3. 策略模式可以提供相同行为的不同实现, 客户可以根据不同时间或空间要求选择的不同.
  4. 策略模式可以提供开闭原则的完美支持, 可以不修改源码的情况下,灵魂增加算法.
  5. 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

缺点:

  1. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
  2. 策略模式造成很多的策略类。

应用场景:

  1. 旅行出游的时候,选择骑自行车,坐汽车,
  2. 诸葛钢铁有很多锦囊妙计,每一个荷包都是一个策略.
  3. 选择不同种类的支付.

使用场景:

  1. 如在一个系统有很慢类,它之间的区别只是区别于他们的行为,那么使用策略模式可以动态让一个对象在许多行为中选择一种行为.
  2. 一个系统需要动态的几种算法中选择一种.


关于支付的分析图

代码实现
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
type Payment interface {
Pay(money int64) error
Refund(money int64) error
}

type Alipay struct {
}

func (a *Alipay) Pay(money int64) (err error) {
fmt.Printf("Pay by Alipay %d", money)
return
}

func (a *Alipay) Refund(money int64) (err error) {
fmt.Printf("Refund by Alipay %d", money)
return
}

type WechatPay struct {
}

func (w *WechatPay) Pay(money int64) (err error) {
fmt.Printf("Pay by WechatPay %d", money)
return
}

func (w *WechatPay) Refund(money int64) (err error) {
fmt.Printf("Refund by WechatPay %d", money)
return
}
type BankPay struct {
}

func (w *BankPay) Pay(money int64) (err error) {
fmt.Printf("Pay by BankPay %d", money)
return
}

func (w *BankPay) Refund(money int64) (err error) {
fmt.Printf("Refund by BankPay %d", money)
return
}

type PayType struct {
use Payment
}

func (u *PayType) SetPayment(payment Payment) {
u.use = payment
}

func (u *PayType) Pay() error {
return u.use.Pay(10)
}

func (u *PayType) Refund() error {
return u.use.Refund(10)
}
1
2
3
4
5
6
7
8
9

func TestStrategy(t *testing.T) {
a := assert.New(t)
p := PayType{}

p.SetPayment(&Alipay{})
a.Equal("Pay by Alipay 10", p.Pay())
a.Equal("Refund by Alipay 10", p.Pay())
}

工厂方法设计模式Golang

工厂方法模式

工厂方法模式(Factory Method Pattern)又称为工厂模式,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,
即通过不同的工厂子类来创建不同的产品对象。

优点 和 缺点

– 优点

  1. 符合开闭原则, 具有很强的扩展性,弹性和可维护性
  2. 可以很好的对累进行约束,
  3. 客户只需要知道所需产品的具体工厂,而无须知道具体工厂的创建产品的过程,甚至不需要知道具体产品的类名

– 缺点

  1. 每增加一个产品时,都需要一个具体类和一个具体创建者,增加体统类的数目增多, 复杂性增加
  2. 对简单工厂,增加功能修改的是工厂类;对工厂方法,增加功能修改的是产品类
UML

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
type Operator interface {
SetA(int)
SetB(int)
Result() int
}

type OperatorFactory interface {
Create() Operator
}

type OperatorBase struct {
a, b int
}

//SetA 设置 A
func (o *OperatorBase) SetA(a int) {
o.a = a
}

//SetB 设置 B
func (o *OperatorBase) SetB(b int) {
o.b = b
}
type PlusOperator struct {
*OperatorBase
}


type PlusOperatorFactory struct{}

func (PlusOperatorFactory) Create() Operator {
return &PlusOperator{
OperatorBase: &OperatorBase{},
}
}

func (o PlusOperator) Result() int {
return o.a + o.b
}
type MinusOperator struct {
*OperatorBase
}

type MinusOperatorFactory struct{}

func (MinusOperatorFactory) Create() Operator {
return &MinusOperator{
OperatorBase: &OperatorBase{},
}
}

func (o MinusOperator) Result() int {
return o.a - o.b
}

关于Golang 包管理工具的介绍

Golang官方依赖管理工具:dep

就像 npm or yarn 一样的包管理工具.

dep 和 go get 有什么区别

  • go get
    可以通过外部包安装在自己的 $ GOPATH / src / github.com /下面供自己用.
    自己的其他项目也可共同使用这些外部的地方库.

  • dep
    主要是和自己某一个项目相关的依赖库下载到自己的项目包里面, 通常会下载到 vendor 文件下面, 通过使用 dep ensure 根据Gopkg.toml,Gopkg.lock 来更新以来库.

Dep 的使用方法

  • 首先需要安装
    $ go get -u github.com/golang/dep/cmd/dep
  • dep 命令的说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ dep help
dep is a tool for managing dependencies for Go projects

Usage: dep <command>

Commands:

init Initialize a new project with manifest and lock files
status Report the status of the project's dependencies
ensure Ensure a dependency is safely vendored in the project
prune Prune the vendor tree of unused packages

Examples:
dep init set up a new project
dep ensure install the project's dependencies
dep ensure -update update the locked versions of all dependencies
dep ensure github.com/pkg/errors add a dependency to the project

Use "dep help [command]" for more information about a command.

上面是英文版的, 小弟英文一般般, 翻译一下.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ dep help
dep 是Golang的一个包管理工具.

使用方法:dep <命令>

命令:

init 项目的初始化,在时候用过程中生成第三方包列表文件[Gopkg.toml]和锁文件[Gopkg.lock]

status 项目中文件的状态会报告给你

ensure 会安全的根据[Gopkg.toml] [Gopkg.lock]的版本进行更新.

prune 如果代码更新,或者第三包不在使用的时候,可以使用该命令进行删除

例:
dep init 项目初期化
dep ensure 依赖文件进行安装
dep ensure -update 全部的依赖包进行升级
dep ensure github.com/pkg/errors 添加新的依赖包

信息流广告-定义

信息流广告-定义

Feeds: 喂养
又称: 原生信息流

位置: 根据社交/咨询/娱乐属性穿车在用户想要阅读内容当中, 比如朋友圈,咨询app以及娱乐工具等,因为对广告原生内容加工, 让用户容易忽略其广告属性,从而有效的吸引用户.

展现方式: 一文字图片加链接为主, 点击文字或图片链接即可查看详情, 一般会标注 推广广告 二字, 以便用户区分开.

信息流广告-特点

(1) 内容的价值性: 原生广告为受众提供的是有价值有意义的内容,而不是单纯的广告信息.

(2) 内容的原生性: 内容的植入和呈现不破坏页面本身的和谐, 不是为了抢消费者的注意力儿突兀出现.

(3) 用户的主动性: 用户乐于阅读, 乐于分享, 乐于参与其中, 每个用户都可能成为扩散着.

Go语言的GraphQL实践总结

GraphQL 介绍

REST API的使用方式是,server定义一系列的接口,client调用自己需要的接口,获取目标数据进行整合。REST API开发中遇到的问题:

  • 扩展性 ,随着API的不断发展,REST API的接口会变得越来臃肿。
  • 无法按需获取 ,一个返回id, name, age, city, addr, email的接口,如果仅获取部分信息,如name, age,却必须返回接口的全部信息,然后从中提取自己需要的。坏处不仅会增加网络传输量,并且不便于client处理数据
  • 一个请求无法获取所需全部资源 ,例如client需要显示一篇文章的内容,同时要显示评论,作者信息,那么就需要调用文章、评论、用户的接口。坏处造成服务的的维护困难,以及响应时间变长 。
  • 原因: REST API通常由多个端点组成,每个端点代表一种资源。所以,当client需要多个资源是,它需要向REST API发起多个请求,才能获取到所需要的数据。
  • REST API不好处理的问题 , 比如确保client提供的参数是类型安全的,如何从代码生成API的文档等。
  • 避免了 N+1的出现。

如何定义Schema
schema用来描述对于接口获取数据逻辑 ,GraphQL中使用Query来抽象数据的查询逻辑,分为三种,分别是query(查询)、mutation(更改)、subscription(订阅) 。API的接口概括起来有CRUD(创建、获取、更改、删除)四类,query可以覆盖R(获取)的功能,mutation可以覆盖(CUD创建、更改、删除)的功能。

Query

  • query(查询):当获取数据时,选择query类型
  • mutation(更改): 当尝试修改数据时,选择mutation类型
  • subscription(订阅):当希望数据更改时,可以进行消息推送,使用subscription类型(针对当前的日趋流行的real-time应用提出的)。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2018 - 2021 Noonde All Rights Reserved.

UV : | PV :