프로그램을 여러 클래스로 나누는 것이 좋은 이유는 무엇입니까? [닫은]


62

저는 여전히 고등학교 (10 학년 입학) 학생이며 학교에서 실제 컴퓨터 과정을 수강하지 않았습니다. 내가 지금까지 한 모든 일은 책을 통해서입니다. 그 책들은 상속과 같은 개념을 가르쳐 주었지만 프로그램을 여러 클래스로 나누는 것이 어떻게 도움이됩니까? 책은 나에게 말하지 않았다.

나는 최근 프로젝트 때문에 주로 이것을 묻습니다. 아케이드 비디오 게임입니다. 일부 사람들이 말했듯이 플래시 게임과 같습니다 ( 플래시 게임 이 무엇인지 전혀 모르겠지만 ). 문제는 단 하나의 클래스입니다. 단 하나의 클래스로 완벽하게 작동합니다 (그러나 때때로 약간의 지연이 있습니다). 그래서 나는 그것을 여러 클래스로 나누는 것이 어떻게 도움이되는지 묻고 있습니다.

이 프로젝트는 자바로 이루어졌으며 레코드 작업을 수행하는 유일한 사람입니다.


1
소프트웨어의 각 부분을 더 단순하게 만들기 위해! infoq.com/presentations/Simple-Made-Easy-QCon-London-2012
TehShrike

49
책을 읽을 때 장과 섹션으로 나누어 져 있습니까? 우리는 책이 사물을 정리하기 위해 장을 나누는 것처럼, 프로그램을 수업으로 나눠 사물을 정리합니다.
riwalk

12
로마인들은 '분열과 임페라'라고 말했었다.
조르지오

7
@Giorgio : 또는 영어로 라틴어가 더 이상 사용되지 않기 때문에 : Divide And Conquer .
Matthieu M.

40
10 학년을 고려하고 이미 지능적인 질문을 작성하여 정답, 상황 및 상대 경험을 제공하는 데 필요한 모든 세부 사항과 질문을하는 이유에 대한 배경 정보를 제공 할 수 있습니다. 당신은 이미 제가 현재 일하고있는 많은 사람들보다 더 자격이 있습니다 ...
CaffGeek

답변:


71

가장 간단한 대답은 모든 것을 하나의 클래스에 넣을 경우 새 코드를 작성할 때 모든 것에 대해 한 번에 걱정해야한다는 것입니다. 소규모 프로젝트에서는 효과가 있지만 수십만 줄의 거대한 응용 프로그램에서는 불가능합니다.

이 문제를 해결하기 위해 일부 기능을 자체 클래스로 분류하고 모든 논리를 캡슐화합니다. 그런 다음 수업에 참여하고 싶을 때 코드에서 진행중인 다른 작업에 대해 생각할 필요가 없습니다. 작은 코드 조각에만 집중할 수 있습니다. 이는 효율적으로 작업하는 데 매우 중요하지만 규모가 큰 응용 프로그램에서 작업하지 않고는 이해하기 어렵습니다.

물론 코드를 더 작은 조각으로 나누면 얻을 수있는 또 다른 이점이 있습니다. 코드는 유지 관리 가능하고 테스트 가능하며 재사용이 가능합니다. 그러나 가장 큰 이점은 코드 양을 줄임으로써 대규모 프로그램을 관리 할 수 ​​있다는 것입니다. 한 번에 생각해야합니다.


7
프로그래밍 (OO 원칙, 분산 소스 제어, 코딩 표준)의 많은 개념 / 아이디어는 팀에서 비교적 큰 프로젝트를 수행 할 때만 의미가 있습니다. 실제로 그러한 프로젝트를 수행 할 때 이유를 이해할 수 있습니다.
joshin4colours

40
그것은 지적 가치의 단지 여러 클래스로 프로젝트를 깨는 / 파일에 큰 도움이되지 않습니다. 정말로 중요한 것은 독립적 인 클래스를 갖는 것이므로, 하나의 클래스를 변경하는 것은 프로그램에 대해 다른 것을 알 필요가 없습니다 (그리고 클래스를 사용하는 것은 구현 방법에 대한 지식이 필요하지 않습니다). 많은 클래스가있는 코드를 자주 보지 만 실제 캡슐화가 없기 때문에 이것을 가져옵니다. 캡슐화는 중요한 부분입니다. 달성 방법은 세부 사항입니다.
복구 상태 Monica

