面试题答案
一键面试常见设计缺陷及改进方法
-
模块和类职责不单一
- 问题:一个模块或类承担了过多不同类型的职责,导致代码臃肿、可维护性差。
- 改进:将不同职责拆分成多个独立的模块或类,遵循单一职责原则。
示例:
- 修改前:
class UserManager
def initialize
@users = []
end
def add_user(user)
@users << user
end
def send_email(user, subject, content)
# 邮件发送逻辑
puts "Sending email to #{user}: #{subject}, #{content}"
end
end
- **修改后**:
class UserRepository
def initialize
@users = []
end
def add_user(user)
@users << user
end
end
class EmailSender
def send_email(user, subject, content)
# 邮件发送逻辑
puts "Sending email to #{user}: #{subject}, #{content}"
end
end
-
模块和类之间耦合度过高
- 问题:模块或类之间过度依赖,使得一个模块的修改很可能影响到其他模块,降低了代码的可扩展性和可维护性。
- 改进:通过接口、抽象类等方式降低耦合度,使模块之间通过抽象进行交互。
示例:
- 修改前:
class Database
def get_user(id)
# 从数据库获取用户逻辑
"User #{id}"
end
end
class UserService
def initialize
@database = Database.new
end
def get_user(id)
@database.get_user(id)
end
end
- **修改后**:
class DatabaseInterface
def get_user(id)
raise NotImplementedError
end
end
class Database < DatabaseInterface
def get_user(id)
# 从数据库获取用户逻辑
"User #{id}"
end
end
class UserService
def initialize(database)
@database = database
end
def get_user(id)
@database.get_user(id)
end
end
-
缺少必要的抽象
- 问题:重复的代码片段在多个模块或类中出现,没有进行抽象提取,导致代码冗余。
- 改进:提取重复代码到抽象模块或方法中,提高代码复用性。
示例:
- 修改前:
class OrderProcessor
def calculate_total(order)
total = 0
order.items.each do |item|
total += item.price * item.quantity
end
total
end
end
class CartCalculator
def calculate_total(cart)
total = 0
cart.items.each do |item|
total += item.price * item.quantity
end
total
end
end
- **修改后**:
module TotalCalculator
def calculate_total(items)
total = 0
items.each do |item|
total += item.price * item.quantity
end
total
end
end
class OrderProcessor
include TotalCalculator
def calculate_total(order)
calculate_total(order.items)
end
end
class CartCalculator
include TotalCalculator
def calculate_total(cart)
calculate_total(cart.items)
end
end
-
继承层次过深
- 问题:继承层次过多,导致代码理解和维护困难,同时可能会违反里氏替换原则。
- 改进:尽量减少继承层次,优先考虑组合方式来复用代码。
示例:
- 修改前:
class Animal
def speak
"I'm an animal"
end
end
class Mammal < Animal
def speak
"I'm a mammal"
end
end
class Dog < Mammal
def speak
"I'm a dog"
end
end
class Labrador < Dog
def speak
"I'm a labrador"
end
end
- **修改后**:
class Animal
def speak
"I'm an animal"
end
end
class Dog
def initialize(animal)
@animal = animal
end
def speak
"I'm a dog, based on #{@animal.speak}"
end
end
class Labrador
def initialize(dog)
@dog = dog
end
def speak
"I'm a labrador, based on #{@dog.speak}"
end
end