Examples of how Ruby uses the adorner pattern in design patterns _ruby topics

Source: Internet
Author: User
Tags class definition extend inheritance instance method rewind

Overview
If you are engaged in object-oriented development, the implementation of a class or object to increase behavior, the use of inheritance mechanism, this is a basic feature of all object-oriented languages. If a class that already exists lacks certain methods, or needs to add more functionality (glamour) to the method, you may simply inherit the class to produce a new class-which is built on extra code.
Inheriting an existing class makes it possible for subclasses to have methods of the parent class while owning their own methods. However, this method is static and the user cannot control the way and the time to increase the behavior. What do you do if you want to change the behavior of an already initialized object? Or, what do you want to do with the behavior of many classes? The previous one can only be done at run time, the latter 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 some rarely used features, rather than writing directly without extra code inside your class?

Solution

    • Dynamically add some additional responsibilities or behaviors to an object. Decorator mode is more flexible than generating subclasses in terms of adding functionality.
    • Provides a flexible solution for changing subclasses. The adorner pattern expands the functionality of an object dynamically without having to change the original class file and using inheritance. It is by creating a wrapper object that is decorated to wrap the real object.
    • Adorner mode is more useful when used with a set of subclasses. If you have a family of subclasses (derived from a parent class), you need to add additional features to separate use with subclasses, and you can use adorner patterns to avoid code duplication and increase in the number of specific subclasses.

Applicability

Use decorator mode in the following situations

    • Add responsibilities to a single object in a dynamic, transparent manner without affecting other objects.
    • Handle the duties that can be undone.
    • When the method for generating subclasses cannot be extended. One scenario is that there may be a large number of independent extensions,

To support each combination will produce a large number of subclasses, resulting in an explosive increase in the number of subclasses.

Another scenario might be because the class definition is hidden, or the class definition cannot be used to generate subclasses.

instance

Class Simplewriter Def initialize (path) @file = File.Open (Path, "W") End def Write_line (line) @file. Print (l 
 INE) @file. Print ("\ n") End #字符数 def POS @file. Pos End #它将会将文件指针指向文件的开头 def Rewind @file. Rewind End def close @file. Colse End-SW = Simplewriter.new ("test.txt") sw.write_line ("Hello") puts Sw.pos PU TS Sw.rewind #基类 class Writerdecorator def initialize (real_writer) @real_writer = Real_writer End def WRI Te_line @real_writer. Write_line End def POS @real_writer. Pos End def Rewind @real_writer. Rewind E nd def close @real_writer. Close End Class Numberingwriter < Writerdecorator Attr:line_number de F Initialize (Real_writer) Super (real_writer) @line_number = 1 End #实际调用的是WriterDecorator的write_line方法, only in the written Pre-add number (decoration) #所以说NumberingWriter对WriterDecorator的接口wirte_line进行了装饰 # def write_line (line) @real_writer. Write_line ( "#{@line_number}:#{line}") @line_number + + 1 End sw = simplewriter.new (" numbering_write.txt ") NW = numberingwriter.new (SW) Nw.writ 
 E_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_lin E (line) line.each_byte{|byte| @check_num + + byte% 256} @real_writer. Write_line (line) End-SW = Simplewrit Er.new ("Check_num_writer.txt") CSW = checksummingwriter.new (sw) csw.write_line ("Hello,world") puts Csw.check_num cl Ass Timestampingwriter < Writerdecorator def initialize (real_writer) super (Real_writer) End Def Write_li NE (line) @real_writer. Write_line (' #{time.now}: #{line} ') End #倒着看 #5. The actual call is the Simplewriter Write_line method, which writes the contents to the file SW = simplewriter.new ("Mix.txt") #4. The actual call is the Numberingwriter Write_line method, the input of the data before the number # and then passed to @real_writer, at this time @real_witer for sw NW = NumberiNgwriter.new (SW) #3. The actual call is the Timestampingwriter Write_line method, the input of the data before the timestamp # then passed to @real_writer, at this time @real_witer for NW TSW = Timestampingwriter.new (NW) #2. The actual call is the Checksummingwriter Write_line method, the input data to the number of bytes of statistics # and then passed to @real_writer, at this time @real_witer for tsw CSW = Checksummingwriter.new (TSW) #1. 
 CSW calls Write_line csw.write_line ("Hello,world") puts Csw.check_num

Two ruby-style decorative pattern applications

(1) using extend to infiltrate the module

Class Simplewriter 
 def initialize (path) 
  @file = File.Open (Path, "w") 
 end 
 
 def write_line (line) 
  @ File.print (line) 
  @file. Print ("\ n") End 
 
 #字符数 
 def POS 
  @file. Pos End 
 
 # It will point the file pointer at the beginning of the file 
 def Rewind 
  @file. Rewind End 
 def close 
  @file. Colse 
 
#使用extend方法动态的混入模块 to decorate the 
 
module Timestampingwriter 
 def write_line (line) 
  super ("#{time.now}": #{line} ") 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 last module that is joined is called first, and then the Write_line method of the parent class is called through Super.
In the example, precede the text with a timestamp, add the number, and then write the file

SW = simplewriter.new ("Out3.txt") 
sw.extend (numberingwriter) 
sw.extend (timestampingwriter) 
Sw.write_ Line ("Hello,ruby") 


(2) using 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 
 
 #字符数 
 def POS 
  @file. Pos End 
 
 # It will point the file pointer at the beginning of the file 
 def Rewind 
  @file. Rewind End 
 def close 
  @file. Colse 
 
 
another dynamic way for Ruby to implement a decorative pattern is to 
modify an instance method of an object, so the timestamp is added to the Out1.txt file without affecting the timestamp in the object sw2,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") 

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.