2
일부 핵심 단어는 "커플 링"또는 "디커플링", "캡슐화", "정보 숨기기"입니다.
marktani

@BrendanLong, 나는 또한 캡슐화가 거의 불가능하다는 것에 동의합니다. 물론 별도의 프로그램을 작성하지 않는 한 ... 그러나 일반적으로 서로 의존하지 않지만 의존성을 공유하는 부분이 많이 있습니다.
Jo So

29

가장 간단한 대답은 "사물 정리에 도움이됩니다"입니다. 다른 것이 없다면 노트북의 섹션과 비교할 수 있습니다. 여기에 "UI와 관련된 모든 것"과 "게임 플레이와 관련된 모든 것"이 있으면 훨씬 간단합니다.

더 복잡한 대답은 작업을 나누는 것이 편리 할뿐만 아니라 복잡성을 관리하는 데 매우 중요하다는 것입니다. "복잡성 관리"는 프로그래밍과 관련하여 게임의 이름과 거의 같습니다. 클래스 또는 다른 유형의 모듈을 사용하면 "별도의 우려"를 가질 수 있습니다. "UI 관련 항목"을 찾을 위치를 알고있을뿐만 아니라 UI를 변경하려는 경우 한 곳에서 변경할 수 있으며, 그럴 필요는 없습니다. "지금은 폰트를 Comic Sans로 설정 한 유일한 곳입니까?" 또한 변경을 수행 할 수 있으며 해당 변경의 영향이 적절한 범위 (소규모)에만 있다는 것을 알 수 있습니다. 모든 것이 단일 클래스 또는 모듈에 있다면 본질적으로 모든 것이 전역 적입니다.

특정 유형의 소프트웨어 모듈 유형의 ​​클래스에는 클래스와 관련된 많은 동작이 있으며, 객체 지향 패러다임의 대부분의 개발자는 그룹 관련 클래스와 관련된 의미있는 이름을 갖는 것이 매우 도움이된다는 것을 알게됩니다 함께 작동합니다. 따라서 실제로 UI수업 이 없을 수도 있고 수업이있을 수도 있습니다 Button. 객체 지향 클래스 디자인과 관련된 모든 지식과 기술이 있으며 주류 프로그래밍에서 대규모 시스템을 구성하는 가장 일반적인 방법입니다.


12

이것은 좋은 질문입니다! 간단하고 잘 부탁드립니다. 글쎄 ... 대답은 컴퓨터 과학을 공부하고 있고 깊은 OO를 모르거나 경험이없는 학생에게는 이해하기 쉽지 않습니다.

따라서 시나리오를 설명하고 멀티 클래스 소프트웨어가 모 놀리 식 소프트웨어보다 나은 방법을 상상해 낼 수 있습니다 (하나의 클래스로만 제작).

  • 가독성 : 작고 체계적인 여러 파일보다 10000 줄의 파일 내에서 코드를 찾아보고 쓰는 것이 훨씬 어렵습니다.
  • 재사용 성 : 단일 클래스를 작성하는 경우 코드 중복에 빠질 수 있습니다. 이것은 더 많은 코드 줄과 더 많은 버그를 의미합니다 (!)
  • 테스트 가능성 : 단일 기능 테스트는 어떻습니까? 한 클래스에서 하나의 논리 기능을 분리하면 인생이 더 쉬워집니다.
  • 코드 유지 관리 : 한곳에서 여러 클래스로 버그를 수정하거나 기능을 향상시킬 수 있습니다. 멋진 작은 클래스.
  • 프로젝트 구조 : oooooh 하나의 소스 파일 만있는 프로젝트가 얼마나 못 생겼는지 상상할 수 있습니까?

