ROR中的开/闭原则
软件元素(类、模块、函数等等)应该对扩展开放,但对修改关闭。编写良好的类不应该为了集成新特性(比如添加新的属性地址)而重写:
class OrderReport
def initialize(customer:, total:)
@customer = customer
@total = total
end
def invoice
puts "Invoice"
puts @customer
puts @total
end
def bill_of_lading
puts "BOL"
puts @customer
puts "Shipping Label..."
end
end
order = OrderReport.new(customer: "Google", total: 100)
order.invoice
order.bill_of_lading
在原类上新增属性或者方法(破坏了closed原则)
class OrderReport
def initialize(customer:, total:, address:)
@customer = customer
@total = total
@address = address
end
def invoice
puts "Invoice"
puts @customer
puts @total
end
def bill_of_lading
puts "BOL"
puts @customer
puts "Shipping Label..."
puts @address
end
end
order = OrderReport.new(customer: "Google",
total: 100,
address: "123 Any Street")
order.invoice
order.bill_of_lading
较好的方式如下
class OrderReport
def initialize(customer:, total:)
@customer = customer
@total = total
end
end
class Invoice < OrderReport
def print_out
puts "Invoice"
puts "Customer: #{@customer}"
puts "Total: #{@total} "
end
end
class BillOFLading < OrderReport
def initialize(address:, **arguments)
super(**arguments)
@address = address
end
def print_out
puts "BOL"
puts "Customer: #{@customer}"
print "Shipping Address: #{@address}"
end
end
invioce = Invoice.new(customer: "Baidu", total: 200)
bill_of_lading = BillOFLading.new(customer: "Yahoo",
total: 100,
address: " 123 Any Street")
invioce.print_out
puts
bill_of_lading.print_out
这种重构有很多好处:
它遵循开/关原则,因为现在当我们为发票或提单构建新特性时,我们不必触及OrderReport
类。因此,我们可以说父类是关闭的。
此外,由于我们拆分了这两个组件,所以无论何时创建发票,我们都不必传递不必要的address元素。这将删除不需要的代码,这可能会在以后导致混淆。
最后,我们的程序不仅遵循开/闭原则,同时也遵循SRP
Question
:如果您运行这段代码,您将看到它仍然具有与以前相同的结果,现在我们的代码可扩展性更强了,那么我们敢说,我们已经遵守SOLID原则了吗?