CodeGym/Java Blog/무작위의/코딩 규칙: 시스템 생성에서 개체 작업까지
John Squirrels
레벨 41
San Francisco

코딩 규칙: 시스템 생성에서 개체 작업까지

무작위의 그룹에 게시되었습니다
회원
좋은 하루 되세요! 오늘은 좋은 코드를 작성하는 방법에 대해 이야기하고자 합니다. 물론 Clean Code와 같은 책은 방대한 양의 정보를 포함하고 있지만 처음에는 명확하지 않기 때문에 모든 사람이 당장 읽고 싶어하는 것은 아닙니다. 그리고 당신이 다 읽을 때쯤이면 당신은 코딩에 대한 당신의 모든 욕망을 죽일지도 모릅니다. 이 모든 것을 고려하여 오늘 저는 더 나은 코드를 작성하기 위한 작은 가이드(작은 권장 사항 집합)를 제공하고자 합니다. 이 기사에서는 시스템 생성 및 인터페이스, 클래스 및 개체 작업과 관련된 기본 규칙 및 개념을 살펴보겠습니다. 이 기사를 읽는 데 많은 시간이 걸리지 않으며 지루하지 않기를 바랍니다. 위에서 아래로, 즉 응용 프로그램의 일반적인 구조에서 더 좁은 세부 사항에 이르기까지 내 방식대로 작업할 것입니다. 코딩 규칙: 시스템 생성에서 개체 작업까지 - 1

시스템

다음은 일반적으로 바람직한 시스템 특성입니다.
  • 최소한의 복잡성. 지나치게 복잡한 프로젝트는 피해야 합니다. 가장 중요한 것은 단순성과 명확성입니다(단순함 = 더 좋음).
  • 유지 보수 용이성. 응용 프로그램을 만들 때 유지 관리가 필요하다는 점을 기억해야 합니다(개인적으로 유지 관리에 대한 책임이 없더라도). 이는 코드가 명확하고 명확해야 함을 의미합니다.
  • 느슨한 결합. 즉, 프로그램의 서로 다른 부분 간의 종속성 수를 최소화합니다(OOP 원칙 준수 극대화).
  • 재사용 성. 우리는 다른 응용 프로그램에서 구성 요소를 재사용할 수 있는 기능으로 시스템을 설계합니다.
  • 휴대성. 시스템을 다른 환경에 쉽게 적용할 수 있어야 합니다.
  • 유니폼 스타일. 우리는 다양한 구성 요소에서 균일한 스타일을 사용하여 시스템을 설계합니다.
  • 확장성(확장성). 기본 구조를 위반하지 않고 시스템을 향상시킬 수 있습니다(구성 요소를 추가하거나 변경해도 다른 모든 구성 요소에 영향을 미치지 않아야 함).
수정이나 새로운 기능이 필요하지 않은 애플리케이션을 구축하는 것은 사실상 불가능합니다. 우리는 우리의 발명품이 시대에 발맞추도록 돕기 위해 끊임없이 새로운 부품을 추가해야 할 것입니다. 여기에서 확장성이 작용합니다. 확장성은 기본적으로 응용 프로그램을 확장하고, 새로운 기능을 추가하고, 더 많은 리소스(즉, 더 큰 로드)로 작업하는 것입니다. 즉, 새로운 논리를 추가하기 쉽게 하기 위해 모듈성을 높여 시스템의 결합을 줄이는 것과 같은 몇 가지 규칙을 고수합니다.코딩 규칙: 시스템 생성에서 개체 작업까지 - 2

이미지 출처

시스템 설계 단계

  1. 소프트웨어 시스템. 애플리케이션을 전반적으로 디자인합니다.
  2. 하위 시스템/패키지로 구분합니다. 논리적으로 구별되는 부분을 정의하고 이들 사이의 상호 작용 규칙을 정의합니다.
  3. 하위 시스템을 클래스로 나눕니다. 시스템의 일부를 특정 클래스와 인터페이스로 나누고 이들 간의 상호 작용을 정의합니다.
  4. 클래스를 메서드로 나누기. 할당된 책임에 따라 클래스에 필요한 메서드의 완전한 정의를 만듭니다.
  5. 방법 설계. 개별 방법의 기능에 대한 자세한 정의를 만듭니다.
일반적으로 일반 개발자가 이 디자인을 처리하는 반면 응용 프로그램 설계자는 위에서 설명한 사항을 처리합니다.