나는 당신의 대답을 좋아하고 방금 변경했습니다 (여전히 동료 검토가 필요합니다). 내가 놓친 요점은 SVN / GIT와 같은 소프트웨어 버전 관리 시스템의 변경 사항을 쉽게 감지하는 것입니다. 또한 하나의 프로젝트에서 여러 프로그래머와 병렬로 작업하는 것이 더 쉽습니다.
Martin Thoma

우려, 응집 및 분리의 분리는 OOP의 규율보다 훨씬 높은 범위에있는 개념이라고 말할 수 있습니다. 명령형, 논리적 및 기능적 프로그래머 모두 높은 응집력과 낮은 결합을 위해 노력합니다.
sara

8

여기에 좋은 대답이 많이 있으며, 나는 그들에 분명히 동의하지만 언급 할 가치가 더 있다고 생각합니다.

지금까지 말한 것처럼 프로젝트에서 혼자 작업하고 있습니다. 그러나 앞으로는 팀 환경에서 작업해야 할 때가 있습니다. 이 기간 동안 작업을 분할하게됩니다 (아마도 프로젝트가 상당히 클 것입니다). 결과적으로 몇 가지 (실제로 두 가지 주요한 ) 다른 옵션이 있습니다. 하나의 파일 사본을 여러 개 가질 수 있으며 파일의 개별 "조각"에 대해 작업 한 다음 나중에 복사하여 붙여 넣어 "결합"한 다음 부분이 함께 작동하도록 수정하거나 "조각"을 분할 할 수 있습니다 다른 수업에 쉽게 참여하고 해당 수업을 어떻게 작성할 것인지에 대해 토론 하고 그 지식을 활용하여 진행하십시오.

모든 분리 된 부분을 통합하기위한 작업이 여전히 필요하지만 유지 관리가 훨씬 쉬울 것입니다. x 파일에는 y 코드가 포함되어 있으며 수정해야 할 코드입니다. 이것은 대부분의 다른 답변에 대해 이야기하는 조직에 적용됩니다.

프로그램을 머리 속에 들고 있습니다. 조르지오에서 링크


1
+1 : 팀워크도 중요합니다! 예를 들어 paulgraham.com/head.html 및 "동일한 코드를 편집하는 여러 사람이 없습니다"라는 제목의 단락을 참조하십시오 .
조르지오

@Giorgio 나는 그것을 통해서만 훑어 보았지만 멋진 리소스처럼 보입니다! 일부 사람들은 댓글 섹션을 보지 않을 수 있기 때문에 간단히 답변에 추가하겠습니다. 확실히 좀 더 철저하게 읽을 것입니다.
Sephallia

이것은 또한 개정 제어에도 적용됩니다. 별도의 파일을 작업하면 충돌과 병합이 줄어 듭니다.
복원 Monica Monica

7

실제로 당신이 한 일은 절차 적 프로그래밍을 다시 발명 한 것입니다. 그런 식으로 소프트웨어를 작성하는 것이 가능하며 컴파일러는 신경 쓰지 않을 것입니다. 수년 동안 이것은 컴퓨터가 빨라지고 도구가 나아질 때까지 일이 수행되는 방식입니다.

코드를 다른 논리 단위 (클래스, 모듈 등)로 나눌 경우 코드를 이해하기 쉽고 짧게 이해할 수 있습니다. 나중에 유지 될 수 있습니다. 내 모듈 중 많은 코드가 20 줄 미만입니다. 주어진 주제의 모든 코드가 특정 장소에 있다는 것을 알고 있습니다. 또한 누군가 다른 사람이 프로젝트에 참여하면 물건을 찾기가 훨씬 쉬워 질 것입니다.

Gerald Sussman이 말한 것처럼 사람들이 프로그램을 읽을 수 있도록 프로그램을 먼저 작성하고 컴퓨터가 프로그램을 실행할 수 있도록 프로그램을 작성해야합니다. (그리고 "컴퓨터 프로그램의 구조와 해석"을 아직 읽지 않았다면)


4

하나는 여러 클래스를 사용하기 때문에 더 큰 물건을 얻을 때 하나의 큰 코드 더미 일 때 모든 것을 추적 할 수있는 방법이 없다는 것을 알 수 있습니다.

