2011-02-09 4 views
7

두 가지 구성 방법 중 하나를 기반으로 새 인스턴스를 작성하기 위해 팩토리 메소드를 넣으려는 클래스가 있습니다. 메모리의 데이터로 구성 할 수 있거나, 또는 파일에 저장된 데이터. 내가하고 싶은 무엇Ruby의 클래스 인스턴스 인스턴스 초기화 프로그램 (즉, 팩토리 메소드)

는 건설이 클래스 내에서 수행되는 방법의 논리를 캡슐화하는 것입니다, 그래서 나는 다음과 같이 설정되어 정적 클래스 메소드 싶은 :

class MyAppModel 
    def initialize 
     #Absolutely nothing here - instances are not constructed externally with MyAppModel.new 
    end 

    def self.construct_from_some_other_object otherObject 
     inst = MyAppModel.new 
     inst.instance_variable_set("@some_non_published_var", otherObject.foo) 
     return inst 
    end 

    def self.construct_from_file file 
     inst = MyAppModel.new 
     inst.instance_variable_set("@some_non_published_var", get_it_from_file(file)) 
     return inst 
    end 
end 

이 거기를 메타 프로그래밍 (instance_variable_set)에 의지하지 않고 클래스 자체의 클래스 인스턴스에 @some_private_var를 설정할 방법이 없습니까? 이 패턴은 인스턴스에 메타 - 파킹 변수를 요구하기에는 너무 비밀스럽지 않은 것처럼 보입니다. MyAppModel 외부의 클래스가 some_published_var에 액세스 할 수 있도록 허용하지 않으므로 예를 들어 사용하고 싶지 않습니다. attr_accessor - 그냥 뭔가를 놓친 것 같아요 ...

답변

9

아마도 "생성자"를 사용하여 인스턴스를 만들지 않으려면 원하는 것을 달성하는 더 나은 방법 일 수 있습니다.

class MyAppModel 
    class << self 
    # ensure that your constructor can't be called from the outside 
    protected :new 

    def construct_from_some_other_object(other_object) 
     new(other_object.foo) 
    end 

    def construct_from_file(file) 
     new(get_it_from_file(file)) 
    end 
    end 

    def initialize(my_var) 
    @my_var = my_var 
    end 
end 
+1

이것은 매우 훌륭하고 관용적입니다. – Chuck

+0

고마워, 이건 내가하고 있었던 것보다 훨씬 더 깨끗하다고 ​​생각해. - 여전히 많은 것들을 생성자에 전달하는 것을 포함하지만, 어쨌든 그것은 보호되어 있기 때문에, 큰 문제는 아니며 instance_variable_set보다 훨씬 낫다. – Matt

관련 문제