window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster가 이미 존재합니다') } else { w.LeadBooster = { q: [], on: 함수 (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: 함수 (n) { this.q.push({ t: 't', n: n }) }, } } })() 좋은 품질의 코드를 작성하는 방법은 무엇인가요? - The Codest
The Codest
  • 회사 소개
  • 서비스
    • 소프트웨어 개발
      • 프론트엔드 개발
      • 백엔드 개발
    • Staff Augmentation
      • 프론트엔드 개발자
      • 백엔드 개발자
      • 데이터 엔지니어
      • 클라우드 엔지니어
      • QA 엔지니어
      • 기타
    • IT 자문
      • 감사 및 컨설팅
  • 산업 분야
    • 핀테크 및 뱅킹
    • E-commerce
    • 애드테크
    • 헬스 테크
    • 제조
    • 물류
    • 자동차
    • IOT
  • 가치
    • CEO
    • CTO
    • 배달 관리자
  • 우리 팀
  • Case Studies
  • 방법 알아보기
    • 블로그
    • 모임
    • 웹 세미나
    • 리소스
채용 정보 연락하기
  • 회사 소개
  • 서비스
    • 소프트웨어 개발
      • 프론트엔드 개발
      • 백엔드 개발
    • Staff Augmentation
      • 프론트엔드 개발자
      • 백엔드 개발자
      • 데이터 엔지니어
      • 클라우드 엔지니어
      • QA 엔지니어
      • 기타
    • IT 자문
      • 감사 및 컨설팅
  • 가치
    • CEO
    • CTO
    • 배달 관리자
  • 우리 팀
  • Case Studies
  • 방법 알아보기
    • 블로그
    • 모임
    • 웹 세미나
    • 리소스
채용 정보 연락하기
뒤로 화살표 뒤로 가기
2020-11-13
소프트웨어 개발

좋은 품질의 코드를 작성하는 방법은 무엇인가요?

저스티나 미아노프스카

멋지고 잘 디자인되고 보기 좋은 코드를 작성하는 것은 생각만큼 어렵지 않습니다. 주요 규칙을 파악하고 이를 코드에 적용하는 데 약간의 노력이 필요합니다. 그리고 한 번에 모든 것을 다 할 필요는 없지만, 한 가지에 익숙해지면 다른 것도 생각해보는 식으로 하면 됩니다.

바보 같은 코드가 아닌 견고한 코드 구축

먼저 SOLID라는 가장 기본적인 규칙부터 소개하겠습니다. 이는 좋은 디자인 원칙의 집합을 설명하는 용어입니다. 코드 로버트 C. 마틴이 발명했습니다:

S 는 단일 책임 원칙을 의미합니다.

클래스에는 변경해야 할 이유가 하나만 있어야 한다고 명시되어 있습니다. 즉, 한 클래스는 해야 할 일이 하나만 있어야 하므로 많은 책임이 있는 큰 클래스를 만들지 않아야 합니다. 만약 클래스가 많은 일을 해야 한다면 각각의 일을 별도의 클래스로 위임해야 합니다.

Notification 클래스
  def initialize(params)
    @params = params
  end

  def call
    EmailSender.new(message).call
  end

  private

  def message
    # 일부 구현
  end
끝

O 는 개방/폐쇄 원리를 의미합니다.

클래스를 수정하지 않고도 클래스 동작을 확장할 수 있어야 한다고 명시하고 있습니다. 즉, 클래스를 수정하지 않고도 클래스를 쉽게 확장할 수 있어야 한다는 뜻입니다. 예를 들어 전략 패턴이나 데코레이터를 사용하여 이를 달성할 수 있습니다.

Notification 클래스
  def initialize(params, sender)
    @params = params
    @발신자 = 발신자
  end

  def call
    sender.call 메시지
  end

  private

  def message
    # 일부 구현
  end
끝

class EmailSender
  def call(message)
    # 일부 구현
  end
end

class SmsSender
  def call(message)
    # 일부 구현
  end
end

