Whiteship's Note


Maven 같지 않은 Maven 프로젝트 만들기

Build/Maven : 2008.10.21 15:28


사용자 삽입 이미지

위 프로젝트는 일반적인 이클립스의 웹 프로젝트와 다름 없이 src와 test 소스 폴더를 가지고 있고, 웹 폴더도 루트바로 밑에 webapp를 사용하고 있습니다. 하지만, 이 녀석은 메이븐 프로젝트 입니다. 맨 아래에 pom.xml 보이시죠?

사부님이 전에 작성하셨던 메이븐 기본 디렉터리 설정 방법과 Arawn님의 메이븐 웹 폴더 설정 플러긴 사용방법을 조합하면 위와 같은 프로젝트를 만들 수 있습니다.

둘 다 pom.xml의 build 엘리먼트 내부에 적절하게 넣어주면 됩니다.

<build>
...
        <sourceDirectory>${project.basedir}/src</sourceDirectory>
        <scriptSourceDirectory>
            ${project.basedir}/scripts
        </scriptSourceDirectory>
        <testSourceDirectory>
            ${project.basedir}/test
        </testSourceDirectory>
        <resources>
            <resource>
                <directory>${project.basedir}/src</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
        </resources>
...
        <plugins>
...
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1-alpha-2</version>
                <configuration>
                    <warSourceDirectory>webapp</warSourceDirectory>
                </configuration>
            </plugin>
...
        </plugins>
<build>

설정 내용은 엘리먼트 이름을 보면 대충 알 수 있으면 자세한 설명은 사부님과 Arawn님의 블로그에 가셔서 보시면 되겠습니다. ㅋㅋ
top


AspectJ의 @DeclareError를 사용해서 컴파일 시점에 아키텍처 에러 검증하자.

AOP : 2008.10.21 11:26


참조: http://www.parleys.com/display/PARLEYS/Home#slide=1;title=Spring%20Architectures;talk=20676612

위 발표자료 내용 주에 아주 잼나는 코드를 건졌습니다. 지난 번 KSUG에서 발표한 내용과 겹치는데 아래 코드는 그때 제가 보여드린 코드보다 좀 더 좋은 것 같아서 가져왔습니다.

@Aspect
public class SystemArchitecture {
  @Pointcut("execution(* configurator.*.*(..))")
  public void configuratorLogic () {}
  @Pointcut("execution(* dao.*.*(..))")
  public void dao() {}
  @Pointcut("within(*.dao.*)")
  public void inDaoLayer() {}
  @Pointcut("call(* *.service.*.*(..))")
  public void callServiceLayer() {}
}


@Aspect
public class Layering {
  @DeclareError("SystemArchitecture.inDaoLayer() && "+
   "SystemArchitektur.callServiceLayer() ")
  public static final String DAOsNotFromServices =
   "DAO must not call Service!";
 @DeclareError(" (call(* java.sql.*.*(..)) && " +
  "!within(*.dao.*) ) ")
  public static final String JdbcOnlyInDAOs =
   "JDBC only in DAOs!";
}

좋은 건 이Aspectj를 사용하면 @DecalreError를 사용해서, 컴파일 시점에 아키텍처 에러를 검증할 수 있다는 것입니다. 제가 준비했던 코드는 cflow를 사용해서 런타임에 검증하는 방법이었습니다. 따라서 테스트 하지 않고 그냥 커밋하면 뭐 어떻게 찾아낼 방법이 없었습니다. 그런데 이 방법을 쓰면 코딩할 때 문제되는 코드를 발견할 수 있으니 훨씬 좋은 것 같습니다. 캬.. 귿..


top


Spring Architecture - Eberhard Wolff



참조: http://www.parleys.com/display/PARLEYS/Home#slide=1;title=Spring%20Architectures;talk=20676612

아키텍처
The software architecture of a program or computing system is the structure or structures of the system, which comprise software components, the externally visible properties of those components, and the relationships between them.

Wikipedia

객체: Information hiding

클래스: 객체의 타입을 정의. White box 재사용.

재사용:
A Software Component is a unit of composition with contractually-specified interfaces and explicit  context dependencies only. A software component can be deployed independently and is subject to composition by third parties.

C. Szyperski: Component Software - Beyond Object-
Oriented Programming, Addison-Wesley, 1999

컴포넌트: note the plugability.
- 계약 같은 인터페이스
- Only 명시적인 의존성
- 독립적인 배포
- 컴포지션
- 결과: 간편한 재사용(black box)
- 결과: 간편한 수정(인터페이스는 놔두고 내부만 바꿀 수 있으니.)

