부풀린 GUI 코드 작성을 피하는 가장 좋은 방법은 무엇입니까?


48

GUI 코드로 작업 할 때마다 코드가 다른 종류의 코드보다 빠르게 팽창하는 경향이 있습니다. 또한 리팩토링하기가 더 어려워 보입니다. 다른 종류의 코드에서는 꽤 쉽게 리팩터링 할 수 있습니다. 대규모 클래스를 더 작은 기능으로 분해 할 수 있습니다. 대부분의 GUI 프레임 워크를 사용하면 위젯 / 컨트롤 / 클래스가 필요한 프레임 워크에 바인딩됩니다. 위젯 / 컨트롤 / 무엇이든 더 많은 것을 직접 구현하십시오. 때때로 이것은 (a) 일부 기본 위젯 / 컨트롤 / 물리를 상속하거나 (b) 보호 된 메소드에 액세스해야하기 때문입니다.

또한 일반적으로 예를 들어 사용자와 상호 작용하는 모든 모드를 구현하기 위해 프레임 워크의 신호 / 이벤트 / 무엇을 통해 다양한 입력에 응답해야합니다. 다음과 같은 다양한 입력 / 출력을 처리하기 위해 하나의 GUI 위젯 / 컨트롤이 필요할 수 있습니다.

  1. 오른쪽 클릭 / 컨텍스트 메뉴
  2. 상황에 맞는 메뉴에서 선택한 항목에 반응
  3. GUI를 그리는 특별한 방법
  4. 키보드 입력에 반응
  5. 버튼, 체크 박스,

... 항상 비즈니스 로직을 나타내는 GUI에서 클래스를 관리하십시오.

간단한 직관적 GUI는 비즈니스 로직을 분리하고 MVC를 사용할 때에도 코드가 매우 빠르게 커질 수 있으므로 GUI 코드가 큰 변화를 가져옵니다.

GUI 코드를 깔끔하게 관리하고 깨진 창으로 만들지 않도록하는 방법이 있습니까? 또는 GUI 이벤트에 가장 많은 랜덤 이벤트 핸들러 / 재정의 된 메소드가 실제로 최선입니까?


4
"bloat"에 대한 정확한 정의는 무엇입니까?

답변:


36

GUI 코드에 대해 기억해야 할 것은 이벤트 중심적이며 이벤트 중심적 코드는 항상 무작위로 구성된 수많은 이벤트 처리기처럼 보일 것입니다. 이벤트가 아닌 코드를 클래스에 삽입하려고 할 때 정말 혼란스러워집니다. 물론 이벤트 핸들러를 지원하는 것처럼 보이며 이벤트 핸들러를 작고 작게 유지할 수는 있지만 추가 지원 코드가 떠 다니면 GUI 소스가 부풀어지고 지저분 해 보입니다.

그렇다면 이것에 대해 무엇을 할 수 있으며, 어떻게 리팩토링하기 쉽게 만들 수 있습니까? 글쎄, 나는 때때로 리팩토링에 대한 나의 정의를 때때로 내가하는 일에서 내가 코딩 할 때 지속적으로하는 일로 바꿀 것이다. 왜? 리팩토링을 사용하면 코드를 더 쉽게 수정할 수 있기 때문에 다른 방법은 아닙니다. 여기서 의미를 변경하도록 요청하는 것이 아니라 코드를 다르게 보려면 약간의 정신 미용을 수행하도록 요청합니다.

내가 가장 일반적으로 사용하는 세 가지 리팩토링 기술은 Rename , Extract MethodExtract Class 입니다. 하나의 다른 리팩토링을 배운 적이 없다면이 세 가지 코드를 사용하여 코드를 깨끗하고 체계적으로 유지할 수 있으며 질문 내용에서 거의 동일한 리팩토링을 거의 사용하는 것처럼 보일 것입니다. GUI 코드를 얇고 깨끗하게 유지하십시오.

세계에서 GUI와 비즈니스 로직을 최대한 분리 할 수 ​​있지만 GUI 코드는 중간에 폭발 한 코드처럼 보일 수 있습니다. 내 조언은 GUI를 올바르게 관리하는 데 도움이되는 추가 클래스 또는 2 개가 없어지는 것이 아니라 MVC 패턴을 적용하는 경우 반드시 View 클래스 일 필요는 없다는 것입니다. 중급 클래스는 사용자의 관점과 매우 유사하므로 편의를 위해 클래스를 병합해야하는 경우가 많습니다. 이것에 대한 나의 취지는 모든 시각적 논리를 관리하기 위해 GUI 특정 계층을 추가하는 것이 실제로 아프지 않다는 것입니다.

