面试题答案
一键面试1. 模块职责划分
- 单一职责原则:每个模块应专注于完成一项主要任务。例如,在一个Web应用中,可以有专门处理用户认证的模块
UserAuthentication
,只负责登录、注册、验证等相关功能,这样使得模块功能明确,易于理解和维护。 - 功能聚合:将相关功能聚合在同一模块。比如,在一个电商项目中,与商品操作相关的功能,如商品查询、添加、修改、删除等可放在
ProductModule
模块中。
2. 模块间依赖管理
- 最小化依赖:尽量减少模块之间不必要的依赖。若一个模块依赖过多其他模块,会使该模块变得脆弱,其他模块的改动可能影响到它。例如,在一个数据分析项目中,数据清洗模块应尽量只依赖于数据读取模块,而避免依赖数据可视化模块等不直接相关的模块。
- 依赖注入:通过传递参数的方式引入依赖,而不是在模块内部直接实例化依赖对象。例如:
module DataProcessor
def process(data_source)
data = data_source.fetch_data
# 处理数据的逻辑
end
end
module DatabaseDataSource
def fetch_data
# 从数据库获取数据的逻辑
end
end
module FileDataSource
def fetch_data
# 从文件获取数据的逻辑
end
end
# 使用
database_source = DatabaseDataSource.new
FileDataSource = FileDataSource.new
processor = DataProcessor.new
processor.process(database_source)
processor.process(file_source)
这样如果数据源有变化,只需要替换传递给 process
方法的参数,而不需要修改 DataProcessor
模块内部代码。
3. 防止模块污染
- 命名空间隔离:模块提供了命名空间,在模块内定义的常量、类和方法不会与全局命名空间或其他模块冲突。例如,定义一个
Utils
模块用于存放通用工具方法:
module Utils
def self.log(message)
puts "[LOG] #{message}"
end
end
这里 log
方法就不会与其他地方定义的 log
方法冲突。
- 私有方法和变量:将不需要外部访问的方法和变量设为私有。在模块内使用
private
关键字来实现,比如:
module MathUtils
def self.add(a, b)
validate_numbers(a, b)
a + b
end
private
def self.validate_numbers(a, b)
raise ArgumentError, "Both arguments must be numbers" unless a.is_a?(Numeric) && b.is_a?(Numeric)
end
end
这里 validate_numbers
方法是私有的,外部无法直接调用,避免了误操作和模块污染。
实际项目场景案例及代码实现
假设我们正在开发一个博客系统。
模块职责划分
- 用户模块(
UserModule
):负责用户相关功能,如注册、登录、信息修改等。
module UserModule
def self.register(username, password)
# 注册逻辑,例如将用户信息保存到数据库
puts "User #{username} registered successfully"
end
def self.login(username, password)
# 登录验证逻辑
puts "User #{username} logged in successfully"
end
end
- 文章模块(
ArticleModule
):处理文章的创建、发布、编辑、删除等操作。
module ArticleModule
def self.create_article(user, title, content)
# 创建文章逻辑,关联用户
puts "#{user}'s article #{title} created"
end
def self.publish_article(article)
# 发布文章逻辑
puts "Article #{article['title']} published"
end
end
模块间依赖管理
ArticleModule
的 create_article
方法依赖 UserModule
来验证用户是否合法。但不是在 ArticleModule
内部直接实例化用户相关操作,而是通过参数传递。
# 使用示例
UserModule.register('John', 'password123')
user = {name: 'John'}
ArticleModule.create_article(user, 'My First Article', 'This is the content')
ArticleModule.publish_article({title: 'My First Article'})
防止模块污染
每个模块都有自己的命名空间,例如 UserModule
和 ArticleModule
中的方法不会相互冲突。同时,模块内部可以将一些辅助方法设为私有,如 UserModule
内部可能有验证密码强度的私有方法。
module UserModule
def self.register(username, password)
validate_password(password)
# 注册逻辑,例如将用户信息保存到数据库
puts "User #{username} registered successfully"
end
private
def self.validate_password(password)
raise ArgumentError, "Password must be at least 6 characters" if password.length < 6
end
end
通过以上方式,在这个博客系统项目中,合理使用模块提高了代码的可维护性。