객체는 컴포넌트인가?
- 계약 같은 인터페이스? 있네, public 메소드
- 명시적인 의존성? 없네. 코드 내부에서 암거나 만들 수 있으니까.
- 독립적인 배포? 대부분은 안 돼지.
- 컴포지션? No.

DI를 사용하는 객체는 컴포넌트?
- 계약 기반인가? 응
- 명시적인 의존성? 응 설정하자나. setter/constuctor injection,
- 독립적인 배포? Yes. Everything else is injected
- 컴포지션? Yes. DI 컨테이너를 사용해서 조합하니까.

계층
- 각각의 계층은 하위 계층에만 의존해. -> 더 나은 의존성 관리(계층을 쉽게 바꿀 수 있으니까..)
- Typical technical
- 퍼사드를 사용할 수 있음.

스프링을 사용하는 컴포넌트
- 스프링 설정 파일을 각각의 컴포넌트 별로 만든다.
- 추가적인 기반 설정 파일은 javase.xml로..
- Facade를 인터페이스로 추가하고, bean 설정 파일에서 의존성을 정의한다.
- 각각의 컴포넌트는 JAR 파일로.
- 자신만의 빌드 스크립트를 가지고 있고
- 그들 컴포넌트를 묶을 때는 classpath*을 사용한다.

ApplicationContext applicationContext =
 new ClassPathXmlApplicationContext(
  "classpath*:/config/applicationContext.xml");

스프링 설정 파일 + Facade 사용했을 때 컴포넌트 체크 리스트
- Contractually-specific 인터페이스? Yes. Facade 사용했으니까.
- Only explicit context depedencies? No. 스프링 빈 의존성이 명시적이지 않을 수도 있다.
- 독립적인 배포 가능? Yes. 설정 파일 + 참조하는 클래스
- A way of composition? Yes. 스프링 DI.

계층은 어떤가?
- ApplicationContext 계층 구조를 사용해서 구현했다.
- DispatcherServlet과 ApplicationContext 같은 예.
- 예제 코드

ApplicationContext environmentApplicationContext =
 new ClassPathXmlApplicationContext(
  "javase.xml");

ApplicationContext persistenceApplicationContext =
 new ClassPathXmlApplicationContext(
  new String[] { "classpath*:*-persistence.xml" },
 environmentApplicationContext);

ApplicationContext logicApplicationContext =
 new ClassPathXmlApplicationContext(
  new String[] { "classpath*:*-logic.xml" },
  persistenceApplicationContext);

ApplicationContext guiApplicationContext =
 new ClassPathXmlApplicationContext(
  new String[] { "classpath*:*-gui.xml" },
  logicApplicationContext);

Vertical Slices.
- 예제 코드

ApplicationContext environmentApplicationContext =
 new ClassPathXmlApplicationContext("javase.xml");

ApplicationContext catalogApplicationContext =
 new ClassPathXmlApplicationContext(
  new String[] { "classpath*:/catalog-*.xml"},
 environmentApplicationContext);

ApplicationContext configuratorApplicationContext =
 new ClassPathXmlApplicationContext(
  new String[] { "classpath*:/configurator-*.xml" },
 catalogApplicationContext);

ApplicationContext trackingApplicationContext =
 new ClassPathXmlApplicationContext(
  new String[] { "classpath*:/tracking-*.xml"},
configuratorApplicationContext);

이후 발표는...
- 스프링 JavaConfig를 사용해서 스프링을 사용해서 컴포넌트 설정 예제
- 스프링 DM을 사용하여 컴포넌트 개발 예제
가 이어집니다.

top


OSGi 툴 세트 Pax

Spring DM/OSGi : 2008.10.21 00:16


홈피 http://wiki.ops4j.org/confluence/display/ops4j/Open+Participation+Software+for+Java

관련글 http://www.jroller.com/habuma/entry/is_your_osgi_toolset_pax

'Spring DM > OSGi' 카테고리의 다른 글

OSGi 툴 세트 Pax  (0) 2008.10.21
Shared Mutable State  (2) 2008.09.25
The Price of Freedom  (0) 2008.09.25
Concurrency and OSGi  (0) 2008.09.25
BundleContext로 할 수 있는 일  (0) 2008.06.25
2 Security Layer  (0) 2008.02.18
1. Introduction  (0) 2008.02.17
top

TAG OSGi, tool

게시판 페이징은 어떤 기능을 갖추고 있어야 할까?



봄싹 스터디에서 게시판을 구현하기로 했습니다. 간단한 CRUD와 페이징처리가 주 목적이며, 저를 포함한 대, 여섯 명의 개발자 분들이 자기 나름대로 구현해온 코드를 서로 보여주고 피드백을 받는 방식으로 진행될 예정입니다. 이를 통해 스프링을 실제 프로젝트에 적용하는 방법은 물론이거니와, 게시판 구현 방법에 대한 고민도 나눌 수 있을 것 같고, 개발 전반에 좋은 코드, 좋은 개발 방법 및 현재 자신에게 필요한 학습은 무엇인가에 대한 고민까지도 해볼 수 있는 좋은 스터디로 생각하고 있습니다.