그러므로 나의 충고는 :

  • GUI가 View (또는 중개 계층)에 연결되는 방법을 호출하고 정의하는 것 외에는 GUI 바로 뒤에는 아무것도하지 마십시오.
  • 모든 뷰 관련 사항을 GUI 클래스 당 단일 클래스 또는 GUI 클래스 당 단일 클래스로 분류하려고 시도하지 않는 것이 좋습니다. 대안은 GUI 로직을 관리하기 위해 작고 관리하기 쉬운 클래스를 많이 만드는 것입니다.
  • 메소드가 4-5 줄의 코드보다 조금 더 크게 보이기 시작하면 이것이 필요한지 여부와 클래스를 의미하더라도 메소드를 간결하게 유지할 수 있도록 메소드를 추출 할 수 있는지 확인하십시오. 더 많은 방법으로.
  • 클래스가 실제로 크게 보이기 시작하면 복제 된 기능을 모두 제거하여 시작한 다음 다른 클래스를 추출 할 수 있도록 메소드를 논리적으로 그룹화 할 수 있는지 확인하십시오.
  • 한 줄의 코드를 작성할 때마다 리팩토링을 고려하십시오. 작동하는 코드 줄을 얻는 경우 기능 복제를 피하기 위해 리팩터링 할 수 있는지 또는 동작을 변경하지 않고 조금 더 좁힐 수 있는지 확인하십시오.
  • 불가피하게, 특히 시스템의 일부 또는 다른 부분이 약간 부풀어 오르기 시작한다는 느낌이들 것입니다. 특히 리팩토링을 무시할 때 더욱 그렇습니다. 잘 짜여진 코드 기반이 있어도 할 수있는 일 이 더있는 것처럼 느낄 있습니다. 이것은 소프트웨어 작성의 현실이며, 더 많은 것이 "더 나은"일을 할 수 있다고 항상 느끼게되므로 전문적인 업무 수행과 금도금 사이의 균형을 잡아야합니다.
  • 깔끔하게 코드를 작성하고 유지할수록 코드의 부풀어 짐이 줄어 듭니다.

3
+1 좋든 싫든, GUI는 복잡한 세부 작업을 처리하며 코드를 의미합니다.
Patrick Hughes

개발자는 GUI에 이벤트 중심 코딩을 사용하는 방법을 배워야합니다.
David Gao

23

나는 당신이 겪고있는 많은 문제가 단순한 원인으로 되돌아 갈 수 있다고 생각합니다. 대부분의 개발자는 GUI 코드를 '실제'코드처럼 취급하지 않습니다. 나는 여기에 증거 나 통계가없고 단지 내 직감도 있습니다.

어쩌면 그들은 그것이 ' 단순한 프레젠테이션 '이며 중요하지 않다고 생각할 수도 있습니다. ' 비즈니스 로직이 없다 '고 그들은 왜 단위 테스트를해야 합니까? 객체 지향을 언급하고 깨끗한 코드를 작성할 때 웃습니다. 그들은 일을 더 잘하기 위해 시도조차하지 않습니다. 시작할 구조가 없으며 코드를 때리고 다른 사람들이 시간이 지남에 따라 자신의 손길을 가할 때 썩게합니다. 아름다운 혼란, 낙서 코드.

GUI 코드에는 고유 한 문제가 있으므로 다르게 취급해야합니다. 그것을 쓰고 싶은 사랑과 개발자가 필요 합니다. 그것을 얇게 유지하고 좋은 구조와 올바른 패턴을 줄 것입니다.


2
GUI 코드가 아닌 코드와 다르게 취급되는 GUI 코드에 대한 인식으로 +1 "GUI를 테스트하는 데 비용을 들이지 않고 그렇게하기가 어렵 기 때문에 GUI 테스트를 귀찮게하지 마십시오"라고 말한 횟수를 잃어 버렸습니다. 나는 보통 "어려워서 그것을하는 법을 배우기에는 너무 게으르다!"라고 번역합니다.
S.Robins

1
+1 내가 일하는 곳에서는 종종 GUI 코드를 검토하지 않습니다. "GUI 일뿐입니다. 건너 뛰십시오". 그리고 나는 다른 사람만큼 유죄입니다. 이상한 것은 개인 프로젝트에서 깔끔한 GUI 코드를 얻으려고 많은 시간을 보낸다는 것입니다. 그것은 단지 문화적인 것 같아요.
HappyCat

8

어떤 이유로 GUI 코드는 개발자의 우려 분리에 대한 사각 지대를 만듭니다. 모든 자습서가 모든 것을 하나의 클래스로 묶기 때문일 수 있습니다. 아마도 물리적 인 표현은 사물을 실제보다 더 밀접하게 결합시켜 보이기 때문일 수 있습니다. 어쩌면 클래스가 느리게 구축되어 사람들이 천천히 열을 올리면서 잠언 개구리가 끓는 것처럼 리팩토링이 필요하다는 것을 인식하지 못하기 때문일 수 있습니다.

