Show () + Hide () 또는 SetVisible (bool visible)이 더 낫습니까?


59

무엇이 더 좋고 왜? (인터페이스 디자인 관점에서) :

A) 두 가지가하려면 Show()Hide()기능을

b) 하나의 SetVisible(bool visible)기능 을 가지려면

편집 : 예를 들어 일부 객체에는 가시성 상태가 있으며이 기능은 객체를 변경하는 데 사용됩니다.

C) 세하도록하려면 Show(), Hide(), SetVisible(bool visible)기능을


4
어떤 맥락에서? 일반적으로 중요하지 않습니다
Aviv Cohn


6
왜 모두 공개하지 않습니까? 항상 표시되거나 숨겨지는 경우가 있으며 조건부로 표시하거나 숨기고 싶은 경우가 있습니다.
pllee

@ pllee : 아마 아주 좋은 지적입니다.
user3123061

4
Java에서는 대문자로 시작하지 않고 setVisible, hide 및 show가 설정됩니다.
Pierre Arlaud

답변:


81

다음 SetVisible(bool visible)과 같은 클라이언트 코드를 작성할 수 있기 때문에 선호 합니다.

SetVisible(DetermineIfItShouldBeVisible());

쓰지 말고

if (DetermineIfItShouldBeVisible()) {
    Show();
} else {
    Hide();
}

SetVisible접근법은 또한 더 쉬운 구현을 허용 할 수있다. 예를 들어, 특정 구체적 클래스가 단순히 메소드를 복합 클래스에 위임하면 SetVisible구현할 메소드가 하나 줄어 듭니다.

void ButtonWithALabel::SetVisible(bool visible) {
    myButton.SetVisible(visible);
    myLabel.SetVisible(visible);
}

25
마찬가지로, 언어가 지원한다고 가정 할 때 Visible을 속성으로 만들 수도 있습니다. MyObject.Visible = false;훨씬 더 직관적 인 이상 나를 파업MyObject.SetVisible(false);
브라이언

9
@Brian 저에게는 읽기 쉽고 디버깅하기가 쉽지 않습니다. 프로그램 동작을 내 눈에 숨기고 있기 때문입니다. 기본 메소드 호출입니다. 그러나 그것은 또 다른 이야기입니다. 자바는 그 구문을 지원하지 않는다. 어쨌든 그것은 선호와 눈 훈련의 문제이다.
ignis

10
SetVisible()실제로 나에게 표시하고 있다고 제안하지는 않습니다. 객체의 가시성 속성을 설정하는 것과 비슷하게 읽혀 지므로 객체를 표시하거나 숨길 지 여부를 결정하기 위해이 속성의 값을 확인 하는 해당 Refresh()또는 Redisplay()메서드로 남겨 둘 수 있습니다.
TMN

1
불행히도 Java는 C #과 같은 속성을 지원하지 않으며 위에서 본 getter 및 setter 만 지원합니다.
theGreenCabbage

1
@TMN : 가시성을 방해하는 다른 요소가 없으면 (Z 순서, 부모 가시성, 위치 등) setVisible(true)동작하지 않고 시스템이 다음에 유휴 상태 일 때 객체가 그려지는 프로세스가 동작 할 것으로 예상합니다 . 그 기대 refresh객체의 표시를 촉진하는 것이 유용 할 수 있지만 객체는 결국 (예를 들어하지 않는 가시성이로 설정에 관계없이 그려 얻을 것이라는 점을 false그 발생하기 전에).
supercat

35

동일한 기능을 수행하는 여러 기능이 좋은 것이라고 제안하는 모든 포스터에 동의하지 않습니다. 하나가 아닌 세 가지 기능이 훨씬 팽창처럼 보이지 않을 수도 동안, 당신의 클래스가 많은 그런 기능 (예 :로 끝날 가능성이 있다는 사실을 setEnabled, enable, disable로 끝날 것이다) 따라서이 방법 훨씬 더 큰 수준의 인터페이스를 제공합니다. 또한 클래스에서 비슷한 소리 기능 / 속성 / 무엇으로 끝나고 함수를 곱하면 어느 것이 무엇과 관련되는지 더 모호해질 수 있습니다.

속성을 지원하는 언어에서는 이것이 선호되어야하지만 Java 나 C ++은 그렇게하지 않기 때문에 그 논점이라고 생각합니다.

