2

D3.js를 학습하면서 blog post을 통해 재사용 가능한 코드 단위의 기본 디자인 패턴을 설명했습니다. 아래 관련 코드를 다시 작성했습니다. 패턴이 아래에 제시된 방식은 D3 코드베이스 및 플러그인 (example)에서 사용되는 것과 정확히 같습니다.리팩터링 방법을 찾고 있습니다. D3.js 스타일의 메소드 체인 패턴

이 코드와 관련된 한 가지 문제점은 속성에 대한 복사 붙여 넣기가 너무 많다는 것입니다. JavaScript는 함수형 언어이므로 상용구 코드를 다시 고려할 수있을 것이라고 생각했지만 어떻게해야 할 지 생각할 수 없습니다. argumentsvalue 매개 변수는 일반적인 함수로 전달하기가 쉽지만 widthheight 속성에 대한 참조를 유지할 수있는 방법을 찾을 수 없습니다.

function chart() { 
    var width = 720, // default width 
     height = 80; // default height 

    function my() { 
    // generate chart here, using `width` and `height` 
    } 

    my.width = function(value) { 
    if (!arguments.length) return width; 
    width = value; 
    return my; 
    }; 

    my.height = function(value) { 
    if (!arguments.length) return height; 
    height = value; 
    return my; 
    }; 

    return my; 
} 

이 (재 인수 분해가 가능한 경우 궁금한데,하지만 난 그게이 높은 우선 순위 문제가 없다는 문제가 단순히입니다 바라고, 그것이 실제 D3 코드베이스에 어떻게하는지이라는 사실 새로운 기여자는 이전에 어떻게했는지에 따라 이런 식으로하고 있습니다.

나는 기본적으로 모든 접근의 신체를 대체 무엇을 찾고 있어요 :

my.height = function(value) { 
    return getSet(arguments, value, whatever); 
}; 

이 호출에 대한 몇 가지 상용구가 여전히 있지만 적어도 논리가 중앙 집중식이며, 단 한 곳에서 업데이트 할 수 있습니다, 필요한 경우.

+0

정확히 무엇을 찾으십니까? 당신이 php의 "마법"getter/setter와 같은 것을 원한다는 것을 들린다. 어떤 속성을 돌보거나 가져 오거나 설정하는 단일 함수. 그럴까요? – bfavaretto

+0

@bfavaretto이 질문을 명확히하기 위해 업데이트되었습니다. –

+0

흠, 아마도 [this] (http://stackoverflow.com/a/543820/825789)와 같은 것이 필요할 것입니다. – bfavaretto

답변

1

getSetchart의 범위로 정의하면 닫힌 변수를 너무 많이 액세스하게됩니다. 문제는, 당신이 어떤 종류의 eval을 사용하지 않는다면, 당신은 이름 문자열에 의해 변수에 접근 할 수 없다는 것입니다.

당신은 검증되지 않은 객체의 모든 개인 변수를 포장하여 해당을 피할 수 :

function chart() { 
    var props = { 
     width: 720, // default width 
     height: 80 // default height 
    } 

    function my() { 
     // generate chart here, using `width` and `height` 
    } 

    my.height = function(value) { 
     // Call getSet with current my instance as this, 
     // 'height' as the first argument, then value 
     return getSet.apply(this, arguments.slice().unshift('height')); 
    }; 

    // Works just like your current accessors, on the props object 
    function getSet(property, value) { 
     if (arguments.length > 1) return props[property]; 
     props[property] = value; 
     return this; 
    } 

    return my; 
} 

문제는이 각 속성에 대한 몇 가지 유사한 접근을 쓰는 것보다 훨씬 더 짧은하지입니다. 현재 접근하는 사람들은 사설 변수를 사실상 공개합니다. 왜 그런 변수를 사용하지 않고 공용 변수를 사용하는 것이 좋을까요?

+0

단순히 공개 변수가 아닌 이유는이 패턴의 전체적인 점은 메소드 체인을 가능하게하는 것입니다. public vars를 사용하면 chart.height = 33과 같은 값을 얻을 수 있습니다.이 값은 체인 연결을 끊습니다.또한 args.slice() 부분이 작동하지 않으며 (그런 메소드가 없음) 사용자의 의도가 확실하지 않습니다. –

+0

이제 코드에 실수가있는 것을 봅니다. 그러나 D3에 익숙하지 않아서 지금 무엇을 제안해야할지 모르겠습니다. D3 코드베이스에서 어떻게 수행되는지 예제를 통해 설명해 주시겠습니까? – bfavaretto

+0

OP에 예제 링크가 있습니다. 해당 문서의 하단 부분은 "rollup.whateverXYZ"형식과 같은 함수로 가득합니다. 보시다시피 모두 복사하여 붙여 넣기 만하면됩니다. –

0

이미 제공되는 대체 솔루션은 함수를 반환하는 '속성'함수를 정의하는 것입니다. 나는 소스가 실제로 마이크 Bostock 생각 (하지만 난 원래 게시물에 대한 링크를 찾을 수 없습니다)

을 -

function chart() { 
    chart.width = property.call(chart, 500); 
    chart.height = property.call(chart, 500); 

    chart.render = function() { 
    //render logic goes here 
    }; 

    return chart; 
} 

나는이에 대한 전체 신용을 할 수 없습니다

function property (v) { 
    return function (_) { 
    if(!arguments.length) 
      return v; 
     v = _; 
    return this; 
}; 
} 

그래서 당신은 말할 수

많은 모듈에서이 '속성'기능을 사용합니다. 많은 성가신 타이핑을 저장합니다. 들어오는 값이 변경되면 이벤트를 내보내도록 쉽게 늘릴 수 있습니다.

관련 문제