Design Patterns in Ruby [Digest 8] Adapter

The Adapter is just like the power adapter such as from 220V to 120V. And when the pin does not fit the socket we need the adapter to fit it.

In software system, we already have a Encrypter to encrypt file:

 

class Encrypter
  def initialize(key)
    @key = key
  end
  def encrypt(reader, writer)
    key_index = 0
    while not reader.eof?
      clear_char = reader.getc
      encrypted_char = clear_char ^ @key[key_index]
      writer.putc(encrypted_char)
      key_index = (key_index + 1) % @key.size
    end
  end
end

 

 

reader = File.open('message.txt')
writer = File.open('message.encrypted','w')
encrypter = Encrypter.new('my secret key')
encrypter.encrypt(reader, writer)

 

And when we want to encrypt a string and we cannot change the Encrypter, we can use the Adapter Pattern:

 

class StringIOAdapter
  def initialize(string)
    @string = string
    @position = 0
  end
  def getc
    if @position >= @string.length
      raise EOFError
    end
    ch = @string[@position]
    @position += 1
    return ch
  end
  def eof?
    return @position >= @string.length
  end
end

 

 

encrypter = Encrypter.new('XYZZY')
reader= StringIOAdapter.new('We attack at dawn')
writer=File.open('out.txt', 'w')
encrypter.encrypt(reader, writer)

 

In ruby we can just modify the class or the instance to implement adapter like requirement.

modify class:

 

 

require 'british_text_object'
# Now add some methods to the original class
class BritishTextObject
  def color
    return colour
  end
  def text
    return string
  end
  def size_inches
    return size_mm / 25.4
  end
end

 

modify instance:

 

bto = BritishTextObject.new('hello', 50.8, :blue)
class << bto
  def color
    colour
  end
  def text
    string
  end
  def size_inches
    return size_mm/25.4
  end
end

 

 

If you modify the original class or object, you do not need the additional adapter class, nor do you need to worry about wrapping the adapter around the adaptee. Things just work. And yet the modification technique involves serious encapsulation violations: You just dive in and start changing things.

 

 

As usual, a pinch of pragmatism seems best. Lean toward modifying the class in the following circumstances:

• The modifications are simple and clear. The method aliasing we did earlier is a prime example of a simple, crystal-clear modification

• You understand the class you are modifying and the way in which it is used. Performing serious surgery on a class without taking a hard look at the class beforehand is probably going to lead to grief.

 

Lean toward an adapter solution in the following situations:

• The interface mismatch is extensive and complex. For example, you probably would not want to modify a string to look like a Fixnum object.

• You have no idea how this class works. Ignorance is always cause to tread lightly

 

The example of Adapter Pattern in Ruby is ActiveRecord database apis:

 

ActiveRecord has to deal with the fact that it needs to talk to a whole crowd of different database systems: MYSQL and Oracle and Postgres, not to mention SQLServer.

All of these database systems provide a Ruby API—which is good.

But all of the APIs are different—which is bad.

 

ActiveRecord deals with all of these differences by defining a standardized interface,

encapsulated in a class called AbstractAdapter. The AbstractAdapter class

defines the interface to a database that is used throughout ActiveRecord.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值