이 디자인을 사용하면 코드를 변경하지 않고도 새 발신자를 추가할 수 있습니다.

L 는 리스크 코프 대체 원리 를 의미합니다.

파생 클래스는 기본 클래스를 대체할 수 있어야 한다고 명시되어 있습니다. 즉, 같은 조상에서 나온 클래스는 다른 자손이 쉽게 대체할 수 있어야 한다는 뜻입니다.

로거 클래스 {
  정보 (메시지) {
    console.info(this._prefixFor('info') + message)
  }

  error (message, err) {
    console.error(this._prefixFor('error') + message)
    if (err) {
      console.error(err)
    }
  }

  _prefixFor (type) {
    // 일부 구현
  }
}

ScepticLogger 클래스 로거 확장 {
  정보 (메시지) {
    super.info(message)
    console.info(this._prefixFor('info') + '그리고 그게 제가 할 말의 전부입니다.')
  }

  오류 (메시지, 오류) {
    super.error(message, err)
    console.error(this._prefixFor('error') + '큰일 났네!')
  }
}

두 클래스 모두 사용 인터페이스가 완전히 동일하기 때문에 클래스 이름을 쉽게 바꿀 수 있습니다.

인터페이스 분리 원칙

클라이언트별로 세분화된 인터페이스를 만들어야 한다고 명시되어 있습니다. 인터페이스란 무엇인가요? 코드의 일부에 대해 제공되는 사용 방법입니다. 따라서 이 규칙을 위반하는 것은 예를 들어 메서드가 너무 많은 클래스나 인자 옵션이 너무 많은 메서드일 수 있습니다. 이 원칙을 시각화하는 좋은 예는 리포지토리 패턴인데, 하나의 클래스에 많은 메서드를 넣는 경우가 많을 뿐만 아니라 이러한 메서드는 너무 많은 인수를 허용할 위험에 노출되어 있기 때문입니다.

#는 이번 예제에서 가장 좋은 예는 아닙니다.
NotificationRepository 클래스
  def find_all_by_ids(ids:, info:)
    notifications = Notification.where(id: ids)
    info ? notifications.where(type: :info) : notifications
  end
end

#와 더 나은 것
class NotificationRepository
  def find_all_by_ids(ids:)
    Notification.where(id: ids)
  end

  def find_all_by_ids_info(ids:)
    find_all_by_ids(ids).where(type: :info)
  end
end

D 는 종속성 반전 원리 를 의미합니다.

구체화가 아닌 추상화에 의존해야 한다고 명시하고 있습니다. 즉, 다른 것을 사용하는 클래스는 구현 세부 사항에 의존해서는 안 되며, 중요한 것은 사용자 인터페이스뿐입니다.

Notification 클래스
  def initialize(params, sender)
    @params = params
    @발신자 = 발신자
  end

  def call
    sender.call 메시지
  end

  private

  def message
    # 일부 구현
  end
끝

발신자 객체에 대해 알아야 할 것은 메시지를 인자로 기대하는 `call` 메서드를 노출한다는 것뿐입니다.

최고의 코드는 아닙니다.

코드를 작성할 때 엄격하게 피해야 할 사항을 아는 것도 매우 중요하므로 코드를 유지 관리하기 어렵고 테스트 및 재사용하기 어렵게 만드는 바보 같은 원칙을 담은 또 다른 컬렉션을 소개합니다.

S 는 싱글 톤 를 의미합니다.

싱글톤은 종종 안티 패턴으로 간주되며 일반적으로 피해야 합니다. 하지만 이 패턴의 가장 큰 문제는 전역 변수/메서드에 대한 일종의 변명이며 개발자가 금방 남용할 수 있다는 점입니다.

T 는 타이트한 결합을 의미합니다.

한 모듈의 변경으로 인해 애플리케이션의 다른 부분도 변경해야 하는 경우 보존됩니다.

U 는 테스트 불가능을 의미합니다.

코드가 훌륭하다면 테스트 작성은 악몽이 아니라 즐거운 일로 느껴질 것입니다.

P 는 조기 최적화를 의미합니다.