시스템 설계의 일반 원칙 및 개념

게으른 초기화. 이 프로그래밍 관용구에서 응용 프로그램은 실제로 사용될 때까지 개체를 만드는 데 시간을 낭비하지 않습니다. 이렇게 하면 초기화 프로세스의 속도가 빨라지고 가비지 수집기의 부하가 줄어듭니다. 즉, 모듈화 원칙을 위반할 수 있으므로 너무 멀리 가져가지 말아야 합니다. 예를 들어 기본 메서드 또는 팩토리 클래스 와 같은 일부 특정 부분으로 구성의 모든 인스턴스를 이동하는 것이 좋습니다 . 좋은 코드의 특징 중 하나는 반복적인 상용구 코드가 없다는 것입니다. 일반적으로 이러한 코드는 필요할 때 호출할 수 있도록 별도의 클래스에 배치됩니다.

AOP

또한 측면 지향 프로그래밍에 주목하고 싶습니다. 이 프로그래밍 패러다임은 투명한 논리를 도입하는 것입니다. 즉, 반복되는 코드를 클래스(Aspect)에 넣고 특정 조건을 만족할 때 호출합니다. 예를 들어 특정 이름으로 메서드를 호출하거나 특정 유형의 변수에 액세스할 때입니다. 코드가 호출되는 위치가 즉시 명확하지 않기 때문에 때때로 aspect가 혼란스러울 수 있지만 이것은 여전히 ​​매우 유용한 기능입니다. 특히 캐싱 또는 로깅할 때. 일반 클래스에 추가 논리를 추가하지 않고 이 기능을 추가합니다. 간단한 아키텍처에 대한 Kent Beck의 네 가지 규칙:
  1. 표현력 — 클래스의 의도가 명확하게 표현되어야 합니다. 이는 적절한 이름 지정, 작은 크기, 단일 책임 원칙 준수를 통해 달성됩니다(자세한 내용은 아래에서 고려할 것임).
  2. 수업 및 방법의 최소 수 — 수업을 가능한 한 작고 좁게 만들려는 욕구에서 너무 멀리 갈 수 있습니다(결과적으로 샷건 수술 안티 패턴이 발생함). 이 원칙은 가능한 모든 작업에 대해 별도의 클래스를 생성하여 시스템을 콤팩트하게 유지하고 너무 멀리 가지 않도록 요구합니다.
  3. 중복 없음 — 혼동을 일으키고 최적이 아닌 시스템 설계를 나타내는 중복 코드가 추출되어 별도의 위치로 이동됩니다.
  4. 모든 테스트 실행 — 모든 테스트를 통과하는 시스템은 관리가 가능합니다. 모든 변경으로 인해 테스트가 실패할 수 있으며 메서드의 내부 논리를 변경하면 시스템 동작도 예기치 않은 방식으로 변경되었음을 알 수 있습니다.

단단한

시스템을 설계할 때 잘 알려진 SOLID 원칙을 고려할 가치가 있습니다.

S (단일 책임), O (열림-닫힘), L (리스코프 대체), I (인터페이스 분리), D (의존성 역전).

우리는 각각의 개별 원칙에 연연하지 않을 것입니다. 그것은 이 문서의 범위를 약간 벗어나지만 여기에서 더 많은 내용을 읽을 수 있습니다 .

상호 작용

아마도 잘 설계된 클래스를 만드는 가장 중요한 단계 중 하나는 좋은 추상화를 나타내는 잘 설계된 인터페이스를 만들고 클래스의 구현 세부 사항을 숨기고 동시에 서로 명확하게 일관된 메서드 그룹을 제시하는 것입니다. SOLID 원칙 중 하나인 인터페이스 분리를 ​​자세히 살펴보겠습니다. 클라이언트(클래스)는 사용하지 않을 불필요한 메서드를 구현해서는 안 됩니다. 즉, 인터페이스의 유일한 작업(단일 책임 원칙과 매우 유사하다고 생각함)을 수행하는 것을 목표로 하는 최소 수의 메서드로 인터페이스를 만드는 것에 대해 이야기하는 경우 대신 두어 개의 작은 메서드를 만드는 것이 좋습니다. 하나의 부풀어 오른 인터페이스. 다행스럽게도 클래스는 둘 이상의 인터페이스를 구현할 수 있습니다. 인터페이스 이름을 올바르게 지정해야 합니다. 이름은 할당된 작업을 최대한 정확하게 반영해야 합니다. 그리고 물론 길이가 짧을수록 혼란이 줄어듭니다. 문서 주석은 일반적으로 인터페이스 수준에서 작성됩니다. 이러한 주석은 각 메서드가 수행해야 하는 작업, 수행할 인수 및 반환할 항목에 대한 세부 정보를 제공합니다.

