필드 대 메서드 인수 [닫기]


9

방금 새 클래스를 작성하기 시작했으며 엄격하게 필요하지 않은 많은 메소드 인수를 추가하고있었습니다. 이것은 일반적인 구성이나 클래스의 종속성이 아닌 일부 메소드 호출에 특정한 클래스의 상태를 피하는 습관을 따릅니다.

그렇게하면 인수를 가질 수없는 많은 메소드가 1, 2 또는 3으로 끝납니다.

이 트레이드 오프에 대해 어떻게 생각하고 어떤 상황에서 어떤 접근법을 취할지 결정하는 방법에 대한 귀하의 의견을 듣고 싶습니다.

코드를 설명 할 때 코드가 영어보다 이해하기 쉬운 경우가 많으므로 https://gist.github.com/JeroenDeDauw/6525656


로컬 변수 (객체의 수명 동안 전역이 아닌)로만 사용되는 인수는 의미가있는 한 범위 내에 있어야합니다 ... 개발자가 인스턴스가 아닌 상태를 인스턴스 상태로 저장할 때 매우 자극적입니다. 편리합니다 ...하지만 제 의견입니다. 실행 흐름이 실제로 어떤지보기가 어렵습니다.
Max

메소드를 실행하는 동안 매개 변수를 사용하고 클래스가 상태를 변경해야하는지 여부를 처리하게함으로써 "tell do n't ask" 원칙에 맞습니다. 그냥 물어 보지 않는에게 당신이 상태 (약 개체 쿼리 할 수 없습니다 의미하지 않는다는 것을 명심 노골적인 플러그 )
마르 얀 Venema의

답변:


2

예제에서 외부에서 볼 수있는 유일한 방법은 updateTable이므로 메서드 매개 변수 대신 필드를 사용하는 것이 좋습니다.

이것이 더 일반적인 클래스 (예 :)의 일부 TableTools이면 상태가 필요한 도우미 메서드를 숨겨진 내부 클래스로 옮길 것입니다.

의사 코드 예 :

class TableTools {
    ...
    public void updateTable(currentTable, newTable) {
        TableUpdater u = new TableUpdater(schemaModifier, currentTable, newTable);
        u.removeRemovedFields();
        u.addAddedFields();
     }

     private class TableUpdater { ... }
}

이렇게하면 하나의 공용 메소드에서만 사용되는 필드를 피할 수 있습니다. 또한 updateTable을 호출 할 때마다 고유 한 TableUpdater와 TableUpdater의 인스턴스 변수 복사본을 사용한다는 점에서 코드는 스레드로부터 안전합니다.


7

필드를 사용하면 해당 필드를 사용하는 메소드에 멀티 스레딩을 사용할 수 있습니다.

이와 같은 필드를 사용하는 것은 재사용 성 및 유지 관리 성 관점에서 글로벌을 사용하는 것보다 약간 더 낫습니다. 여기서 중요한 점은 복잡한 설정에 어떤 방법을 사용하고 어떤 필드를 클로버하는지에 대한 신중한 최신 문서가 필요하다는 것입니다. 인수를 사용할 때 할 필요가없는 것.


Multhithreading은 PHP와 마찬가지로 사용 사례와 관련이 없습니다. 필드가 사용되는 방식이 사소한 것이 아니라면이 방법이 나쁘다는 데 동의합니다. 이 경우에는 유일한 공개 방법으로 만 작성 (항상 작성)됩니다. 나는 이것이 문제를 일으킬 것으로 예상하지 않는다. 이와 같은 분야는 세계보다 약간 더 나은 분야에 관해서는, 나는 당신이 무엇을 의미하는지 잘 모르겠습니다. 정교하게 할 수 있습니까?
Jeroen De Dauw

7

평신도의 말로 :

  • 메소드는 가능한 한 적은 인수를 가져야합니다 (Martin 's Clean Code)
  • 객체의 기능 중 하나는 상태를 가질 수있는 것보다
  • 객체의 상태에서 작동하지 않는 정적이 아닌 메소드, 즉 모든 것을 매개 변수로 수신하는 것은 응집력이 없습니다.
  • 비 응집성 메소드는 유틸리티 클래스에서 정적 및 그룹화 될 수 있습니다.

다시 말하지만, 겸손한 견해로는 비 응집 방식은 유틸리티 클래스에 속하며 도메인 이름을 가진 클래스에는 속하지 않습니다.


1

현재 사례에서 필드를 사용하지 마십시오! 객체를 동시에 사용하는 두 개의 "스레드"는 서로를 혼동합니다. 그것들은 실제 별도의 스레드 일 필요는 없습니다 (따라서 따옴표). 한 테이블에 대해 개체를 설정 한 다음 다른 테이블에 사용하는 메서드를 호출 한 다음 원래 설정을 사용하려고하면 문제가 있습니다. 순간에 대한 매개 변수를 고수하십시오.

당신이 원하는 여기서 뭘하는 것은 하나의 경우에 사용되는 새로운 Updater 클래스를 만드는 것입니다. 원래 클래스에는 필요할 때마다 인스턴스를 만드는 메서드가있을 수 있습니다. 새로운 클래스에는 필드가 있습니다. 당신은 두 세계의 최고를 가지고 있습니다. 때로는 매개 변수를 사용하는 것이 더 간단하지만 예제에서는 이미 별도의 클래스가 더 나은 곳으로 향하고 있습니다.


0

선택은 실제 상황에 따라야한다고 생각합니다. 항목이 인스턴스에 속하는 경우 해당 필드로 표시되어야합니다. 항목이 인스턴스 외부에 있으면 메소드 매개 변수로 전달되어야합니다.

이 경우 우리는 입력의 효과 성 (어쨌든 차이는 중요하지 않음) 또는 (God save!) 용이성이 아니라 코드의 이해 성과 자연성에 따라 안내되어야합니다.


0

내 생각에 뭔가 무언가를 하는 코드를 작성 하는 경우 수행해야 할 작업을 정의하는 매개 변수를 사용해야하며 그 이름은 가능한 한 정의해야합니다.

당신은 최대 패키지 그 코드를 작성하는 경우 동작이 뭔가 수행 할 다음은 객체에 수행해야 할 일을 마무리하고 일에 통과해야한다 무언가를 .

그런 다음 이 작업 은 첫 번째 방법에 대한 호출에 대한 일종의 메타 설명이되어 나중에 큐에 넣거나 나중에 어떤 이유로 든 수행하지 않을 수 있습니다.

그래서 당신의 질문 은 그것이 행동 입니까 아니면 기능 입니까? 액션 연기되거나 취소되고, 따라서이에 작용하는 것을 캡슐화한다 할 수있다. 기능이 필요 상단이 매개 변수를 보존하지가 있으므로 즉시 발생합니다.

실행 취소작업 은 할 수 있지만 기능 은 할 수 없습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.