setVisible()다음과 같은 이유로 선호되어야 한다고 생각 합니다.

  1. 역함수가 무엇인지 즉시 알 수 있습니다. 반대로 setVisible(false)전화를 거는 setVisible(true)반면 반대는 hide()쉽게 할 수 있습니다 reveal().
  2. 코드에서 어떤 상태를 취해야 할지를 결정할 때마다 프로그래밍 방식으로 간단합니다. 즉 setVisible(wantToSee), if명령문을 사용하지 않고 호출 할 수 있습니다 .
  3. 유사한 함수가 여러 개 있으면 setX()형식이 일반화되어 일관된 함수 세트를 사용할 수 있습니다. 반면 verbed 방식은 원하는 것을 모르는 경우 찾기 어려운 여러 함수를 생성합니다. API의 일관성으로 인해 배우고 기억하기가 훨씬 쉽습니다.

3
C ++에는 속성이 없지만 무료 함수가 있으므로 새 멤버 함수를 추가하지 않고 클래스 인터페이스를 확장 할 수 있습니다 (예 : 커플 링 수준이 낮음).
phresnel

Qt는 신호 / 슬롯 시스템을 사용하여 hide () 및 show ()를 다른 이벤트에 직접 연결할 수 있도록 편의상 세 가지를 모두 제공합니다. 이것은 실제로 슬롯 시스템의 한계입니다. boost :: functions와 같은 것을 사용하는 경우 콜백을 설정할 때 true / false 인수가 바인딩 될 수 있습니다.

1
"속성을 지원하는 언어에서는이 언어를 선호하지만 Java 나 C ++ 모두 그렇게하지 않기 때문에 이것이 요점이라고 생각합니다." 반드시 그런 것은 아닙니다. 게터 / 세터보다 선호합니까? 예. 그러나 set_visible은 실제로 세터가 아닙니다.
Miles Rout

19

그것은 어떤 표시 및 숨기기에 따라 의미 맥락에서. 먼저 어떤 방법이 "주된 방법"인지 파악하고이를 개발하는 데 집중하십시오.

  • 선택해야 할 이유 setVisible(bool)
    • 단순한 비트 플립이거나 객체가 주로 상태를 유지하고 있습니다.
    • 당신의 객체는 CRUD 프레임 워크에서 대부분의 시간을 보낼 것입니다
    • 표시와 숨기기 사이에 쉽게 공유되는 코드가 많이 있습니다
  • 고른 이유 show()hide()
    • 오브젝트가 모든 컨테이너 가시성 상태를 확인하거나 전환 애니메이션을 트리거해야하는 경우와 같이 중요한 부작용이나 많은 로직이 실행되고 있습니다 .
    • 의도를 표현 하는 것이 중요한 도메인 모델의 일부입니까?

자, 이제 "골드 표준"코어를 코딩 했으므로 다른 스타일의 얇은 편의 방법을 추가하여 객체를 사용하려는 사람이 더 쉽게 생활을 할 수 있는지 여부를 알아 내야합니다.

  • 편의성 setVisible(bool)
    • 당신은 사소한 조건이 만 가시성에 영향을 미칠 경우 명령문 방지 할 수 있습니다 (예를. setVisible(a==b))
    • 특정 getter / setter 프레임 워크에 연결될 수 있습니다.
  • 편의성 show()hide()
    • 일류의 기능과 콜백와 언어에 유용한 (예. onSuccess(widget.show))
    • 프로그램이 무엇을하려고했는지 빠르게 볼 수 있기 때문에 스택 추적 및 성능 프로파일 링으로 훨씬 쉽게 읽을 수 있습니다.

TLDR : 어느 것이 가장 중요한지 찾아서 구현 한 다음 다른 스타일을 간단한 편의 방법으로 추가 할 가치가 있는지 자문 해보십시오.


11

나는 "세 가지"라고 말할 것입니다.

Show()그리고 Hide()보다 grok 수 쉽게하는 경향이 SetVisible(true)SetVisible(false). 그러나 가시성을 논리적으로 설정 bool하려면 if주변을 구성하는 대신 메소드를 사용하는 것이 좋습니다 bool.

중복되는 로직과 최소 상용구없이 세 가지를 모두 지원할 수 있습니다.

void Show() {
    foo.Show();
    bar.Show();
}

void Hide() {
    foo.Hide();
    bar.Hide();
}

void SetVisible(bool visible) {
    if (visible) {
        Show();
    } else {
        Hide();
    }
}

또는 줄 바꿈하는 것들에 더 SetVisible-ish API가있는 경우 :

void Show() {
    SetVisible(true);
}

void Hide() {
    SetVisible(false);
}

void SetVisible(bool visible) {
    foo.SetVisible(visible);
    bar.SetVisible(visible);
}

