代码之家  ›  专栏  ›  技术社区  ›  yegor256

如何用红宝石装饰所有类似的方法?

  •  1
  • yegor256  · 技术社区  · 6 年前

    这是我的课:

    class Book
      def read
         # something
      end
    end
    

    另一个是:

    class Magazine
      def read
         # something
      end
    end
    

    现在,我想把它们都装饰一下 read 这两个类中的方法。我要他们在开始工作前打印“你好”。我该怎么做?我怀疑,我需要使用混音器,但不知道具体怎么做。

    2 回复  |  直到 6 年前
        1
  •  4
  •   jarosluv    6 年前

    你可以 prepend 模块:

    module Decorator
      def read
        puts "hello"
        super
      end
    end
    
    class Book
      prepend Decorator
    
      def read
        puts "bye"
      end
    end
    
    class Magazine
      prepend Decorator
    
      def read
        puts "cya"
      end
    end
    
    Book.new.read 
    # "hello"
    # "bye"
    
    Magazine.new.read
    # "hello"
    # "cya"
    

    还有更干净的方法来做这种修改 refinements :

    class Book
      def read
        puts "bye"
      end
    end
    
    class Magazine
      def read
        puts "cya"
      end
    end
    
    module Decorator
      def read
        puts "hello"
        super
      end
    end
    
    module DecoratedBook
      refine Book do
        prepend Decorator
      end
    end
    
    module DecoratedMagazine
      refine Magazine do
        prepend Decorator
      end
    end
    
    using DecoratedBook
    using DecoratedMagazine
    
    Book.new.read 
    # "hello"
    # "bye"
    
    Magazine.new.read
    # "hello"
    # "cya"
    

    注意:此代码可能无法运行 irb .

    此外,您还可以在运行时正确执行此操作:

    module Decorator
      def read
        puts "hello"
        super
      end
    end
    
    [Book, Magazine].each do |klass|
      klass.prepend Decorator
    end
    
    Book.new.read 
    # "hello"
    # "bye"
    
    Magazine.new.read
    # "hello"
    # "cya"
    
        2
  •  1
  •   vk26    6 年前

    可能你想要的是:

    class ReaderDecorator
      def initialize(obj)
        @obj = obj
      end
    
      def read
        puts 'Hello'
        @obj.read
      end
    end
    
    ReaderDecorator.new(Book.new).read
    ReaderDecorator.new(Magazine.new).read
    
    推荐文章