脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Ruby - Ruby使用设计模式中的代理模式与装饰模式的代码实例

Ruby使用设计模式中的代理模式与装饰模式的代码实例

2020-05-07 11:08范孝鹏 Ruby

这篇文章主要介绍了Ruby使用设计模式中的代理模式与装饰模式的代码实例,代理模式与装饰模式都可以归类为结构型的设计模式,需要的朋友可以参考下

代理模式

需求:

小明让小李替他追小丽(送洋娃娃,送花,送巧克力)

没有代理的代码:

?
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
# -*- encoding: utf-8 -*-
 
#追求者类
class Pursuit
 attr_accessor :mm
 
 def initialize(mm)
  @mm = mm
 end
 
 def give_dolls
  puts "#{mm.name} 送你洋娃娃"
 end
 
 def give_flowers
  puts "#{mm.name} 送你鲜花"
 end
 
 def give_chocolate
  puts "#{mm.name} 送你巧克力"
 end
 
end
 
#被追求者类
class Girl
 attr_accessor :name
 
 def initialize(name)
  @name = name
 end
end
 
xiao_hong = Girl.new('小红')
 
xiao_ming = Pursuit.new(xiao_hong)
xiao_ming.give_dolls
xiao_ming.give_flowers
xiao_ming.give_chocolate

只有代理的代码:

?
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
# -*- encoding: utf-8 -*-
 
#代理类
class Proxy
 attr_accessor :mm
 
 def initialize(mm)
  @mm = mm
 end
 
 def give_dolls
  puts "#{mm.name} 送你洋娃娃"
 end
 
 def give_flowers
  puts "#{mm.name} 送你鲜花"
 end
 
 def give_chocolate
  puts "#{mm.name} 送你巧克力"
 end
 
end
 
#被追求者类
class Girl
 attr_accessor :name
 
 def initialize(name)
  @name = name
 end
end
 
xiao_hong = Girl.new('小红')
 
xiao_ming = Proxy.new(xiao_hong)
xiao_ming.give_dolls
xiao_ming.give_flowers
xiao_ming.give_chocolate

只是把追求者类换成了代理类。

实际的代理模式代码:

?
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# -*- encoding: utf-8 -*-
 
#公共接口module
module GiveGift
 def give_dolls
 end
 
 def give_flowers
 end
 
 def give_chocolate
 end
end
 
#追求者类
class Pursuit
 include GiveGift
 attr_accessor :mm, :name
 
 def initialize(mm)
  @mm = mm
 end
 
 def give_dolls
  puts "#{mm.name} 替#{name}送你洋娃娃"
 end
 
 def give_flowers
  puts "#{mm.name} 替#{name}送你鲜花"
 end
 
 def give_chocolate
  puts "#{mm.name} 替#{name}送你巧克力"
 end
 
end
 
#代理类
class Proxy
 include GiveGift
 attr_accessor :gg
 
 def initialize(mm)
  @gg = Pursuit.new(mm)
 end
 
 def give_dolls
  gg.give_dolls
 end
 
 def give_flowers
  gg.give_flowers
 end
 
 def give_chocolate
  gg.give_chocolate
 end
 
end
 
#被追求者类
class Girl
 attr_accessor :name
 
 def initialize(name)
  @name = name
 end
end
 
xiao_hong = Girl.new('小红')
 
xiao_ming = Proxy.new(xiao_hong)
xiao_ming.gg.name = '小明'
xiao_ming.give_dolls
xiao_ming.give_flowers
xiao_ming.give_chocolate


装饰模式
 
需求:

给人搭配不同的服饰

代码版本一

?
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
# -*- encoding: utf-8 -*-
 
class Person
 attr_accessor :name
 
 def initialize(name)
  @name = name
 end
 
 def wear_t_shirts
  puts '大T恤'
 end
 
 def wear_big_trouser
  puts '垮裤'
 end
 
 def wear_sneakers
  puts '破球鞋'
 end
 
 def wear_suit
  puts '西装'
 end
 
 def wear_tie
  puts '领带'
 end
 
 def wear_leather_shoes
  puts '皮鞋'
 end
 
 def show
  puts "*****装扮的#{name}\n\n"
 end
 
end
 
 
xc=Person.new('小菜')
puts "******第一种装扮"
xc.wear_t_shirts
xc.wear_big_trouser
xc.wear_sneakers
xc.show
 
puts "******第二种装扮"
xc.wear_suit
xc.wear_tie
xc.wear_leather_shoes
xc.show

这样写的话,功能是实现了,问题是如果增加“超人”的装扮,就要修改Person类,违反了开放-封闭原则。

 

代码版本二

?
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# -*- encoding: utf-8 -*-
 
class Person
 attr_accessor :name
 
 def initialize(name)
  @name = name
 enddef show
  puts "*****装扮的#{name}\n\n"
 end
 
end
 
 
class Finery
 def show
 end
end
 
class TShirts < Finery
 def show
  puts '大T恤'
 end