40
Microsoft는이 방법을 사용하여 시작 및 중지 System.Windows.Forms.Timer합니다. 개인적으로, 나는 이것이 혼란 스럽습니다. 모두 내가 볼 때 ShowSetVisible, 나의 첫번째 성향은 두 기능 사이에 몇 가지 중요한 차이가 궁금합니다.
Brian

1
혼란을 없애기 위해 쉽게 문서화 할 수 있습니다. 나는 이것이 간단한 예가 아니었다.
Garry Shutler

20
수업에 익숙해지기 전에 문서를 읽는 데 X 분을 더 소비해야합니까? 아니면 혼란스러워하거나 버그를 도입하는 데 X 분을 더 낭비해야합니까? 물론, X는 이런 종류의 경우 꽤 작지만 확실히 0은 아닙니다. 3 가지 옵션을 모두 제공한다는 것은 필요한 것보다 3 배 많은 기능을 제공한다는 것을 의미합니다. 즉, 더 많은 작업 문서를 작성하고 수업 사용 방법을 배우는 데 더 많은 작업을하게됩니다. 또한 수업을 사용할 때 다른 개발자가 일관되지 않는 방법을 하나 더 소개합니다.
Brian

5
이는 SOLID 원칙 중 하나 인 인터페이스 분리 원칙을 위반하는 것입니다. 당신의 접근 방식에 대한 또 다른 의견은 netbeans의 디자이너 인 jaroslav tulach의 의견이며, 그의 책 실용적인 API 디자인에서 API 내에서 한 가지 작업을 수행 할 수있는 유일한 방법을 제공해야한다고 주장합니다.
AlfredoCasado

@AlfredoCasado 동의합니다. SetVisible이 보호 된 경우 어떻게해야 합니까? 서브 클래스에서 액세스 할 수 있지만이 인터페이스 (예 : API)를 사용하여 지정된 엔티티를 호출하면 숨기기 / 표시가 필요합니다.
Pierre Arlaud

5

실제로 show () 및 hide ()를 선호합니다. 실제로 하나의 부울을 수신하는 모든 메소드는 API의 의도를 더 잘 표현하는 두 가지 메소드로 변경할 수 있습니다. 예를 들어 깨끗한 코드의 Robert Martin은 인수가 하나 인 메소드보다 인수가없는 메소드를 선호합니다.

저에게 또 다른 중요한 주장은 가독성입니다. 제 의견으로는 좋은 코드는 산문처럼 읽을 수 있습니다. "main_window hide"대신 "main_window setVisible false"와 같은 이상한 산문이 있습니다. 완벽하게 가능할 때 소프트웨어 프로그램의 언어 구성이 더 자연스런 언어를 사용합니까?


1
어셈블러가 충분하지 않습니까?
Alexander

시퀀스 it.setVisible(false); it.setVisible(true);가 컨트롤의 부모의 가시성에 영향을 주어서는 안되며 컨트롤의 Z 순서 또는 위치에 영향을 미치지 않아야합니다. 대조적으로 hide(); show(); 컨트롤의 부모를 눈에 잘 띄게하고 다른 컨트롤 위로 옮기고 볼 수있는 위치로 위치를 제한 할 수 있습니다. 어떤 경우에는 무언가가 실제로 보이는지 확인하는 방법을 사용하는 것이 유용합니다 (앞서 언급 한 것처럼 show()) 그러나 다른 경우에는 변경 하지 않고 가시성 플래그 변경하는 것이 유용합니다 .
supercat

객체 지향 API에는 "플래그"가 없으며, OO는 메시징에 관한 것이며, 객체 상태는 "플래그"를 변경하는 것이 아니라 다른 객체에게 일부 작업을 지시합니다. 제어, 부모, z 순서 및 다른 API에 대한 이전 경험에서 아마 기대하는 것에 대해 많은 가정을하고 있습니다. 도메인에 대한 개인적인 감정과 가정을 기반으로 API를 설계하는 것은 매우 나쁜 생각입니다.
AlfredoCasado

5

방법이 표현이 많을수록 코드를 더 읽기 쉽고 결과적으로 유지 관리 할 수 ​​있다고 생각합니다. 다음 두 가지 경우를 고려하십시오.

사례 1 :

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  customerPanel.setVisible(customer.isCustomerEnabled());
}

사례 2 :

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  //always show customer panel
  customerPanel.setVisible(true);
}

첫 번째 경우, "setVisible"함수가 무엇을하고 있는지는 분명하지만, 읽으려면 다음과 같이 말하십시오.

고객이 사용 가능한 경우 고객 패널을 표시하도록 설정하거나 고객이 사용 불가능한 경우 숨겨 지도록 설정하십시오.