이유가 무엇이든, 해결책은 수업을 훨씬 작게 만드는 것입니다. 나는 내가 타이핑하는 것을 별도의 클래스에 넣을 수 있는지 지속적으로 나 자신에게 묻음 으로써이 작업을 수행합니다. 다른 수업에 참여할 수 있고 해당 수업에 대한 합리적이고 간단한 이름을 생각할 수 있다면 그렇게합니다.


6

Model View Presenter / Passive View 패턴을 살펴볼 수 있습니다. Ray Ryan은 Google IO에서 GWT의 최상의 아키텍처 사례에 대해 좋은 대화를 나 gave습니다.

http://www.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html

아이디어를 다른 프레임 워크와 언어로 쉽게 추출 할 수 있습니다. MVP의 주요 이점은 (제 생각에) 단위 테스트 가능성입니다. 그리고 부 풀지 않고 스파게티가 아닌 코드 (질문으로 판단하면 이것이 원하는 것) 만 얻을 수 있습니다. 발표 자라는 뷰 논리 계층을 도입하여 작동합니다. 실제 뷰는 인터페이스를 통해 이로부터 분리되므로 단위 테스트에서 쉽게 조롱 할 수 있습니다. 이제 뷰 로직 계층 (발표자)이 구체적인 GUI 프레임 워크의 내부에서 제거되었으므로 일반 코드처럼 구성 할 수 있으며 예를 들어 Swings 상속 계층 구조에 묶여 있지 않습니다. 이상적으로 동일한 인터페이스를 따르는 한 다른 프레임 워크에서 GUI 구현을 전환 할 수 있습니다.


1
+1. MVP는 GUI 로직을 별도의 클래스로 추출하는 방법에 정확하게 중점을 두는데, 이는 종종 MVC에 대해 사람들이 이해하는 것과는 상당히 다릅니다.
Doc Brown

5

내 대답은 구조, 단순성, 테스트 및 구문의 네 부분으로 구성됩니다.

처음 세 사람은 정말로하기가 어렵습니다!

구조 는 최소량의 코드와 최대량의 프레임 워크, 라이브러리 등을 사용하는 데 많은주의를 기울이는 것을 의미합니다.

단순성 은 초기 설계에서 실제 구현에 이르기까지 단순하게 유지하는 것을 의미합니다. 간단한 플러그인을 사용하여 탐색을 단순하게 유지하고 레이아웃을 '일반'으로 유지하면 여기에 도움이 될 것입니다. PC, ipad, 모바일 및 기타 장치에서 작동하는 페이지의 장점을 빠르게 볼 수있는 클라이언트 / 사용자에게 '판매'될 수 있습니다.

코드의 빈번한 '패칭'과는 달리 처음에 더 나은 코드를 처리 할 수있을 때 더 나은 코드를 설계 할 수있는 경우 브라우저 간 문제를 미리 파악하는 브라우저 테스트 도구 (webrat 및 capybara가 레일 작업에 영향을 미침)를 포함한 테스트 수단 다른 브라우저의 사용자가 '발견'하는 다른 개발자의

통사론. HTML, CSS, Javascript 등을 위해 코드 검사기 / IDE / 편집기 플러그인 등을 사용하는 것이 정말 도움이됩니다. 브라우저가 다른 브라우저와 다르게 작동하는 경우 잘못된 형식의 HTML 작업을 처리 할 수있어 브라우저가 얻는 이점 HTML 형식을 확인하는 도구가 필수적입니다. 잘못된 코드는 더 많은 가시성을 가져야하므로 HTML이 제대로 구성되어 있으면 부풀어 오른 HTML을 만드는 데 매우 도움이됩니다.


4

내가 찾은 해결책은 선언적 코드입니다. 절차 코드 만 사용하면 스파게티 GUI 코드를 만들 수 있습니다. 물론 "위젯을 그리는 특별한 방법"은 아마도 코드로 남아있을 것입니다. 그러나 이것은 클래스에서 분리 된 코드입니다. 이벤트 처리기, 키보드 단축키, 창 크기-지저분한 모든 것이 가장 잘 선언됩니다.


4

여기에 많은 훌륭한 답변이 있습니다.

GUI 코드를 단순화하는 데 도움이 된 한 가지는 GUI에 자체 데이터 모델이 있는지 확인하는 것입니다.

간단한 예를 들어, 4 개의 텍스트 입력 필드가있는 GUI가있는 경우 4 개의 텍스트 입력 필드의 내용을 유지하는 별도의 데이터 클래스가 있습니다. 더 복잡한 GUI에는 더 많은 데이터 클래스가 필요합니다.