Anyway, 기존 애플리케이션들의 UI를 보면서 페이지 네비게이션을 어떻게 구현하면 좋을지 고민해봤습니다.

Gmail


- 처음은 일단 가장 최신 글(메일)을 보여주고, "이전" 과 "처음"이 있군요.
- "이전"을 클릭하면 "이전" 과 "처음"은 그대로 있고, "다음"이 추가됩니다.
- 또 한 번 "이전"을 클릭하면 "이전"과 "처음", "다음"은 그대로 있고, "최근"이 추가됩니다.

두 번째에서 "다음"만 추가한 건 "다음"이 곧 "최근"이기 때문이죠. 이런 페이징의 단점은 중간으로 이동할 수가 없다는 겁니다. "다음"만 10번 눌렀다가 세 번째 페이지로 이동하고 싶을 땐 어떻게 하죠?? 바로 이동할 수 있는 방법은 없습니다. "최근"으로 갔다가 "이전"을 세 번 클릭하는 수밖에..

한 페이지에 보이는 목록의 갯수 설정은 환경 설정에서 할 수 있습니다. 기본으로 50개씩 보여주는데, 이 설정을 별도의 페이지로 옮겨둔건 좋은 것 같습니다. 자주 바꾸는 설정도 아닐텐데 자꾸 눈에 들어오면 괜히 한 번 해보고싶고, 그럼 괜히 불필요한 요청만 늘어날 뿐이니까요. 이런 경우에는 대신 모델 설계가 좀 달라질 것 같습니다. 게시판에 대한 설정을 담고 있는 별도의 모델이 있고 그 모델의 속성으로 한 페이지당 목록 갯수가 들어있을 것 같습니다. 반대로, 만약 페이지와 한 페이지에 대한 목록 갯수가 같이 따라 다닌다면, 페이징 관련 모델에 한 페이지 목록 갯수가 속성으로 들어있겠죠?

Forum


KSUG 포럼 게시판의 페이징을 봤습니다. 처음 모습 그대로를 유지하고, 버튼의 색으로 현재 페이지를 구분하고 있습니다. 일단 위에서 언급했던 중간 페이지로의 이동이 가능해졌습니다. 대신, 여기서도 한 페이지당 갯수 설정 화면은 보이지 않습니다. 어딘가 게시판 설정 페이지에 있을 것 같습니다. 포럼과 Gmail과의 공통점은 둘 다 거의 한 페이지의 내용이 브라우저 범위를 벗어나서 스크롤리 필요하다는 겁니다. 그래서인지, 페이지 네비게이션이 화면의 가장 상단과 가장 하단 두 곳에 모두 위치하고 있습니다. 이런 UI가 사용자에 편하다는 반증으로 생각됩니다. 따라서 화면을 만들 때 네비게이션 부분을 컴포넌트화 해야겠다는 생각이 듭니다. 그래야 코드 중복도 최소화 하고 관리하기 쉬울테니까요.

게시판


제가 자주가는 어떤 사이트의 게시판에 있는 페이지 네비게이션 부분을 봤습니다. 고정이라는 측면에선 포럼과 동일했습니다만, 게시물 갯수에 대한 정보는 없었습니다. 게시물 목록에서 해당 게시물의 번호를 가지고 있는데 그 번호가 그런 정보를 줄테니 굳이 필요 없었던 것 같습니다. 다만, 게시물 번호가 그다지 사실상 사용자에게 그리 의미가 있는지는 모르겠습니다. 게시물을 어떤 URL로 접근하는 것과, 게시물의 번호로 게시물에 접근하는 것의 차이는 좀 크다고 봅니다. 개인적으로는 URL로 게시물에 접근하는게 더 타당해 보이니, 번호는 사실 필요 없다는 생각입니다. 그리고 이 게시판은 한 페이지 목록 수가 작아서 네비게이션을 자주 해야 합니다. 대신에 네비게이션 바는 화면의 맨 하단에 하나만 위치하고 있습니다. 한 화면에 전부 눈에 들어오기 때문에 위의 두 경우처럼 위, 아래 두 곳에 네비게이션 바를 둘 필요는 없다고 생각했을지도 모르는데.. 뭐 타당해 보입니다. 여기서도 한 페이지당 목록 수를 설정하는 화면은 보이지 않습니다.

하아~~ 페이징 어떻게 구현할까나..
top