end
 
class BigTrouser < Finery
 def show
  puts '垮裤'
 end
end
 
class Sneakers < Finery
 def show
  puts '破球鞋'
 end
end
 
class Suit < Finery
 def show
  puts '西装'
 end
end
 
class Tie < Finery
 def show
  puts '领带'
 end
end
 
 
class LeatherShoes < Finery
 def show
  puts '皮鞋'
 end
end
 
 
xc=Person.new('小菜')
ts = TShirts.new
bt = BigTrouser.new
sk = Sneakers.new
puts "******第一种装扮"
ts.show
bt.show
sk.show
xc.show
 
 
suit = Suit.new
tie = Tie.new
ls = LeatherShoes.new
puts "******第二种装扮"
suit.show
tie.show
ls.show
xc.show

这样改了之后,如果增加超人装扮,确实不需要去修改Person类。存在的问题是,各种衣服是独立的,并且暴露在外边的,就是一件一件穿的,没有顺序,没有控制。

代码版本三

?
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# -*- encoding: utf-8 -*-
 
class Person
 attr_accessor :name
 
 def initialize(name=nil)
  @name = name
 end
 
 def show
  puts "*****装扮的#{name}\n\n"
 end
 
end
 
 
class Finery < Person
 attr_accessor :componet
 
 def decorate(componet)
  @componet = componet
 end
 
 def show
  componet.show if componet
 end
end
 
class TShirts < Finery
 def show
  super
  puts '大T恤'
 end
end
 
class BigTrouser < Finery
 def show
  super
  puts '垮裤'
 end
end
 
class Sneakers < Finery
 def show
  super
  puts '破球鞋'
 end
end
 
class Suit < Finery
 def show
  super
  puts '西装'
 end
end
 
class Tie < Finery
 def show
  super
  puts '领带'
 end
end
 
 
class LeatherShoes < Finery
 def show
  super
  puts '皮鞋'
 end
end
 
 
xc=Person.new('小菜')
ts = TShirts.new
bt = BigTrouser.new
sk = Sneakers.new
puts "******第一种装扮"
ts.decorate xc
bt.decorate ts
sk.decorate bt
sk.show
 
 
suit = Suit.new
tie = Tie.new
ls = LeatherShoes.new
puts "******第二种装扮"
suit.decorate xc
tie.decorate suit
ls.decorate bt
ls.show

延伸 · 阅读

精彩推荐
  • RubyRuby学习笔记之gem 命令详解

    Ruby学习笔记之gem 命令详解

    gem是一种文件组织的包,一般的ruby的很多插件都有由这种各种的包提供。我们来看看gem的用法 ...

    hebedich8662020-04-16
  • Ruby深入讲解Ruby中Block代码块的用法

    深入讲解Ruby中Block代码块的用法

    这篇文章主要介绍了深入讲解Ruby中Block代码块的用法,block是Ruby学习进阶当中的重要知识,需要的朋友可以参考下 ...

    pringwq4582020-04-27
  • Rubyruby实现修改ubuntu下的hosts

    ruby实现修改ubuntu下的hosts

    本文给大家分享的是通过ruby获取github上的hosts文件内容,修改到本地Ubuntu中,十分的实用,具体你懂得,有需要的小伙伴可以参考下。 ...

    脚本之家3882020-05-03
  • Ruby对Ruby on Rails进行高效的单元测试的教程

    对Ruby on Rails进行高效的单元测试的教程

    这篇文章主要介绍了在Ruby on Rails中进行高效的单元测试的教程,使用到了Ruby的RSpec和Factory Girl框架,需要的朋友可以参考下 ...

    李冠德3562020-04-26
  • RubyRuby on Rails所构建的应用程序基本目录结构总结

    Ruby on Rails所构建的应用程序基本目录结构总结

    Ruby on Rails是Ruby世界中一家独大的Web开发框架,要掌握Rails程序的构建,对其目录结构的了解十分必要,下面就来看一下Ruby on Rails所构建的应用程序基本目录结...

    kevinhua4002020-05-09
  • RubyRuby编程中关于中断和返回的用法教程

    Ruby编程中关于中断和返回的用法教程

    这篇文章主要介绍了Ruby编程中关于中断和返回的用法教程,作者用代码举例讲解了其中需要注意的问题,需要的朋友可以参考下 ...

    李哲3142020-04-27
  • RubyWindows下ruby语言安装教程

    Windows下ruby语言安装教程

    这篇文章主要介绍了Windows下ruby语言安装教程,本文使用rubyinstaller提供的安装包安装,并给出图文说明,非常简单,需要的朋友可以参考下 ...

    脚本之家5522020-04-22
  • RubyRuby中对一元操作符重载实例

    Ruby中对一元操作符重载实例

    这篇文章主要介绍了Ruby中对一元操作符重载实例,实例说明如何对一元操作符进行重载,需要的朋友可以参考下 ...

    junjie1852020-04-14