Tbpgr Blog

Recruiting Operations tbpgr(てぃーびー) のブログ

書籍 Refactoring to Patterns | Creation | Inline Singleton

パンくず

書籍 Patterns to Patterns
Creation
Inline Singleton

概要

Inline Singletonのリファクタリングについて

使用する場面

Singletonitisは、Singletonパターンを適用することと定義します。
Singletonの目的はインスタンスが一つしかないことを保証し、
グローバルで一箇所からしかアクセスさせないようにすることです。

しかし不要なSingletonが存在する場合がある。
どうやって不要とみわけるか?

短い答えはほぼ全て
長い答えは、Singletonはオブジェクトへの
リソースの参照をよりシンプルにする場合、不要である。

対応方法

SingletonをInline化する

利点と欠点

利点

・オブジェクトの連携を可視化し、強制する。
・一つのインスタンスを守るのに特殊なコードを必要としない

欠点

・多くのレイヤーを通してインスタンスを生成してる場合、設計を複雑にする

手順

これらのリファクタリングはInline Classによる。
Singletonをのインライン化を受け入れる一つのクラスをabsorbing classとします。

1.absorbing classクラスにSingletonのpublicのMethodを宣言する。

2.Singletonを利用しているすべての箇所をabsorbing classを利用するように変更する。

3.Move MethodとMove Fieldを用いてSingletonからabsorbing classに適用する。

4.Singletonを削除する

サンプル

リファクタリング
# encoding: Windows-31J

require 'singleton'
class Alone
	include Singleton
	def increment
		@count = @count.succ
	end
	def initialize
		@count = 0
	end
end

class Client
  def call_singleton
    alone1=Alone.instance
    alone2=Alone.instance

    puts alone1.increment
    puts alone2.increment
  end
end

Client.new.call_singleton
リファクタリング
# encoding: Windows-31J

class Alone
	def increment;@count = @count.succ;end
	def initialize;@count = 0;end
end

class Client
  attr_accessor:alone
  def call_singleton;2.times {puts instance.increment};end
  def instance;return @alone = (@alone.nil? ? Alone.new : @alone);end
end

Client.new.call_singleton
共通の出力
1
2

関連

Move Method
Move Field
Singleton