더 설명하기는 쉽지만 :

  • 고객 상태를 확인하십시오.
    • 고객이 활성화 된 경우 고객의 패널을 표시합니다
    • 그렇지 않으면 숨기십시오

"Case 1"기능이 다음과 같이 변경됩니다.

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  if(customer.isCustomerEnabled()){
    customerPanel.Show();
  }
  else{
    customerPanel.Hide();
  }
}

더 많은 코드를 생성하지만 더 읽기 쉽습니다.

두 번째 경우에는 명백한 결함이 있습니다. 즉, 이미 패널을 표시하려고한다는 것을 알고 있으므로 "표시"기능을 사용하지 않겠습니까?

"setVisible"을 사용하는 것이 절대적으로 잘못되었다는 말은 아니지만 시간이 지남에 따라 사용자가 작성하지 않은 코드를 읽으려고 할 때 혼란스럽고 "함수는 한 작업 만 수행해야합니다"규칙을 따르지 않습니다.


나는 말할 것이다 : show customer panel iff the user/customer is enabled. 나는 당신의 예제만큼 더 복잡한 조건이 읽기 쉽지 않을 수도 있다는 데 동의하지만, 그러한 경우 조건을 다른 줄로 나눌 것입니다.
ComFreek

5

나는 Hide()/ Show()대안이 매력적 이라고 생각합니다. SetVisible(true)왜냐하면.

이 경우 열거 형을 입력으로 사용하는 것이 좋습니다 . SetVisible따라서 SetVisible(Visibility.Visible)또는 을 얻습니다 SetVisible(Visibility.Hidden). 수행중인 작업을 즉시 읽을 수있는 단일 기능이 있습니다.

Java의 명명 규칙을 사용하면 setVisible(Visibility.VISIBLE)또는을 가질 수 setVisible(Visibility.HIDDEN)있습니다.


3

Darien의 답변에 동의하지만 C # 프로그래머 관점에서 관점을 추가하고 싶었습니다.

'setXXX'라고 표시된 코드를 볼 때 물건에 값을 설정하고 있다고 말하는 것을 읽었습니다.이 값을 설정하는 것 외에는 부작용이 없을 것으로 예상됩니다. (즉, 동일한 값으로 계속 설정할 수 있으며 괜찮습니다). 오히려 필드에 액세스하는 것과 같습니다. 일반적으로 나는 'setXXX'와 함께 'getXXX'방법을 볼 것으로 기대합니다.

이것이 Java 및 C ++에서 기대하는 것인지는 모르겠지만 C #에서는 C #에서 기대하는 것입니다 .C #에서는이 속성에 대한 짧은 손이 있습니다. 그리고 다음은 속성 사용 방법에 대한 유용한 지침입니다 ( http://msdn.microsoft.com/en-us/library/ms182181.aspx ).

이 관점에서 내가 선택한 인터페이스는 부작용이 있는지 여부에 따라 전적으로 의존합니다 (필드 값 변경 제외).

작업을 수행하는 데 부작용이있는 경우 (예 : 대화 상자가 표시되는 경우) "Show ()"및 "Hide ()"로 이동합니다.

부작용이 없다면 "위젯"의 가시성을 설정하고 다른 상태에 따라 위젯을 렌더링한다고 가정하면 setVisibility 또는 setIsVisible을 사용합니다. (나는 그것을 SetVisible이라고 부르지 않을 것이다).

C # (Java에 대해 잘 모르겠 음)에서는 UI 프레임 워크가 객체의 변경 사항을 수신하고 가시성 같은 속성이 변경 될 때 UI를 자동으로 다시 렌더링하는 관찰자 패턴을 채택하는 것이 일반적입니다. 즉, setIsVisible을 호출하여 값을 설정하면 부작용이있는 것처럼 보이지만 내 정의에는 그렇지 않습니다. 위젯의 계약은 "IsVisible"을 나타내는 필드 값을 설정하여 이행됩니다.

달리 말하면, 폼이 표시되기 전에 폼에서 레이블의 가시성을 토글해도됩니다. 즉 label.getIsVisible == true이지만 양식이 표시되지 않습니다.

양식이 표시되지 않을 때 Hide ()를 호출하는 것은 좋지 않습니다.


1
부작용없이 필드에 액세스 할 수있는 방법에 대한 설명 getXXX()setXXX()방법은 C #이 아닌 Java와 비슷 합니다. 이것은 속성이 없기 때문에 Java에서 해야하는 방법 입니다. C #에서 이와 같은 코드를 본다면 아직 C #의 속성에 대해 배우지 않은 Java 개발자가 작성한 것 같습니다.
gilly3

