最近讀書會在讀深入淺出設計模式,趁這個機會複習一下設計模式,試著舉出簡單的例子並且用非模式與模式的方式來實作,比較它們的差異與優缺點。
我們有一個 log 輸出系統會將 log 輸出個一個檔案之中,它有下面的功能:
class Logger
def initialize
@counter = 0
do_heavy_work
end
def write(msg)
@counter += 1
p "Write #{msg} to log ..."
end
def count
@counter
end
private
def do_heavy_work
p "Do heavy work..."
end
end
logger = Logger.new
logger.write('Hello')
logger.write('Hi')
p logger.count
class A
def initialize
@logger = Logger.new
end
def say(msg)
@logger.write(msg)
p msg
end
end
a = A.new
a.say('Yoooo~~')
p logger.count # 2
class Logger
def self.gen
@@instance
end
private_class_method :new
def initialize
@counter = 0
do_heavy_work
end
def write(msg)
@counter += 1
p "Write #{msg} to log ..."
end
def count
@counter
end
private
def do_heavy_work
p "Do heavy work..."
end
@@instance = new
end
logger = Logger.gen
logger.write('Hello')
logger.write('Hi')
p logger.count
class A
def initialize
@logger = Logger.gen
end
def say(msg)
@logger.write(msg)
p msg
end
end
a = A.new
a.say('Yoooo~~')
p logger.count # 3
class Logger
@@instance = nil
def self.gen
@@instance = @@instance || new
end
private_class_method :new
def initialize
@counter = 0
do_heavy_work
end
def write(msg)
@counter += 1
p "Write #{msg} to log ..."
end
def count
@counter
end
private
def do_heavy_work
p "Do heavy work..."
end
end
logger = Logger.gen
logger.write('Hello')
logger.write('Hi')
p logger.count # 2
class A
def initialize
@logger = Logger.gen
end
def say(msg)
@logger.write(msg)
p msg
end
end
a = A.new
a.say('Yoooo~~')
p logger.count # 3
class Logger
@@instance = nil
def self.gen
instance_mutex = Mutex.new
instance_mutex.synchronize do
@@instance = @@instance || new
end
end
private_class_method :new
def initialize
@counter = 0
do_heavy_work
end
def write(msg)
@counter += 1
p "Write #{msg} to log ..."
end
def count
@counter
end
private
def do_heavy_work
p "Do heavy work..."
end
end
Singleton - 獨體模式
當某個 class (Logger) 只需要單一 instance 時,使用 private 的 contructor(Logger.new) 來限制 instance 的建立,取而代之的是使用另一個 class method (Logger.gen) 並搭配 class variable(@@instance) 來確保只有唯一個 instance 會被建立。要特別注意的是在多執行緒下的同步問題。
當某個 class 只需要單一 instance,而且在初使化的過程可能會花費較多的資源而希望可以減少初使化的次數。