당신은 단순히 그것을 처리하기 위해 나누고 정복해야합니다.


3

객체 지향 프로그래밍은 프로그래밍에서 본 최고의 아이디어입니다. 그러나 모든 경우에 가장 좋은 것은 아니며, 요점을 알기 위해서는 약간의 프로그래밍 경험이 필요하며 많은 사람들이 OOP를하지 않을 것이라고 주장합니다.

"구조화 된 프로그래밍"을 찾을 수 있다면 아마도 더 유용한 것이있을 것입니다. ( 구식 구조화 된 프로그래밍 에 대해 읽으십시오 . 구식 용어는 종종 더 새롭고 더 멋진 의미를 갖지만 아직 멋진 것은 필요하지 않습니다.) 이것은 프로그램을 서브 루틴으로 나누는 것에 대한 다소 단순한 개념으로, 프로그램보다 훨씬 쉽습니다. 그것을 물체로 분해. 기본 프로그램은 작업을 수행하기 위해 서브 루틴 (Java의 "메소드")을 호출하는 짧은 루틴입니다. 각 서브 루틴은 해당 매개 변수에 의해 전달 된 내용 만 알고 있습니다. (이러한 매개 변수 중 하나는 파일 이름 일 수 있으므로 약간의 부정 행위를 할 수 있습니다.) 따라서 서브 루틴 / 메서드의 제목을 살펴보면 서브 루틴 / 방법을 빠르게 이해할 수 있습니다. 거의 한 눈에.

그런 다음 메소드 호출없이 몇 줄의 코드가 작업을 수행 할 때까지 모든 서브 루틴이 유사하게 분류됩니다. 몇 가지 메소드를 호출하는 기본 프로그램. 각각은 몇 가지 메소드를 호출합니다. 각 메소드는 작업을 수행하는 작은 간단한 메소드입니다. 이런 식으로 매우 큰 프로그램 (또는 작은 프로그램)의 어느 부분을보고 그 기능을 빠르게 이해할 수 있습니다.

Java는 객체 지향 코드를 작성하는 사람들을 위해 특별히 설계되었습니다. 그러나 가장 강력한 OO 프로그램조차도 일부 구조화 된 프로그래밍을 사용하므로 언제든지 모든 언어를 파괴 할 수 있습니다. (저는 평범한 C로 OO를 했었습니다.) 따라서 Java로 SP 또는 다른 작업을 수행 할 수 있습니다. 클래스를 잊고 다루기 쉬운 작은 방법으로 나눌 수있는 큰 방법에 집중하십시오. SP를 사용하면 코드를 재사용하고 DRY (Google 코드를 사용하지만 "자신을 반복하지 않음") 원칙을 통해 많은 도움이된다고 덧붙여 야합니다.

"클래스"를 가져 오지 않고 코드를 여러 부분으로 나누는 이유와 방법에 대해 설명했습니다. 그것들은 훌륭한 아이디어이며 단지 게임을위한 것이고 Java는 OOP를위한 훌륭한 언어입니다. 그러나 왜 내가하고있는 일을하고 있는지 아는 것이 좋습니다. 이해가 될 때까지 OOP를 그대로 두십시오.


0

장점 중 하나는 재사용 성입니다. 프로그램은 기본적으로 함께 묶인 명령입니다. 이러한 지침 중 일부는 다른 프로그램에도 적합하다는 것을 알 수 있습니다.

점프 게임을한다고 가정 해 봅시다. 나중에 대포 게임을 만들 때 점프 게임에서 사용한 물리 계산이 편리하다는 것을 알 수 있습니다.

따라서 다시 쓰거나 새 프로그램에 복사하여 붙여 넣는 대신 클래스로 만듭니다. 다음에 게임 역학에 물리가 필요한 다른 게임을 만들면 재사용 할 수 있습니다. 물론 이것은 지나치게 단순화되었지만 의미가 있기를 바랍니다.


0

