The example explains how Ruby uses the decorator mode in the design mode, and the ruby design mode.

Source: Internet
Author: User
Tags rewind

The example explains how Ruby uses the decorator mode in the design mode, and the ruby design mode.

Overview
If you are engaged in object-oriented development, adding behavior to a class or object and using inheritance mechanisms, this is a basic feature of all object-oriented languages. If an existing class lacks some methods, or you need to add more functions (CHARM) to the method ), you may just inherit this class to generate a new class-this is built on additional code.
By inheriting an existing class, the subclass can have its own method and its parent class method. However, this method is static, and users cannot control the ways and opportunities for adding behaviors. What if you want to change the behavior of an initialized object? Or, what should you do if you want to inherit the behavior of many classes? The first one can only be completed at runtime, which is obviously possible, but may lead to a large number of different classes-terrible things.
Problem
How do you organize your code so that it can easily add basic or few features that are rarely used, rather than directly writing no additional code inside your class?

Solution

  • Dynamically add some additional responsibilities or actions to an object. The Decorator mode is more flexible than the subclass generation function.
  • Provides a flexible solution for changing sub-classes. The decorator mode dynamically extends the functions of an object without changing the original class file and using inheritance. It creates a packaging object, that is, decoration, to package a real object.
  • The decorator mode is more useful when used in a group of child classes. If you have a subclass (derived from a parent class), you need to add additional features when it is used independently of the subclass. You can use the decorator mode, to avoid code duplication and increase in the number of sub-classes.

Applicability

Decorator Mode

  • Add roles to a single object dynamically and transparently without affecting other objects.
  • Handle unrecoverable responsibilities.
  • When the subclass generation method cannot be used for expansion. One case is that there may be a large number of independent extensions,

To support each combination, a large number of child classes are generated, which leads to explosive growth in the number of child classes.

Another scenario is that the class definition is hidden, or the class definition cannot be used to generate a subclass.
 
Instance

class SimpleWriter
 def initialize (path)
  @file = File.open (path, "w")
 end
  
 def write_line (line)
  @ file.print (line)
  @ file.print ("\ n")
 end
  
 #Number of characters
 def pos
  @ file.pos
 end
  
 #It will point the file pointer to the beginning of the file
 def rewind
  @ file.rewind
 end
  
 def close
  @ file.colse
 end
end
  
sw = SimpleWriter.new ("test.txt")
sw.write_line ("Hello")
puts sw.pos
puts sw.rewind
  
#Base class
class WriterDecorator
 def initialize (real_writer)
  @real_writer = real_writer
 end
  
 def write_line
  @ real_writer.write_line
 end
  
 def pos
  @ real_writer.pos
 end
  
 def rewind
  @ real_writer.rewind
 end
  
 def close
  @ real_writer.close
 end
end
  
class NumberingWriter <WriterDecorator
 attr: line_number
 def initialize (real_writer)
  super (real_writer)
  @line_number = 1
 end
  
 #What is actually called is the write_line method of WriterDecorator, just adding the number (decoration) before the content written
 #So NumberingWriter decorated the interface wirte_line of WriterDecorator
 ##
 def write_line (line)
  @ real_writer.write_line ("# {@ line_number}: # {line}")
  @line_number + = 1
 end
end
  
sw = SimpleWriter.new ("numbering_write.txt")
nw = NumberingWriter.new (sw)
nw.write_line ("hello, world")
nw.write_line ("hello, ruby")
puts nw.line_number
  
class CheckSummingWriter <WriterDecorator
 attr_reader: check_num
  
 def initialize (real_writer)
  super (real_writer)
  @check_num = 0
 end
  
 def write_line (line)
  line.each_byte {| byte | @check_num + = byte% 256}
  @ real_writer.write_line (line)
 end
end
  
sw = SimpleWriter.new ("check_num_writer.txt")
csw = CheckSummingWriter.new (sw)
csw.write_line ("hello, world")
puts csw.check_num
  
