'분류 전체보기'에 해당되는 글 648건

  1. 2022/08/22 용비 Chapter 2. Organizing Domain Logic
  2. 2022/08/22 용비 Chapter 1. Layering
  3. 2021/11/17 용비 06. Javadoc
  4. 2021/11/17 용비 05. Practice
  5. 2021/11/17 용비 04. Naming

Chapter 2. Organizing Domain Logic

(도메인 로직 구성)

도메인 로직을 구성할 때, 트랜잭션 스크립트, 도메인 모델, 테이블 모듈 3가지 기본 패턴으로 구분.
트랜잭션 스크립트 : 도메인 로직을 저장하는 가장 간단한 방법. 프리젠테이션에서 입력값을 가져와서 유효성 검사 및 계산 처리하고 데이터베이스에 데이터를 저장하고, 다른 시스템에서 작업을 호출하는 절차. 프레젠테이션에 데이터를 응답. 작업에 대한 절차이므로 프리젠테이션에서 호출하는 모든 기능을 트랜잭션 스크립트라고 할 수 있음.

트랜잭션 스크립트의 장점
- 대부분의 개발자들이 이해하는 간단한 절차 모델
- Row Data Gateway or Table Data Gateway를 사용하는 단순 데이터 소스 계층과 잘 동작함
- 트랜잭션을 열고 닫는 것으로 트랜잭션 경계를 명확하게 설정

도메인 모델 : 복잡한 논리를 해결하는 것은 도메인 모델을 사용하는 것. 명사로 이루어진 도메인 주위에 도메인 모델(클래스)을 구축. 각 클래스에 연관된 로직을 배치. 트랜잭션 스크립트와 반대되는 도메인 모델의 사용은 객체 지향에서 이야기하는 패러다임 전환의 본질임. 사용자의 Action에 대한 모든 로직이 있는 하나의 루틴이 아니라, 각 객체별 관련된 논리가 분산되어 있음. 시퀀스 다이어그램도 객체 중심으로 그림. 도메인 모델의 가치는 우선 익숙해지면, 점점 더 복잡해지는 로직을 잘 구조화된 방식으로 처리할 수 있는 많은 기술적 방법이 있다는 것.
트랜잭션 스크립트는 새로운 조건이나 알고리즘이 추가되면 코드 내 분기로 추가하게 되지만, 도메인 모델은 기존 코드를 수정하지 않고 새로운 메소드나 클래스를 추가하면 됨.

테이블 모듈 : 데이터베이스에서 쿼리로 필요한 데이터를 가져다 놓고, 요청에 따라 해당 데이터 결과를 리턴.

Making a Choice (선택)

3가지 패턴은 상호 보완적임. 대부분 도메인 모델로 시작하지만, 일부 로직에서는 트랜잭션 스크립트를 사용하고, 다른 부분에서는 도메인 모델이나 테이블 모듈을 사용할 수 있다.

Service Layer

도메인 로직을 처리하는 일반적인 방법은 도메인 레이어를 둘로 나누는 것이다. 서비스 레이어는 기본 도메인 모델이나 테이블 모듈 위에 위치한다. 트랜잭션 스크립트만 사용하는 도메인 레이어는 레이어 분리의 유익한 점이 없기 때문에 도메인 모델이나 테이블 모듈에서만 레이어 분리로 인한 잇점을 얻을 수 있다.
프리젠테이션 로직은 어플리케이션에 대한 API 역할을 하는 서비스 레이어를 통해서 도메인과 상호작용을 한다.

서비스 레이어는 명확한 API를 제공할 뿐만 아니라, 트랜잭션이나 보안을 처리하는 좋은 위치이기도 하다. 대부분의 비즈니스 로직은 서비스 레이어의 트랜잭션 스크립트에 위치함. 하위에 위치한 도매인 객체는 매우 간단하다. 도메인 모델이 데이터베이스와 1:1이다. 컨트롤러-엔터티 스타일에 해당함. MVC, Application Controller라고도 함.

고정된 레이어를 만들면 안 됨.
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/894

