面试题答案
一键面试1. 结合设计模式设计系统架构
在这种大型Ruby项目中,可以结合工厂模式和抽象工厂模式来设计系统架构。
工厂模式
对于简单的对象创建场景,例如数据库访问模块中具体数据库连接对象的创建。假设我们有MySQL和PostgreSQL两种数据库连接方式:
class DatabaseConnection
def self.create_connection(db_type)
case db_type
when :mysql
MySQLConnection.new
when :postgresql
PostgreSQLConnection.new
end
end
end
class MySQLConnection
def connect
puts "Connecting to MySQL database"
end
end
class PostgreSQLConnection
def connect
puts "Connecting to PostgreSQL database"
end
end
在业务逻辑模块中,只需要调用DatabaseConnection.create_connection(:mysql)
或 DatabaseConnection.create_connection(:postgresql)
来获取数据库连接对象,而不需要关心具体的连接对象创建细节,从而降低了业务逻辑模块与具体数据库连接实现的耦合。
抽象工厂模式
当系统中有多个相关的对象家族需要创建时,抽象工厂模式更为合适。例如,用户界面模块可能有不同风格(如Material Design、iOS Design)的界面组件。
class UIFactory
def create_button
raise NotImplementedError
end
def create_text_field
raise NotImplementedError
end
end
class MaterialUIFactory < UIFactory
def create_button
MaterialButton.new
end
def create_text_field
MaterialTextField.new
end
end
class iOSUIFactory < UIFactory
def create_button
iOSButton.new
end
def create_text_field
iOSTextField.new
end
end
class Button
def render
raise NotImplementedError
end
end
class MaterialButton < Button
def render
puts "Rendering a Material Design button"
end
end
class iOSButton < Button
def render
puts "Rendering an iOS button"
end
end
class TextField
def render
raise NotImplementedError
end
end
class MaterialTextField < TextField
def render
puts "Rendering a Material Design text field"
end
end
class iOSTextField < TextField
def render
puts "Rendering an iOS text field"
end
end
在用户界面模块中,通过选择不同的具体工厂(MaterialUIFactory
或 iOSUIFactory
)来创建相应风格的界面组件,而业务逻辑模块无需关心具体的界面风格实现,只与抽象的UIFactory
交互。
2. 模块间解耦及依赖关系管理
- 模块间解耦:通过工厂模式和抽象工厂模式,各个模块依赖于抽象(如抽象工厂类、抽象产品类)而非具体实现。例如业务逻辑模块依赖于
DatabaseConnection
这个抽象的创建数据库连接的类,而不依赖于MySQLConnection
或PostgreSQLConnection
的具体实现;用户界面模块依赖于UIFactory
这个抽象工厂类,而不依赖于MaterialUIFactory
或iOSUIFactory
的具体实现。这样,具体实现的变化不会影响到依赖它们的模块。 - 依赖关系管理:在模块初始化时,将所需的对象通过工厂方法创建并注入到模块中。例如,业务逻辑模块可以在初始化时接收一个由
DatabaseConnection.create_connection
创建的数据库连接对象,而不是在业务逻辑模块内部直接实例化具体的数据库连接对象。同样,用户界面模块在初始化时可以接收一个由具体的UIFactory
子类创建的界面组件对象。
3. 面对需求变化时的扩展性和维护性
- 扩展性:当有新的需求,比如添加一种新的数据库连接方式(如Oracle)或者新的界面风格时,只需要在工厂类中添加相应的创建逻辑即可。对于数据库连接,在
DatabaseConnection
类的create_connection
方法中添加when :oracle
分支创建OracleConnection
对象;对于用户界面,创建一个新的OracleUIFactory
类继承自UIFactory
并实现相应的创建组件方法。这种方式不需要修改依赖这些对象的其他模块,使得系统易于扩展。 - 维护性:由于模块间耦合度低,每个模块专注于自己的职责,当某个模块出现问题时,只需要在该模块内部进行调试和修改,不会对其他模块产生连锁反应。例如,如果
MySQLConnection
的连接逻辑出现问题,只需要修改MySQLConnection
类及其相关的工厂创建逻辑,而不会影响到业务逻辑模块和其他数据库连接相关的部分。