여기서 '시기상조'라는 단어가 핵심입니다. 지금 당장 필요하지 않다면 시간 낭비입니다. 일반적으로 코드를 더 복잡하게 만드는 일부 미세 최적화보다는 깔끔하고 좋은 코드에 집중하는 것이 좋습니다.

설명할 수 없는 이름 지정

좋은 코드를 작성하는 데 있어 가장 어려운 일이지만, 이는 여러분의 나머지 팀 하지만 미래의 당신을 위해서도 그러니 당신을 올바르게 대하세요 🙂 짧고 수수께끼 같은 이름보다는 모든 것을 담고 있는 긴 이름을 쓰는 것이 더 낫습니다.

D 는 복제 를 의미합니다.

코드가 중복되는 주된 이유는 긴밀한 결합 원칙을 따르지 않기 때문입니다. 코드가 긴밀하게 결합되어 있으면 재사용할 수 없고 중복된 코드가 나타나므로 DRY를 따르고 반복하지 마세요.

지금 당장은 중요하지 않습니다.

또한 종종 누락되는 매우 중요한 두 가지를 언급하고 싶습니다. 첫 번째는 이미 들어보셨을 텐데요, 바로 YAGNI입니다. 코드 리뷰를 하거나 심지어 직접 코드를 작성할 때도 가끔 이 문제를 관찰하지만, 기능 구현에 대한 생각을 바꿔야 합니다. 더도 말고 덜도 말고 지금 이 순간 필요한 코드를 정확히 작성해야 합니다. 모든 것(특히 애플리케이션 요구 사항)은 매우 빠르게 변하기 때문에 언젠가 유용하게 쓰일 것이라고 생각할 필요가 없다는 점을 명심해야 합니다. 시간을 낭비하지 마세요.

이해가 되지 않습니다.

마지막으로, 제 생각에는 명확하지 않고 어떤 사람들에게는 꽤 논란의 여지가 있을 수 있는 것은 설명적인 코드입니다. 클래스, 변수 또는 메서드에 올바른 이름을 사용하는 것만을 의미하는 것은 아닙니다. 전체 코드를 한 눈에 읽을 수 있으면 정말 정말 좋습니다. 아주 짧은 코드의 목적은 무엇이고, 그 코드를 작성한 사람 외에는 아무도 그 코드가 무엇을 하는지 알 수 없는 수수께끼 같은 코드의 목적은 무엇일까요? 제 생각에는 다음과 같은 문자를 작성하는 것이 좋습니다.조건문한 마디 이상의 다른 말을 한 다음 어제 앉아서 결과가 무엇인지, 어떻게 일어났는지 등 궁금해합니다.

const params = [
  {
    movies: [
      { 제목: '쇼생크 탈출' },
      { 제목: '뻐꾸기 둥지 위로 날아간 새' }, { 제목: '뻐꾸기 둥지 위로 날아간 새' }
    ]
  },
  {
    movies: [
      { 제목: '라이언 일병 구하기' },
      { 제목: '펄프 픽션' },
      { 제목: '쇼생크 탈출' },
    ]
  }
]

// 첫 번째 명제
함수 uniqueMovieTitlesFrom (params) {
  const titles = params
    .map(param => param.movies)
    .reduce((prev, nex) => prev.concat(next))
    .map(movie => movie.title)

  반환 [...new Set(titles)]]
}

// 두 번째 명제
함수 uniqueMovieTitlesFrom (params) {
  const titles = {}
  params.forEach(param => {})
    param.movies.forEach(movie => titles[movie.title] = true)
  })

  반환 Object.keys(titles)
}

요약하면 다음과 같습니다.

보시다시피 기억해야 할 규칙이 많지만 처음에 언급했듯이 좋은 코드를 작성하는 것은 시간 문제입니다. 코딩 습관을 한 가지 개선하기 시작하면 모든 좋은 것은 나쁜 것과 마찬가지로 저절로 생겨나기 때문에 또 다른 좋은 규칙이 따라올 것입니다.

자세히 읽어보세요:

