一個(gè)程序應(yīng)該能夠用一個(gè)子類的實(shí)例替換父類的任何實(shí)例,而不會(huì)產(chǎn)生負(fù)面的副作用误澳,即為LSP原則滩届。
違反LSP原則案例
在我們的示例中,我們嘗試用子類(AdminUser類)的實(shí)例替換其父類养筒。通過執(zhí)行這個(gè)操作,它破壞了程序端姚,我認(rèn)為這是一個(gè)負(fù)面的副作用晕粪。
require 'date'
class User
def initialize(email:)
@email = email
end
attr_accessor :settings, :email
end
class AdminUser < User
end
user = User.new(email: "user@test.com")
user.settings = {
"level" => "Low Security",
"status" => "Live",
signed_in: Date.today
}
admin = AdminUser.new(email: "admin@test.com")
admin.settings = ["Editor", "VIP", Date.today]
# puts user.settings
# puts admin.settings
@user_database =[user, admin]
def signed_in_today?
@user_database.each do |user|
if user.settings[:signed_in] == Date.today
puts "#{user.email} singed in today"
end
end
end
signed_in_today?
解決方案
使用
ostruct
庫文件,并規(guī)范化設(shè)置@settings
的數(shù)值
require 'date'
require 'ostruct'
class User
def initialize(email:)
@email = email
end
def set_settings(level:, status:, signed_in:)
@settings = OpenStruct.new(
level: level,
status: status,
signed_in: signed_in
)
end
def get_settings
@settings
end
attr_accessor :settings, :email
end
class AdminUser < User
end
user = User.new(email: "user@test.com")
user.settings = {
"level" => "Low Security",
"status" => "Live",
signed_in: Date.today
}
admin = AdminUser.new(email: "admin@test.com")
admin.settings = {
level: "Editor" ,
status: "VIP" ,
signed_in: Date .today
}
# puts user.settings
# puts admin.settings
@user_database =[user, admin]
def signed_in_today?
@user_database.each do |user|
if user.settings[:signed_in] == Date.today
puts "#{user.email} singed in today"
end
end
end
signed_in_today?