class TimeStampingWriter <WriterDecorator
  
 def initialize (real_writer)
  super (real_writer)
 end
  
 def write_line (line)
  @ real_writer.write_line ("# {Time.now}: # {line}")
 end
  
end
  
# Inverted looking
# 5. The actual call is SimpleWriter get write_line method, write content to the file
sw = SimpleWriter.new ("mix.txt")
# 4. The NumberingWriter write_line method is actually called, and the number is added before the input data
# Then pass to @real_writer, @real_witer at this time is sw
nw = NumberingWriter.new (sw)
# 3. The actual call to the Write_line method of TimeStampingWriter adds a time stamp to the input
# Then pass to @real_writer, @real_witer at this time is nw
tsw = TimeStampingWriter.new (nw)
# 2. The CheckSummingWriter write_line method is actually called, and the byte count of the input data
# Then pass it to @real_writer, @real_witer at this time is tsw
csw = CheckSummingWriter.new (tsw)
# 1. Csw calls write_line
csw.write_line ("hello, world")
puts csw.check_num

Two ruby-style decoration Models
 
(1) Use extend to mix modules

class SimpleWriter
  def initialize (path)
   @file = File.open (path, "w")
  end
 
  def write_line (line)
   @ file.print (line)
   @ file.print ("\ n")
  end
 
  #Characters
  def pos
   @ file.pos
  end
 
  #It will point the file pointer to the beginning of the file
  def rewind
   @ file.rewind
  end
 
  def close
   @ file.colse
  end
end
 
#Use the extend method to dynamically mix modules for decoration
 
module TimeStampingWriter
  def write_line (line)
   super ("# {Time.now}: # {line}")
  end
end
 
module NumberingWriter
  attr_reader: line_number
  def write_line (line)
   @line_number = 1 unless @line_number
   super ("# {@ line_number}: # {line}")
   @line_number + = 1
  end
end


The added module is called first, and then the write_line method of the parent class is called through super.
In this example, add a timestamp before the text, add a number, and finally write the file

sw = SimpleWriter.new("out3.txt") 
sw.extend(NumberingWriter) 
sw.extend(TimeStampingWriter) 
sw.write_line("hello,ruby") 

 
(2) Use the alias keyword

class SimpleWriter
  def initialize (path)
   @file = File.open (path, "w")
  end
 
  def write_line (line)
   @ file.print (line)
   @ file.print ("\ n")
  end
 
  #Characters
  def pos
   @ file.pos
  end
 
  #It will point the file pointer to the beginning of the file
  def rewind
   @ file.rewind
  end
 
  def close
   @ file.colse
  end
end
 
 
Ruby implements another dynamic way of decorating patterns:
Modify the instance method of the object, so a timestamp will be added to the out1.txt file without affecting the object sw2, and no timestamp will be added to out2.txt.
sw1 = SimpleWriter.new ("out1.txt")
class << sw1
  alias old_write_line write_line
  def write_line (line)
   old_write_line ("# {Time.now}: # {line}")
  end
end
sw1.write_line ("hello, world")
sw2 = SimpleWriter.new ("out2.txt")
sw2.write_line ("hello, world") 


Articles you may be interested in:
  • Detailed description of the structure of the Combination Mode and Its Application in Ruby Design Mode Programming
  • The template method in the design mode applies two examples in Ruby.
  • Example parsing: Use of Strategy Mode in Ruby Design Mode Programming
  • Example of using Builder mode in Ruby Design Mode Programming
  • Detailed description of the Application of Singleton mode in Ruby Design Mode Programming
  • Programming in Ruby design mode-Introduction to adapter Mode
  • Ruby uses code instances in the proxy mode and decoration mode in the Design Mode
  • Ruby uses the simple factory mode and factory method mode in the Design Mode
  • Application instance analysis of appearance mode in Ruby Design Mode Programming


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.