루비 온 제트란 무엇이며 이를 사용하여 앱을 빌드하는 방법은 무엇인가요?

Vuelendar. Vue.js를 기반으로 하는 새로운 코데스트의 프로젝트

코데스트의 주간 베스트 기술 기사 리포트. 5천만 동시 소켓을 위한 소프트웨어 구축 (10)

관련 문서

소프트웨어 개발

미래 지향적인 웹 앱 구축: The Codest의 전문가 팀이 제공하는 인사이트

The Codest가 최첨단 기술로 확장 가능한 대화형 웹 애플리케이션을 제작하고 모든 플랫폼에서 원활한 사용자 경험을 제공하는 데 탁월한 성능을 발휘하는 방법을 알아보세요. Adobe의 전문성이 어떻게 디지털 혁신과 비즈니스를 촉진하는지 알아보세요...

최신
소프트웨어 개발

라트비아에 본사를 둔 10대 소프트웨어 개발 기업

최신 기사에서 라트비아 최고의 소프트웨어 개발 기업과 그들의 혁신적인 솔루션에 대해 알아보세요. 이러한 기술 리더들이 어떻게 귀사의 비즈니스를 향상시키는 데 도움을 줄 수 있는지 알아보세요.

thecodest
엔터프라이즈 및 스케일업 솔루션

Java 소프트웨어 개발 필수 사항: 성공적인 아웃소싱을 위한 가이드

The Codest로 효율성을 높이고 전문 지식을 활용하며 프로젝트 성공을 이끌 수 있는 성공적인 outsourcing Java 소프트웨어 개발에 대한 이 필수 가이드를 살펴보세요.

thecodest
소프트웨어 개발

폴란드 아웃소싱을 위한 최고의 가이드

폴란드에서 outsourcing가 급증한 것은 경제, 교육, 기술 발전으로 인한 IT 성장과 비즈니스 친화적인 환경이 조성된 덕분입니다.

더코데스트
엔터프라이즈 및 스케일업 솔루션

IT 감사 도구 및 기술에 대한 완벽한 가이드

IT 감사는 안전하고 효율적이며 규정을 준수하는 시스템을 보장합니다. 전체 기사를 읽고 그 중요성에 대해 자세히 알아보세요.

The Codest
야쿱 야쿠보비치 CTO & 공동 설립자

지식창고를 구독하고 IT 분야의 전문 지식을 최신 상태로 유지하세요.

    회사 소개

    The Codest - 폴란드에 기술 허브를 둔 국제 소프트웨어 개발 회사입니다.

    영국 - 본사

    • 사무실 303B, 182-184 하이 스트리트 노스 E6 2JA
      영국 런던

    폴란드 - 현지 기술 허브

    • 파브리츠나 오피스 파크, 알레야
      포코주 18, 31-564 크라쿠프
    • 뇌 대사관, 콘스트럭터스카
      11, 02-673 바르샤바, 폴란드

      The Codest

    • 홈
    • 회사 소개
    • 서비스
    • Case Studies
    • 방법 알아보기
    • 채용 정보
    • 사전

      서비스

    • IT 자문
    • 소프트웨어 개발
    • 백엔드 개발
    • 프론트엔드 개발
    • Staff Augmentation
    • 백엔드 개발자
    • 클라우드 엔지니어
    • 데이터 엔지니어
    • 기타
    • QA 엔지니어

      리소스

    • 외부 소프트웨어 개발 파트너와의 협력에 대한 사실과 오해
    • 미국에서 유럽으로: 미국 스타트업이 유럽으로 이전을 결정하는 이유
    • 테크 오프쇼어 개발 허브 비교: 테크 오프쇼어 유럽(폴란드), 아세안(필리핀), 유라시아(터키)
    • CTO와 CIO의 주요 과제는 무엇인가요?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • 웹사이트 이용 약관

    저작권 © 2025 by The Codest. 모든 권리 보유.

    ko_KRKorean
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese es_ESSpanish nl_NLDutch etEstonian elGreek ko_KRKorean