수업

코딩 규칙: 시스템 생성에서 개체 작업까지 - 3

이미지 출처

내부적으로 클래스가 어떻게 배열되어 있는지 살펴보겠습니다. 또는 클래스를 작성할 때 따라야 하는 몇 가지 관점과 규칙입니다. 일반적으로 클래스는 특정 순서로 된 변수 목록으로 시작해야 합니다.
  1. 공개 정적 상수;
  2. 개인 정적 상수;
  3. 개인 인스턴스 변수.
다음으로 인수가 가장 적은 생성자부터 인수가 가장 많은 생성자 순으로 다양한 생성자가 나옵니다. 그 다음에는 가장 공개적인 방법부터 가장 사적인 방법까지 있습니다. 일반적으로 제한하려는 일부 기능의 구현을 숨기는 개인 메서드는 맨 아래에 있습니다.

학급 크기

이제 수업 규모에 대해 이야기하고 싶습니다. SOLID 원칙 중 하나인 단일 책임 원칙을 상기해 봅시다. 그것은 각 객체가 단 하나의 목적(책임)을 가지며 모든 방법의 논리가 그것을 달성하는 것을 목표로 한다고 명시합니다. 이것은 우리에게 크고 부풀려진 클래스(실제로 God 객체 안티 패턴)를 피하라고 말하며, 클래스에 온갖 종류의 서로 다른 논리가 포함된 많은 메서드가 있는 경우 클래스를 분리하는 것에 대해 생각해야 합니다. 몇 개의 논리적 부분(클래스). 이렇게 하면 주어진 클래스의 대략적인 목적을 알면 각 메서드의 목적을 이해하는 데 오래 걸리지 않기 때문에 코드의 가독성이 높아집니다. 또한 포함된 논리를 반영해야 하는 클래스 이름을 주시하십시오. 예를 들어 이름에 20개 이상의 단어가 포함된 클래스가 있는 경우 리팩토링에 대해 생각해야 합니다. 자존심이 강한 클래스에는 그렇게 많은 내부 변수가 없어야 합니다. 실제로 각 방법은 하나 또는 몇 가지와 함께 작동하여 클래스 내에서 많은 응집력을 유발합니다(클래스는 통합된 전체여야 하므로 정확히 그래야 합니다). 결과적으로 학급의 결속력을 높이면 학급 규모가 줄어들고 당연히 학급 수가 늘어난다. 특정 대규모 작업이 어떻게 작동하는지 확인하기 위해 클래스 파일을 더 자세히 살펴봐야 하기 때문에 일부 사람들에게는 이것이 성가신 일입니다. 무엇보다도 각 클래스는 다른 클래스와 최소한으로 관련되어야 하는 작은 모듈입니다. 이러한 격리는 클래스에 로직을 추가할 때 변경해야 하는 변경 횟수를 줄여줍니다. 각 방법은 그들 중 하나 또는 몇 개와 함께 작동하여 클래스 내에서 많은 응집력을 유발합니다(클래스는 통합된 전체여야 하므로 정확히 그래야 합니다). 결과적으로 학급의 결속력을 높이면 학급 규모가 줄어들고 당연히 학급 수가 늘어난다. 특정 대규모 작업이 어떻게 작동하는지 확인하기 위해 클래스 파일을 더 자세히 살펴봐야 하기 때문에 일부 사람들에게는 이것이 성가신 일입니다. 무엇보다도 각 클래스는 다른 클래스와 최소한으로 관련되어야 하는 작은 모듈입니다. 이러한 격리는 클래스에 로직을 추가할 때 변경해야 하는 변경 횟수를 줄여줍니다. 각 방법은 그들 중 하나 또는 몇 개와 함께 작동하여 클래스 내에서 많은 응집력을 유발합니다(클래스는 통합된 전체여야 하므로 정확히 그래야 합니다). 결과적으로 학급의 결속력을 높이면 학급 규모가 줄어들고 당연히 학급 수가 늘어난다. 특정 대규모 작업이 어떻게 작동하는지 확인하기 위해 클래스 파일을 더 자세히 살펴봐야 하기 때문에 일부 사람들에게는 이것이 성가신 일입니다. 무엇보다도 각 클래스는 다른 클래스와 최소한으로 관련되어야 하는 작은 모듈입니다. 이러한 격리는 클래스에 로직을 추가할 때 변경해야 하는 변경 횟수를 줄여줍니다. 응집력은 학급 규모의 축소로 이어지고 당연히 학급의 수는 증가합니다. 특정 대규모 작업이 어떻게 작동하는지 확인하기 위해 클래스 파일을 더 자세히 살펴봐야 하기 때문에 일부 사람들에게는 이것이 성가신 일입니다. 무엇보다도 각 클래스는 다른 클래스와 최소한으로 관련되어야 하는 작은 모듈입니다. 이러한 격리는 클래스에 로직을 추가할 때 변경해야 하는 변경 횟수를 줄여줍니다. 응집력은 학급 규모의 축소로 이어지고 당연히 학급의 수는 증가합니다. 특정 대규모 작업이 어떻게 작동하는지 확인하기 위해 클래스 파일을 더 자세히 살펴봐야 하기 때문에 일부 사람들에게는 이것이 성가신 일입니다. 무엇보다도 각 클래스는 다른 클래스와 최소한으로 관련되어야 하는 작은 모듈입니다. 이러한 격리는 클래스에 로직을 추가할 때 변경해야 하는 변경 횟수를 줄여줍니다.