이 글은 Martin Fowler의 "Patterns of Enterprise Application Architecture"의 내용을 번역, 요약 & 발췌하여 정리한 글입니다.

Chapter 1. Layering

Layer와 Tier : Layer는 역할과 책임을 명확하게 구분할 수 있는 논리적인 구분이고, Tier는 물리적인 구분.
하나의 Tier에 모든 Layer를 구현하여 동작시킬 수 있음.

<The three principle layer>
 1) Presentation (UI) : 사용자와 소프트웨어간 인터페이스를 담당하는 로직. 사용자에게 정보를 보여주고, 사용자의 command를 해석하여 비즈니스 로직이나 데이터 소스로부터 실제적인 액션을 수행하게 함
 2) Domain (Business) : 시스템의 실제적인 비즈니스 로직을 수행. 응용 프로그램이 도메인에 대해 수행해야 하는 작업을 나타냄.
 3) Data Source (Data) : 응용 프로그램을 위한 작업을 수행하는 다른 시스템과의 통신하는 것. 트랜잭션 모니터링, 메시징 시스템, 등. 대부분 데이터베이스를 사용함.

Choosing Where to Run Your Layers (레이어를 실행할 위치 선택)

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/893

06. Javadoc

Programming Style Guide/java 2021/11/17 17:50 용비

개발자를 위한

Java Programming Style Guide (ref. Google style guide)

7. 문서화 (javadoc) 

7.1 서식(formatting)

1. 일반 서식 (General form)

Javadoc 블록의 기본적인 형식은 다음 예제에서 보는 것과 같습니다.

/**

 * Multiple lines of Javadoc text are written here,

 * wrapped normally...

 */

public int method(String p1) { ... }


또는 다음과 같은 하나의 라인으로 작성할 있습니다.

/** An especially short bit of Javadoc. */


기본적인 형식(basic form) 항상 허용됩니다. Javadoc 블록 전체(주석 표시 포함) 하나의 라인으로 작성할 있는 경우는 형식으로 대체될 있습니다. @return 같은 블록 태그가 없는 경우에만 해당됨을 유의하세요.

2. 단락(Paragraphs)

정렬된 선행 별표(aligned leading asterisk:’*’) 포함하고 있는 하나의 줄은 단락 사이와 블록 태그 그룹이 있을 경우 태그 그룹 앞에 나옵니다. 첫번째 단락을 제외한 단락은 첫번째 단어 바로 앞에 <p> 태그가 있고, 뒤에는 공백이 없습니다.

3. 블록 태그(Block tags)

코드에 사용하는 표준블록 태그(block tags)” @param, @return, @throws, @deprecated 순서로 사용되며, 4가지 유형은 설명이 비어 있으면 됩니다. 블록 태그가 줄에 맞지 않으면 @위치에서 4 이상의 스페이스로 들여쓰기를 합니다.

7.2 요약 단편(the summary fragment)

Javadoc 블록은 간단한 요약 단편으로 시작합니다. 단편적인 요약은 매우 중요합니다.  클래스나 메서드 인덱스처럼 특별한 컨텍스트(context)에서 나타나는 텍스트의 유일한 부분입니다.

단편은 완전한 문장이 아니라 명사구나 동사 구절입니다. A {@code Foo}처럼 시작하지도 않고, “This method returns…” 시작하지도 않고, “Save the rcord..” 같은 완전한 명령형 문장의 형태로 시작하지도 않습니다. 하지만, 요약 단편에는 완전한 문장인 것처럼 대문자와 구두점이 있습니다.

Tip : 일반적으로 /** @return the customer ID */ 같이 Javadoc 작성하는 실수를 하게 됩니다. 이것은 잘못된 것입니다. /** Returns the customer ID */처럼 변경해야 합니다.

7.3 Javadoc 사용처(where javadoc is used)

최소한, Javadoc 모든 public class 클래스에 있는 public, protected 멤버에 관해 존재하지만, 아래 언급된 가지 예외가 있습니다.

아래 3 Non-required Javadoc 설명되어 있는 것처럼, 추가적인 Javadoc 컨텐츠가 있을 있습니다.

