2015-01-18 2 views
0

기본 로거에서로드하고 몇 가지 방법을 추가하여 일부 구문 설탕을 가질 수있는 Log 클래스가 있습니다. 문제는 Logger가 파일 위치를 얻고 Info (구성 옵션, 상수 등)라는 모든 정보의 중심 위치 역할을하는 다른 클래스에서 log.progname 이름을 가져 오는 것입니다.Ruby 데 커플 링 클래스 도움이 필요합니다.

Log 클래스를 재사용 가능하게 만들고 싶어서 문제가됩니다. 비헤이비어를 변경하지 않고 Info 클래스에서 Log 클래스를 분리하는 방법은 무엇입니까?

내 클래스는 현재 다음과 같습니다

class Log 
    F = File.open(Info[:logfile], 'a') 
    F.sync = true 
    @l = Logger.new(F).tap do |log| 
     log.progname = Info[:short_name] 
    end 
    class << self 
     def set_level(level) 
     @l.level = Logger.const_get level.upcase 
     end 

     def display(message, level) 
     puts message unless level == :fatal 
     end 

     def []=(level,message) 
     case message.class.to_s 
      when 'String' 
      display message, level 
      @l.send level, message 
      when 'Array' 
      message.each do |line| 
       display line, level 
       @l.send level, line 
      end 
      when 'Hash' 
      message.each do |level,line| 
       display line, level 
       @l.send level, line 
      end 
     else 
      raise TypeError, "method expects Hash,String or Array, message was of type #{message.class}" 
     end 
     end 


    end 

    end 

내가 생각할 수있는 유일한 방법은 그때 나는, 하지만 ID를 초기화하는 경우에 값을 패스 복제 된 개체에 싱글에서이 변환하는 것입니다 오히려 그것을 싱글 톤으로 유지하십시오, 그래서 어떤 제안을 해주시겠습니까?

내가 정말로 묻고있는 것은이 수업을 다른 수업에서 어떻게 분리하고 더 중요한 것은 앞으로 어떻게 할 것인가에 대한 조언이라고 생각합니다.

답변

0

아마도 싱글 톤이 필요하지 않습니다. 여기 당신이 할 수있는 것입니다 :

class MyLogger 
    def initialize(info) 
    @file = File.open(info[:logfile], 'a') 
    @file.sync = true 
    @l = Logger.new(F).tap do |log| 
     log.progname = info[:short_name] 
    end 
    end 

    # ... 
end 

Log = MyLogger.new(Info) 

# Now you can inject info and even have multiple logs 
Log2 = MyLogger.new(Info2) 

이에 대한 또 다른 좋은 점은 로그인 대신 클래스가로드 될 때 당신이를 열기 때문에 나쁜 일이 될 수있는 그것을 초기화하는의 초기화 될 때 제어 할 수 있다는 것입니다 파일.

+0

유일한 방법은 인스턴스가있는 개체로 전환하는 것입니다. – Thermatix

+0

나는 이것이 유일한 방법은 아니라고 말하고있다. 그러나 제 의견으로는 가장 좋습니다. –

+0

이 접근법을 사용하면 싱글 톤을 사용하면서 얻은 이점을 잃지 않으며 싱글 톤 사용의 단점도 없습니다. –

관련 문제