ROR中的LSP原则

一个程序应该能够用一个子类的实例替换父类的任何实例,而不会产生负面的副作用,即为LSP原则。

违反LSP原则案例

在我们的示例中,我们尝试用子类(AdminUser类)的实例替换其父类。通过执行这个操作,它破坏了程序,我认为这是一个负面的副作用。

require 'date'
class User
    
    def initialize(email:)
        @email = email
    end

    attr_accessor :settings, :email
end

class AdminUser < User
end

user = User.new(email: "[email protected]")

user.settings = {
    "level" => "Low Security",
    "status" => "Live",
    signed_in: Date.today
}

admin = AdminUser.new(email: "[email protected]")

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 库文件,并规范化设置@settings的数值

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: "[email protected]")

user.settings = {
    "level" => "Low Security",
    "status" => "Live",
    signed_in: Date.today
}

admin = AdminUser.new(email: "[email protected]")

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?

你可能感兴趣的:(ROR中的LSP原则)