사물

캡슐화

여기서 우리는 먼저 OOP 원칙인 캡슐화에 대해 이야기할 것입니다. 구현을 숨기는 것은 변수를 격리하는 메서드를 만드는 것과는 다릅니다(개별 메서드, 게터 및 세터를 통한 액세스를 생각 없이 제한하는 것은 캡슐화의 전체 지점이 손실되기 때문에 좋지 않습니다). 액세스 숨기기는 추상화를 형성하는 것을 목표로 합니다. 즉, 클래스는 데이터 작업에 사용하는 공유된 구체적인 메서드를 제공합니다. 그리고 사용자는 우리가 이 데이터로 작업하는 방법을 정확히 알 필요가 없습니다. 작동하고 그것으로 충분합니다.

데메테르의 법칙

Demeter의 법칙도 고려할 수 있습니다. Demeter는 클래스 및 메서드 수준에서 복잡성을 관리하는 데 도움이 되는 작은 규칙 집합입니다. Car 객체가 있고 여기에 move(Object arg1, Object arg2) 메서드가 있다고 가정합니다 . 데메테르의 법칙에 따르면 이 메서드는 다음을 호출하는 것으로 제한됩니다.
  • Car 객체 자체 의 메서드 (즉, "this" 객체);
  • move 메소드 내에서 생성된 객체의 메소드 ;
  • 인수로 전달된 객체의 메서드( arg1 , arg2 );
  • 내부 Car 객체의 메서드(다시 "this").
즉, 데메테르의 법칙은 부모가 아이에게 "친구와는 이야기할 수 있지만 낯선 사람과는 이야기할 수 없다"고 말하는 것과 같습니다.

데이터 구조