1. 예외(Exception) : 자체 서술적인 메서드 (self-explanatory methods)

getFoo 같이단순하고 분명한(simple, obvious)” 메서드에 대해서 Javadoc 작성하는 것은 선택 사항입니다. 경우처럼, “Returns the foo”라고 말하는 이외 아무것도 말할 가치가 없는 경우도 있습니다.

중요(important) : 일반적으로 독자가 필요가 있는 관련 정보를 생략하는 것을 정당화하기 위해 위에 언급된 예외를 적용하는 것은 적합하지 않습니다. 예를 들어, getCanonicalName 메서드의 경우, 일반 독자가표준 이름(canonical name)”이라는 용어가 무엇을 의미하는지 모를 경우 해당 Javadoc 문서(단지 /** Returns the canonical name. */만을 말하고자 하는 이유일지라도) 생략하면 됩니다.

2. 예외(Exception) : 재정의(override)

상위 유형(supertype) 메서드를 재정의하는 경우에는 항상 Javadoc 존재하는 것은 아닙니다.

3. 불필요한 경우 (Non-required Javadoc)

다른 클래스와 멤버의 경우, 필요에 따라 Javadoc 있습니다.

구현 주석(implementation comments) 클래스나 멤버 전체의 목적이나 동작에 대해 정의하는데 사용되는 경우, 해당 주석은 Javadoc으로 작성될 있습니다. (/** 사용)

불필요한 경우의  Javadoc(non-required javadoc) 위에서 정리한 단락(Paragraphs)이나 블록 태그(Block tags), 요약 단편(Summary fragments) 형식을 따르도록 엄격하게 요구되지는 않지만, 있으면 정해진 형식을 따르기를 권고합니다.  

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/892

05. Practice

Programming Style Guide/java 2021/11/17 17:49 용비

개발자를 위한

Java Programming Style Guide (ref. Google style guide)

6. 프로그래밍 실습 (Programming practices) 

6.1 @Override: always used

메서드(method) 합법적일 때마다 @Override 어노테이션(annotation)으로 표시됩니다. 여기에는 슈퍼클래스(super class) 메서드를 재정의(override)하는 클래스 메서드, 슈퍼인터페이스(super interface) 메서드를 재지정(respecifying)하는 인터페이스 메서드를 포함합니다.

예외(Exception) : @Deprecared 경우에는 @Override 생략할 있습니다.

6.2 Caught exceptions: not ignored (예외가 발생했을 , 무시하지 )

아래 언급된 경우를 제외하고, 예외가 발생했을 (caught exception) 아무런 응답을 하지 않는 것은 매우 드문 경우입니다. (일반적으로 응답(response) 기록해야 합니다. 만약 기록이 불가능(“impossible”)하다고 여겨지는 경우에는 AssertionError 다시 발생(rethrow)시킵니다.)

Catch 블록에서 아무 조치도 취하지 않는 것이 정말 적합할 경우, 정당화되는 이유가 코멘트로 설명되어 있습니다.

try {

  int i = Integer.parseInt(response);

  return handleNumericResponse(i);

} catch (NumberFormatException ok) {

  // it's not numeric; that's fine, just continue

}

return handleTextResponse(response);


예외(Exception) : 테스트에서 발견된 예외는 이름이 기대되는 예외일 경우, 주석없이 무시될 있습니다. 다음 코드는 예상되는 예외를 확인하기 위한 아주 일반적인 관용구이기 때문에 주석이 필요하지 않습니다.

try {

  emptyStack.pop();

  fail();

} catch (NoSuchElementException expected) {

}


6.3 정적 멤버(static members): 클래스를 사용하여 한정(qualified using class)

정적 클래스 멤버(static class member) 대한 참조(reference) 규정되어야 하는 경우, 클래스 유형(class type) 참조나 표현식이 아니라 해당 클래스 이름으로 규정되어야 합니다.

Foo aFoo = ...;

Foo.aStaticMethod(); // good

aFoo.aStaticMethod(); // bad

somethingThatYieldsAFoo().aStaticMethod(); // very bad


6.4 종료자(finalizers) : 사용하지 않음(not used)

Object.finalize 재정의(override)하는 것은 극히 드문 경우입니다. 사용하지 않습니다.

Tip : 사용하지 마십시오. 반드시 사용해야 같으면, 먼저 Effective Java 항목 7 “종료자 피하기(Avoid Finalizers)” 매우 주의 깊에 읽고 이해한 다음에 사용하지 마세요.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/890

04. Naming

Programming Style Guide/java 2021/11/17 17:48 용비

개발자를 위한

Java Programming Style Guide (ref. Google style guide)

5. 네이밍(naming)


5.1 모든 식별자에 적용되는 공통 규칙(rules common to all identifiers)

식별자(identifier) ASCII 문자와 숫자만 사용하며, 아래에 언급된 소수의 경우에만 밑줄(underscore) 사용합니다. 따라서, 유효한 식별자 이름은 정규식(regular expression) \w+ 일치합니다.

(구글 스타일에서는) 특수한 접두사나 접미사를 사용하지 않습니다. 예를 들어, name_, mName, s_name, kName 같은 이름은 (구글) 스타일이 아닙니다.

5.2 식별자 유형별 규칙(rules by identifier type)

1. 패키지 (Package names)

패키지 명은 모두 소문자이며, 연속된 단어는 간단하게 서로 연결됩니다. (밑줄 없음) 예를 들어, com.example.deepSpace com.example.deep_space 아니라 com.example.deepspace 패키지명을 작성합니다.

2. 클래스 (Class names)

클래스 이름은 UpperCamelCase(단어가 시작되는 한글자를 대문자로 작성하는 유형) 작성합니다. 클래스 이름은 일반적으로 명사나 명사구입니다. 예를 들어, Character ImmutableList 같습니다. 인터페이스(Interface) 이름은 명사나 명사구(예를 들면, List) 수도 있지만, 때로 형용사나 형용사구가 수도 있습니다. ( : Readable)

어노테이션 유형의 명명(naming annotation type) 대해서는 특정 규칙이나 정립된(well-established) 규정(convention) 없습니다.

테스트 클래스(Test class) 테스트 중인 클래스 이름으로 시작하여 Test 끝나는 이름으로 명명합니다. : HashTest 또는 HashIntegrationTest

3. 메서드 (Method names)

메서드 이름은 lowerCamelCase( 한글자는 소문자로, 다음 단어의 한글자는 대문자로 작성하는 유형) 작성합니다. 메서드 이름은 일반적으로 동시 또는 동사구로 작성합니다. 예를 들면 다음과 같습니다. 

Ex) sendMessage 또는 stop

밑줄은 lowerCamelCase 작성된 컴포넌트와 이름을 논리적으로 구분하기 위해 JUnit 테스트 메서드에 나타날 있습니다. 한가지 일반적인 패턴은 <methodUnderTest>_<state> 형태입니다. (: pop_emptyStack). 테스트 메서드의 이름을 지정하는 한가지의 완벽한 방법은 없습니다.

4. 상수 (Constant names)

상수 명은 CONSTANT_CASE 같은 유형을 사용합니다. 상수 명은 모두 대문자이며, 단어는 하나의 밑줄로 다음 단어와 구분됩니다. 하지만, 정확하게 상수가 무엇일까요?

상수는 내용이 변경되지 않고(immutable), 메서드에 부작용(side effect) 전혀 없는 static final field 입니다. 여기에는 기본형(primitives), 스트링형(Strings), 불변 유형(immutable type), 불변 유형의 불변 컬렉션(immutable collection) 포함됩니다. 만약 인스턴스의 관찰 가능한 상태가 변경될 있다면, 그것은 상수가 아닙니다. 객체를 변경하지 않으려는 의도만으로는 충분하지 않습니다.

예를 들면 다음과 같습니다.

// Constants

static final int NUMBER = 5;

static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");

static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Ed", 35, "Ann", 32);

static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable

static final SomeMutableType[] EMPTY_ARRAY = {};

enum SomeEnum { ENUM_CONSTANT }


// Not constants

static String nonFinal = "non-final";

final String nonStatic = "non-static";

static final Set<String> mutableCollection = new HashSet<String>();

static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);

static final ImmutableMap<String, SomeMutableType> mutableValues =

    ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2);

static final Logger logger = Logger.getLogger(MyClass.getName());

static final String[] nonEmptyArray = {"these", "can", "change"};


이러한 이름은 일반적으로 명사나 명사구입니다.

5. 비상수 필드 (Non-constant field names)

상수가 아닌 필드 (non-constant field name) (static이든 아니든) lowerCamelCase 작성됩니다.

이러한 이름은 일반적으로 명사 또는 명사구로 작성됩니다.

예를 들면 다음과 같습니다.

Ex) computedValues 또는 index

6. 파라미터 (Parameter names)

파라미터(매개변수 : parameter) 명은 lowerCamelCase 작성됩니다.

Public 메서드에서 단일 문자 파라미터 이름은 피해야 합니다.

(다른 사람이 변수 명을 이해할 없습니다.)

7. 지역 변수 (Local variable names)

지역 변수 명은 lowerCamelCase 작성합니다. final이나 immutable 경우에도, 지역 변수는 상수로 간주하지 않으며 상수 스타일로 코드를 작성하면 됩니다.

8. 유형 변수 (Type variable names)

유형 변수 명은 다음 2가지 스타일 하나로 작성합니다.

 - 단일 대문자, 선택적으로 뒤에 단일 숫자 추가 (ex. E, T, X, T2)

 - 클래스에 사용되는 형태의 이름 뒤에 대문자 T (ex. RequestT, FooBarT)

5.3 카멜 케이스(camel case : defined)

“IPv6”이나 “iOS” 같이 두문자어나 특이한 구조가 있는 경우처럼 영어 구문을 Camel Case(영어 대소문자로 변환) 변환하는 합리적인 방법이 한가지 이상 있습니다. 예측 가능성을 개선하기 위해서 Google Style 표준에서는 다음과 같은 (거의) 결정적인 스키마를 지정합니다.


산문형 이름으로 시작 : 

1. 어구를 ASCII 변환하고 Apostrophe(‘) 제거하세요. 예를 들어, “Müller's algorithm” “Muellers algorithm”으로 변환됩니다.

2. 결과를 공백과 나머지 구두점(punctuation)으로 (일반적으로 hypen: ‘-‘)으로 분할하여 나눕니다.

    • 권장(Recommended) : 이미 전통적인 Camel Case 일반적으로 사용하고 있다면, 구성요소로 분할합니다. ( : AdWord ad word 분할됨) 하지만, “iOS” 같은 경우는 Camel Case 아니기 때문에 어떤 규칙에도 위배됩니다. 따라서 권장사항은 적용되지 않습니다.

3. 모든 항목(약어 포함) 소문자로 만든 다음, 첫번째 문자만 대문자로 합니다.

    • 단어를 Upper Camel Case 사용하거나, ( 단어의 첫글자를 대문자로)
    • 단어의 첫번째 글자를 제외하고,  Lower Camel Case 사용합니다. ( 단어의 첫글자 소문자, 다른 단어의 첫글자는 대문자로)

4. 끝으로, 모든 단어를 단일 식별자로 결합합니다.

원래 단어의 대소문자는 거의 대부분 무시되는 것에 유의하세요.

:

Prose form

Correct

Incorrect

"XML HTTP request"

XmlHttpRequest

XMLHTTPRequest

"new customer ID"

newCustomerId

newCustomerID

"inner stopwatch"

innerStopwatch

innerStopWatch

"supports IPv6 on iOS?"

supportsIpv6OnIos

supportsIPv6OnIOS

"YouTube importer"

YouTubeImporter

YoutubeImporter*


YoutubeImporter* : 수용 가능하지만, 권장하지 않습니다.


Note : 일부단어는 영어에서 모호하게 ‘-‘으로 연결됩니다. : 예를 들어, “nonempty” “non-empty” 모두 정확하기 때문에 checkNonempty, checkNonEmpty 모두 정확한 표현입니다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/889