우선, 나는 Java가 아닌 C ++ 및 Python이므로 일부는 완전히 적용되지 않을 수 있습니다. Java에서 클래스가 작동하는 방식에 대해 잘못된 가정을하면 수정하십시오.

클래스는 주로 인스턴스화 할 때 유용합니다. 실제로 인스턴스가 생성되지 않은 클래스는 실제로 영광스러운 네임 스페이스입니다. 이런 식으로 모든 클래스를 사용한다면 실제로 네임 스페이스에서 네임 스페이스로 물건을 옮기는 이점은 중요하지 않을 수 있습니다.

그러나 이것은 수업이 빛나는 곳이 아닙니다. String클래스를 고려하십시오 . char배열과 일부 정적 함수를 사용하여 동일한 기능을 모두 가질 수 있습니다 . 이 시점에서 기능은 약간의 안전성과 구문 설탕을 제공합니다. string.length()대신 쓸 수 있습니다 length(char_array); 그다지 큰 문제는 아니지만 많은 사람들이 여전히 그것을 좋아합니다. 또한 누군가가 당신에게을 주면 생성자 String로 생성되었으며 함수 String와 함께 작동해야한다는 것을 알고 있습니다 length. 배열 버전이 일부 문자를 처리 할 수 ​​없다면 거기에 넣을 수있는 방법이 없습니다 .

그래도 여전히 그렇지 않습니다. 핵심은 클래스가 데이터와 함수를 묶고 추상화하는 기능과 데이터를 묶는 것입니다. 당신이 방법을 가지고 있다면 void f(Builder b)당신은을 얻는다는 것을 알고 있으며 Builder, 당신은 그것이 특정 행동을 지원할 것이라고 기대할 수 있습니다. 그러나 실행중인 데이터 나 함수에 대해 전혀 알지 못합니다. 실제로 작성하고 컴파일 할 때 둘 다에 대한 정의가 아직 작성되지 않았을 수 있습니다 f.

첫 번째로 이해해야 할 점은 클래스가 데이터가 손상되지 않도록 확인하면서 데이터를 전달하는 것이 편리하다는 것입니다. 두 번째 요점은 객체가 가진 데이터와 기능 (구현)이 객체에 대한 것이지 그 유형에서 알 수있는 것이 아니라는 것입니다.


0

전체 아이디어는 split and conquer 라는 일반적인 규칙을 기반으로합니다 .
이 패러다임은 거의 모든 곳에서 사용될 수 있습니다. 문제를 작은 문제로 나눈 다음이 작고 단순하며 잘 알려진 문제를 해결합니다.
프로그램을 수업으로 나누는 것은 지난 10 년 동안 일반화되기 시작한 유형 중 하나입니다. 이 프로그래밍 패러다임에서 우리는 일부 객체에 의해 문제를 모델링하고 이러한 객체 사이에 메시지를 보내서 문제를 해결하려고 시도합니다.
어떤 사람들은이 접근법이 이해, 확장 및 디버깅이 더 쉽다고 말할 수 있습니다. 어떤 사람들은 동의하지
않지만 :)


0

프로그램을 클래스로 나누는 것이 아니라 응용 프로그램을 모델링하는 방법, 즉 응용 프로그램의 일부를 시각화하는 방법에 관한 것입니다. 사물 분할은 복잡한 사물을 더 잘 이해하기 위해 사용하는 메커니즘 일뿐입니다. 프로그래밍 만이 아닙니다. 서로 얽힌 많은 전선을 가진 회로 보드를 상상해보십시오. 각 전선이 어딘가에 연결되어 복잡한 구조를 형성한다고 가정하십시오 (스파게티 코드). 연결을 파악하려면 각 와이어를 끝까지 따라야합니다. 반대로 기능에 따라 그룹화되고 색상이 지정된 전선을 상상해보십시오. 일을 고치는 것이 훨씬 쉬워집니다.

긴 프로그램으로 시작하지 않고 클래스로 나누는 것이 좋습니다. 그러나 먼저 객체 / 클래스 측면에서 애플리케이션을 모델링 한 다음 연결하여 애플리케이션을 빌드하십시오.

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