데이터 구조는 관련 요소의 모음입니다. 개체를 데이터 구조로 고려할 때 메서드가 작동하는 데이터 요소 집합이 있습니다. 이러한 메서드의 존재는 암시적으로 가정됩니다. 즉, 데이터 구조는 저장된 데이터를 저장하고 작업(처리)하는 것이 목적인 객체입니다. 일반 개체와의 주요 차이점은 일반 개체는 암묵적으로 존재한다고 가정되는 데이터 요소에 대해 작동하는 메서드 모음이라는 것입니다. 이해했나요? 일반 개체의 주요 측면은 메서드입니다. 내부 변수는 올바른 작동을 용이하게 합니다. 그러나 데이터 구조에는 여기에 가장 중요한 저장된 데이터 요소로 작업을 지원하기 위한 메서드가 있습니다. 데이터 구조의 한 유형은 데이터 전송 개체(DTO)입니다. 이것은 데이터베이스 작업, 소켓에서 메시지 구문 분석 등을 수행할 때 데이터를 전송하는 데 사용되는 공용 변수 및 메서드(또는 읽기/쓰기를 위한 메서드만 있음)가 없는 클래스입니다. 데이터는 일반적으로 오랜 기간 동안 이러한 개체에 저장되지 않습니다. 거의 즉시 애플리케이션이 작동하는 엔터티 유형으로 변환됩니다. 엔터티도 데이터 구조이지만 그 목적은 응용 프로그램의 다양한 수준에서 비즈니스 논리에 참여하는 것입니다. DTO의 목적은 응용 프로그램과 데이터를 주고 받는 것입니다. DTO의 예: 데이터 구조이기도 하지만 그 목적은 응용 프로그램의 다양한 수준에서 비즈니스 논리에 참여하는 것입니다. DTO의 목적은 응용 프로그램과 데이터를 주고 받는 것입니다. DTO의 예: 데이터 구조이기도 하지만 그 목적은 응용 프로그램의 다양한 수준에서 비즈니스 논리에 참여하는 것입니다. DTO의 목적은 응용 프로그램과 데이터를 주고 받는 것입니다. DTO의 예:
@Setter
@Getter
@NoArgsConstructor
public class UserDto {
    private long id;
    private String firstName;
    private String lastName;
    private String email;
    private String password;
}
모든 것이 충분히 명확해 보이지만 여기서 우리는 잡종의 존재에 대해 배웁니다. 하이브리드는 중요한 논리를 처리하고, 내부 요소를 저장하고, 접근자(get/set) 메서드를 포함하는 메서드가 있는 객체입니다. 이러한 개체는 지저분하고 새 메서드를 추가하기 어렵게 만듭니다. 그것들이 무엇을 위한 것인지 명확하지 않기 때문에 그것들을 피해야 합니다 — 요소를 저장하거나 논리를 실행합니까?

변수 생성 원리

변수에 대해 조금 생각해 봅시다. 보다 구체적으로 생성할 때 어떤 원칙이 적용되는지 생각해 봅시다.
  1. 이상적으로는 변수를 사용하기 직전에 변수를 선언하고 초기화해야 합니다(만들고 잊어버리지 마십시오).
  2. 가능하면 변수를 최종 변수로 선언하여 초기화 후 값이 변경되지 않도록 하십시오.
  3. 일종의 for 루프에서 일반적으로 사용하는 카운터 변수를 잊지 마십시오. 즉, 제로화하는 것을 잊지 마십시오. 그렇지 않으면 모든 논리가 깨질 수 있습니다.
  4. 생성자에서 변수를 초기화해야 합니다.
  5. 참조가 있는 개체를 사용하거나( new SomeObject() ) 사용하지 않는 개체를 사용할 수 있는 경우 개체가 사용된 후 다음 가비지 수집 주기 동안 삭제되고 해당 리소스가 낭비되지 않기 때문에 사용하지 않는 것을 선택하십시오.
  6. 변수의 수명(변수 생성과 마지막 참조 시간 사이의 거리)을 가능한 한 짧게 유지하십시오.
  7. 루프를 포함하는 메서드의 시작 부분이 아니라 루프 직전에 루프에 사용된 변수를 초기화합니다.
  8. 항상 가장 제한된 범위에서 시작하고 필요한 경우에만 확장합니다(변수를 가능한 한 로컬로 만들어야 함).
  9. 각 변수는 한 가지 목적으로만 사용하십시오.
  10. 숨겨진 목적이 있는 변수, 예를 들어 두 작업 사이의 변수 분할을 피하십시오. 이는 해당 유형이 그 중 하나를 해결하는 데 적합하지 않음을 의미합니다.

행동 양식

코딩 규칙: 시스템 생성에서 개체 작업까지 - 4

영화 "스타워즈: 에피소드 III - 시스의 복수"(2005)에서