일에 대한 SetVisibility.
akaltar

@ gilly3-물론입니다. 그리고 "속성"은 CLR에 존재하지 않으며 C #은 IL에서 메소드 호출 get_XXX 및 set_YYY로 변환됩니다. 내 요점은 : 질문의 맥락에서 자바에서 setXXX, getXXX를 보았을 때 C #의 속성과 동일한 의미로 작동한다고 기대할 것입니다. 사실이므로 C #의 속성에 대한 동일한 지침이 Java의 setXXX 및 getXXX 쌍에 적용될 수 있다고 생각합니다. 나는 게시물에서 참조하는 지침에 동의하기 때문에 인터페이스를 정의 할 때 Java 에서이 시나리오에서 사용하기 위해 동일한 지침을 옹호합니다.
Daniel James Bryars

1
"부작용"을 의미 할 때 " '관찰 할 수있는 것"과 관련된 것 이외의 것을 의미한다는 것을 명확히하는 데 도움이 될 수 있습니다. 내가 선호하는 규칙은 getXX호출에 해당하는 setXX메소드 가있는 경우 해당 메소드에 setYY영향을 미치지 않아야하지만 메소드 getZZ가없는 호출에는 영향을 줄 수 있다는 setZZ것입니다.
supercat

2

약간 수정 된 인터페이스를 제안합니다.

Show();
Hide();
ToggleVisible();
ToggleVisible(bool visible);

더 나은 이름

이 메소드 이름은 개발자가 수행해야 할 작업에 따라 사용할 메소드를 결정하는 데 도움이됩니다. 반면이 SetVisible(bool visible)그것과 동일한 의미의 의미를 전달하기 때문에 현상을 혼동하게 Show()하고 Hide(), Toggle()행동을 결정하는 조건의 존재를 의미한다. 따라서 각 방법을 사용할 때 개발자에게 직관적이됩니다.

코드 중복 감소

인터페이스에 여러 메소드를 사용하면 호출 코드를 단순화 할 수 있다는 이점이 있습니다. 당신은 노출 수 Show()Hide()있지만 :

  • 당신은 아마 어떤 종류의 필요 것 SetVisible()배후에서 실제 작업을 수행하는 개인 방법 (또는에 대한 중복 코드를 작성 Show()하고 Hide()).
  • 호출 코드에는 사용할 메소드를 선택하기 위해 많은 중복 if / else 블록이있을 수 있습니다. 내 의견으로는 코드가 부풀어 오른다.
  • 내가 소비자라면 코드 팽창을 피하기 위해 이미 수행 하는 작업 SetVisible()(또는 Toggle()) 을 수행하는 자체 래퍼 함수를 ​​작성했을 것입니다 (중복 코드가 싫어). 따라서 구현에서 이미 개인용 메소드로 존재 하는 메소드를 복제합니다 .

1
방법 중복은 합리적으로 들리지만 직접하지는 않습니다. 반면, toggleVisible (bool)이 직관적이라는 데 동의하지 않습니다. 나에게 그것은 부울에 전달 된 것이 사실이라면 토글해야한다는 것을 의미합니다. 그것이 실제로 변장에 설정된 기능이라고 가정하지는 않습니다.
Patrick M

0

SetVisible(bool)가시성을 두 번 토글 (표시 및 다시 숨기기 또는 숨기기 및 다시 표시)하는 경우 작업을 수행하기 전과 본질적으로 동일한 상태로 물건을 남길 경우에만 사용 하는 것이 좋습니다 (표시 및 다시 숨기면 괜찮습니다) 무언가 또는 그 반대의 경우 "자동으로"발생할 것으로 예상되는 경우 다시 그리기가 필요한 객체를 남깁니다. 객체를 숨기고 표시하는 것이 1 비트의 상태를 변경하는 것 외에는 아무런 영향을 미치지 않으면 가시성 매개 변수를 허용하는 일부 메서드를 사용하는 것이 외부 코드에 적합하며 이러한 코드를 쉽게 작성할 수 있습니다 SetVisible.

개체를 숨기고 다시 표시하면 Z 순서 변경과 같은 부작용이있을 수있는 경우 별도의 방법으로 이러한 작업을 수행해야합니다. 이러한 경우 "가시성"매개 변수를 허용하는 외부 메소드의 유용성이 제한되므로이를 용이하게하는 이점이 거의 없습니다. 또한, SetVisible방법은 부작용없이 객체의 가시성에 대한 변경이 이루어질 수 있다고 제안합니다.

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