GUI를 모델로 디자인했습니다. GUI 모델은 애플리케이션 모델-보기-컨트롤러의 애플리케이션 컨트롤러에 의해 제어됩니다. 응용 프로그램보기는 GUI 코드 자체가 아니라 GUI 모델입니다.


2

워드 프로세싱, 그래픽 편집기 등과 같은 응용 프로그램에는 복잡한 인터페이스가 있으며 코드는 단순 할 수 없습니다. 그러나 비즈니스 응용 프로그램의 경우 GUI가 그렇게 복잡 할 필요는 없지만 여전히 몇 가지가 있습니다.

GUI를 단순화하기위한 몇 가지 키는 다음과 같습니다 (대부분 .NET에 적용).

  1. 가능할 때마다 더 단순한 디자인을 위해 노력하십시오. 사업체가 요구하지 않는 경우 멋진 행동을 피하십시오.

  2. 좋은 컨트롤 제공 업체를 사용하십시오.

  3. 클라이언트 코드 자체에서 사용자 정의 제어 기능을 작성하지 마십시오. 대신 사용 양식 / 페이지의 코드가 아닌 컨트롤에 특정 동작을 반영 할 수 있도록 원래 컨트롤을 확장하는 사용자 컨트롤을 만듭니다.

  4. 모든 UI에서이 코드를 반복하지 않도록 국제화, 자원 관리, 스타일 등을 처리하기 위해 프레임 워크 (집에서 재배 한 것까지)를 사용하십시오.

  5. 탐색을위한 구성 요소 (또는 프레임 워크)를 사용하십시오.

  6. 오류, 경고, 확인 등에 대한 표준 대화를 작성하십시오.


1

코드 및 UI 개발에 객체 지향 디자인을 적용하십시오.

  1. 별도의 프리젠 테이션 및 모델 MV에 관계없이 라이브러리 / 프레임 워크를 사용하거나 직접 작성하여 데이터 모델과 뷰 / 컨트롤러 로직을 분리 할 수 ​​있습니다. 백엔드와의 모든 통신은 모델 내부에서 수행해야하며 모델 상태는 항상 백엔드와 동기화되어 있어야합니다.
  2. 디커플링 객체 A가 객체 B에 대해 알고있는 경우 A는 B에서 메소드를 호출 할 수 있지만 B는 A에 대해 알아야합니다. 대신 A는 B의 이벤트를 수신 할 수 있습니다. 순환 종속성이 없는지 확인합니다. 앱에 구성 요소간에 많은 이벤트가있는 경우 EventBus를 만들거나 Twitter Flight와 같은 이벤트 중심 프레임 워크를 활용하십시오.
  3. 부분 대 전체 렌더링 보기가 테이블 또는 항목 목록 인 경우 "add", "remove"와 같은 메소드를 작성하여 하나의 항목을 컬렉션에 삽입 / 삭제할 수 있습니다. 정렬 및 페이지 매김을 지원해야 할 때 코드가 쉽게 부 풀릴 수 있습니다. 그래서 내 충고는 : 부분 변경이 있더라도 단순히 전체보기를 다시 렌더링하십시오. 성능은 어떻습니까? 컬렉션이 크면 어쨌든 페이지 매김을해야합니다. 웹 개발자 : 이벤트 핸들러가 변경되지 않는보기의 루트 요소에 위임되었는지 확인하십시오.
  4. 뷰 모델 뷰의 상태가 유지하기에 너무 복잡해지면 (예 : 테이블 뷰는 행 데이터, 열 데이터, 정렬 순서, 현재 확인 된 행 (다중 검사를 지원하는 경우) 등)를 추적해야합니다. 해당 상태에 대한 ViewModel 객체를 만듭니다. UI에서 무언가가 변경되면 View 객체가 ViewModel에서 setter를 호출해야합니다 (예 : 사용자가 행을 확인). UI를 업데이트하여 ViewModel의 변경 이벤트에 응답해야합니다. 일반적으로 변경 이벤트가 UI에 의해 트리거되는 경우 UI 업데이트를 피해야합니다.

여기 내 요점 중 일부를 설명하는 데 도움이되는 작지만 사소한 응용 프로그램이 있습니다. https://github.com/vanfrankie/pushpopbox 에서 코드 및 뷰 / 모델 상호 작용 다이어그램을 찾을 수 있습니다.


0

"databinding" 개념을 보려고합니다 . 모델 요소가 UI의 컨텐츠와 자동으로 동기화되도록 UI 요소를 선언적 방식으로 추상 모델 요소에 연결하는 방법입니다. 예를 들어, 데이터를 동기화하기 위해 이벤트 핸들러를 직접 작성할 필요가없는 등이 방법에는 많은 이점이 있습니다.

많은 UI 프레임 워크 (예 : .NETEclipse / JFace)에 대한 데이터 바인딩 지원이 있습니다 .

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