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: "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 库文件,并规范化设置@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: "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?
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容