面试题答案
一键面试使用模块实现代码复用与解耦
- 模块的混入(Mixin):
- 在Ruby中,可以通过
include
关键字将模块混入到类中,从而实现代码复用。例如,假设有一个Logger
模块,提供日志记录功能:
- 在Ruby中,可以通过
module Logger
def log(message)
puts "#{Time.now}: #{message}"
end
end
class User
include Logger
def initialize(name)
@name = name
end
def greet
log("User #{@name} is greeting")
end
end
user = User.new('John')
user.greet
- 这里
User
类通过混入Logger
模块,获得了log
方法,实现了日志记录功能的复用,同时将日志记录功能与User
类本身的业务逻辑解耦。
- 模块作为命名空间:
- 模块可以作为命名空间,避免命名冲突。例如,有两个不同功能的模块
MathUtils
和StringUtils
:
- 模块可以作为命名空间,避免命名冲突。例如,有两个不同功能的模块
module MathUtils
def add(a, b)
a + b
end
end
module StringUtils
def capitalize(str)
str.capitalize
end
end
class MyApp
include MathUtils
include StringUtils
def perform
result = add(2, 3)
text = capitalize('hello')
puts "Addition result: #{result}, Capitalized text: #{text}"
end
end
app = MyApp.new
app.perform
- 这两个模块分别定义了不同的方法,通过作为命名空间,在
MyApp
类中可以清晰地复用这些方法,不会产生命名冲突。
设计遵循开闭原则的类
开闭原则要求类对扩展开放,对修改关闭。例如,设计一个图形绘制系统:
- 定义抽象图形类:
class Shape
def draw
raise NotImplementedError, 'Subclasses must implement draw method'
end
end
- 定义具体图形类:
class Circle < Shape
def initialize(radius)
@radius = radius
end
def draw
puts "Drawing a circle with radius #{@radius}"
end
end
class Rectangle < Shape
def initialize(width, height)
@width = width
@height = height
end
def draw
puts "Drawing a rectangle with width #{@width} and height #{@height}"
end
end
- 使用图形类:
shapes = []
shapes << Circle.new(5)
shapes << Rectangle.new(10, 5)
shapes.each do |shape|
shape.draw
end
- 这里
Shape
类定义了一个抽象的draw
方法,具体的图形类Circle
和Rectangle
继承自Shape
类并实现draw
方法。如果要添加新的图形,比如Triangle
,只需要创建一个新的类继承自Shape
并实现draw
方法,而不需要修改现有的Shape
类或其他具体图形类的代码,符合开闭原则。