우리 논리의 구현, 즉 메소드로 직접 진행합시다.
  1. 규칙 #1 - 컴팩트함. 이상적으로는 메서드가 20줄을 초과하지 않아야 합니다. 즉, 공용 메서드가 크게 "증가"하는 경우 논리를 분리하여 별도의 전용 메서드로 이동하는 방법을 고려해야 합니다.

  2. 규칙 #2 — if , else , while 및 기타 문에 블록이 많이 중첩되면 안 됩니다. 중첩이 많으면 코드의 가독성이 크게 떨어집니다. 이상적으로는 2개 이하의 중첩된 {} 블록이 있어야 합니다 .

    또한 이러한 블록의 코드를 간결하고 단순하게 유지하는 것이 바람직합니다.

  3. 규칙 #3 — 메서드는 하나의 작업만 수행해야 합니다. 즉, 메서드가 모든 종류의 복잡한 논리를 수행하는 경우 메서드를 하위 메서드로 나눕니다. 결과적으로 메서드 자체는 올바른 순서로 다른 모든 작업을 호출하는 것이 목적인 파사드가 됩니다.

    하지만 작업이 너무 단순해서 별도의 메서드에 넣을 수 없는 경우에는 어떻게 해야 할까요? 사실, 때로는 참새에게 대포를 발사하는 것처럼 느껴질 수 있지만 작은 방법은 여러 가지 이점을 제공합니다.

    • 더 나은 코드 이해;
    • 방법은 개발이 진행됨에 따라 더 복잡해지는 경향이 있습니다. 방법이 간단하면 기능을 복잡하게 만드는 것이 조금 더 쉬울 것입니다.
    • 구현 세부 정보는 숨겨져 있습니다.
    • 더 쉬운 코드 재사용;
    • 보다 안정적인 코드.

  4. 스텝다운 규칙 — 코드는 위에서 아래로 읽어야 합니다. 코드를 낮게 읽을수록 논리를 더 깊이 파고들게 됩니다. 그 반대도 마찬가지입니다. 더 높이 올라갈수록 방법이 더 추상적입니다. 예를 들어 switch 문은 간결하지 않고 바람직하지 않지만 switch를 사용하는 것을 피할 수 없다면 가능한 한 가장 낮은 수준의 메서드로 전환해야 합니다.

  5. 메서드 인수 — 이상적인 숫자는 무엇입니까? 이상적으로는 전혀 없습니다 :) 하지만 정말 그런 일이 일어날까요? 즉, 인수가 적을수록 메서드를 사용하기 쉽고 테스트하기가 더 쉽기 때문에 가능한 한 적은 수의 인수를 갖도록 노력해야 합니다. 확실하지 않은 경우 입력 매개변수가 많은 방법을 사용하는 모든 시나리오를 예상해 보십시오.

  6. 또한 입력 매개변수로 부울 플래그가 있는 메소드를 분리하는 것이 좋을 것입니다. 이는 그 자체로 메소드가 둘 이상의 작업을 수행함을 의미하기 때문입니다(참이면 한 가지 작업 수행, 거짓이면 다른 작업 수행). 위에서 쓴 것처럼 이것은 좋지 않으며 가능하면 피해야 합니다.

  7. 메서드에 많은 수의 입력 매개 변수가 있는 경우(극단적인 값은 7이지만 실제로는 2-3개 이후에 생각해야 함) 인수 중 일부를 별도의 개체로 그룹화해야 합니다.

  8. 유사한(오버로드된) 메서드가 여러 개 있는 경우 유사한 매개 변수를 동일한 순서로 전달해야 합니다. 이렇게 하면 가독성과 사용성이 향상됩니다.

  9. 메소드에 매개변수를 전달할 때 매개변수가 모두 사용되었는지 확인해야 합니다. 그렇지 않으면 매개변수가 왜 필요한가요? 인터페이스에서 사용하지 않는 매개변수를 잘라낸 다음 완료하십시오.

  10. try/catch는 본질적으로 그다지 좋아 보이지 않으므로 별도의 중간 메서드(예외 처리 메서드)로 옮기는 것이 좋습니다.

    public void exceptionHandling(SomeObject obj) {
        try {
            someMethod(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

위에서 중복 코드에 대해 이야기했지만 다시 한 번 반복하겠습니다. 코드가 반복되는 메서드가 두 개 있는 경우 이를 별도의 메서드로 옮겨야 합니다. 이렇게 하면 메서드와 클래스가 모두 더 간결해집니다. 이름을 관리하는 규칙을 잊지 마십시오. 클래스, 인터페이스, 메서드 및 변수의 이름을 적절하게 지정하는 방법에 대한 자세한 내용은 이 기사의 다음 부분에서 설명합니다. 하지만 오늘은 그게 전부입니다.
코멘트
  • 인기
  • 신규
  • 이전
코멘트를 남기려면 로그인 해야 합니다
이 페이지에는 아직 코멘트가 없습니다