Ruby for Rails 最佳实践Ⅵ

第六章 模块和程序组织

一、创建和使用模块的基础知识

1. 除了使用 module 关键字来替代 class 关键字之外,编写模块和编写类很相似

module MyFirstModule

         def say_hello

                   puts "Hello"

         end

end

 

2. 使用模块

class ModuleTester

         include MyFirstModule

end

mt = ModuleTester.new

mt.say_hello

 

二、封装似栈特性的模块

1. 封装具有似栈性的结构和行为的 Stacklike 模块(保存到 stacklike.rb 文件中)

module Stacklike

         attr_reader :stack

         def initialize

                   @stack = Array.new

         end

 

         def add_to_stack(obj)

                   @stack.push(obj)

         end

        

         def take_from_stack

                   @stack.pop

         end

end

 

2. 将 Stacklike 模块混含到 Stack 类中,使用 Stack 类的实例

require "stacklike"

class Stack

         include Stacklike

end

 

s = Stack.new

 

s.add_to_stack("item one")

s.add_to_stack("item two")

s.add_to_stack("item three")

 

puts "Objects currently on the stack:"

puts s.stack

taken = s.take_from_stack

puts "Removed this object:"

puts taken

 

puts "Now on stack:"

puts s.stack

 

运行结果

Objects currently on the stack:

item one

item two

item three

Removed this object:

item three

Now on stack:

item one

item two

 

三、模块、类和方法查找

1. 从对象角度看方法查找

module M

         def report

                   puts "'report' method in module M"

         End

end

 

class C

         include M

end

 

class D < C

end

 

obj = D.new

obj.report 输出:'report' method in module M

 

类 D 的对象实例的方法查找过程图

 

 

2. 一条方法查找路径上的两个同名方法

module M

         def report

                   puts "'report' method in module M"

         end

end

 

class C

include M

         def report

                   puts "'report' method in class C"

         end

end

 

c = C.new

c.report # 输出:'report' method in class C

 

3. 混含定义了同名方法的两个模块

module M

         def report

                   puts "'report' method in module M"

         end

end

 

module N

         def report

                   puts "'report' method in module N"

         end

end

 

class C

         include M

         include N

end

 

c = C.new

c.report # 输出:'report' method in module N

 

4. 用 super 提升方法查找路径

module M

         def report

                   puts "'report' method in module M"

         end

end

 

class C

         include M

         def report

                   puts "'report' method in class C"

                   puts "About to trigger the next higher-up report method..."

                   super

                   puts "Back from the 'super' call."

         end

end

 

c = C.new

c.report

 

输出结果

'report' method in class C

About to trigger the next higher-up report method...

'report' method in module M

Back from the 'super' call.

 

四、类/模块的设计和命名

1. 使用类还是模块?

(1)模块没有实例。因此实体或事物最好建模为类,而实体或事物的特性最好建模为模块,因此我们倾向于使用名词作为类名,使用形容词作为模块名。

(2)一个类中有一个父类,但它可以混含任意多个模块。如果使用继承,要慎重考虑生成一个合理的父类/子类关系。如果使用一个类唯一的父类关系最后却发现几组特性中只有一个赋予了该类,那么这个关系还是不要用的好。

 

2. 嵌套的模块和类

模块和类可以相互嵌套

module Tools

class Hammer

要产生定义在 Tools 模块中的 Hammer 类的实例,须用双冒号(::)访问该类

h = Tools::Hammer.new

 

3. Rails 源代码中样版代码中的模块组织

class Composer < ActiveRecord::Base

end


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值