2008년 11월 21일 금요일

금연... 담배... 술집... 이런 것 이었을까?


어제는 좀 안좋은 사건이 발생하는 바람에...
기분도 우울하고...
술생각도 나고...
겸사 겸사 울 마나님하고 데이트도 할겸...

가끔 일산에서 꼬치생각나면 가는 투다리집에
예전 데이트하던 생각으로 찾아갔다.

생각해보니...

금연한 이후로는 이 투다리집에 자주 오지 못한듯 한데.

.
.
.

다른 것은 잘 모르겠지만.

아! 이것이 간접흡연의 피해이구나.

나도 담배를 줄기차게 피우던
해비스모커였는데...

어제 투다리집의 모든 테이블들은...
우리 테이블 빼고서는..
모든 사람들이 담배를 피우고 있었다.

ㅡㅡ;

결국...
맥주 2000cc는 먹었지만...

그 흡연때문에...
나도 목이 칼칼해서...

1시간정도만
투다리집에 있다가
자리에서 일어나
집으로 걸어갔다.

아!

금연을 하니 좋기는한데...
담배연기가 이렇게 역하고 괴로웠는지
몰랐다.

ㅡㅡ;

그동안
나랑 다니면서...

군소리(?)없이
따라다녀준 우리 이쁜 마눌님에게
고마움을 표시해야할려나?

좌우당간...

담배연기...
정말 ...

ㅡㅡ;

이제 금연합시다.

우리의 사랑스러운 가족들을 위해서...

2008년 11월 20일 목요일

아침에 찍은 둘째 아들 민철이의 귀여운 모습...



아마도 위에 쓴 모자(?)가...
프로방스 마을에서 구입한 '백호'입니다.

~.~

따뜻해보이죠?

저도 하나쓰고 다니고 싶더군요.. ㅋㅋ


저 뒤에서...
잠깐 짬을 이용해서 '만화책'을 보는...
큰 아들 수철이..

~.~

좌우당간...

이쁜 막내아들..

귀여워!

자가발전 손전등... 반영구적 손전등...


얼마전 용산에 들렀다가...
시간이 남아서 편의점 앞에서 음료수를 마시다가 문득 좌판위에서 발견한 제품입니다.


기본적인 모습은 위의 사진과 같습니다.


약간 옆에서 보면... 앞에 라이트가 있고, 위에 스위치, 뒤에 점멸등이 보이고...
좌측에 손잡이가 보입니다.


전원을 켜면... '라이트'가 들어옵니다. LED조명인데... 3개의 LED전구가 있어서...
그럭저럭...
쓸만한 불빛이 나타납니다.


스위치를 뒤로 키면...
붌은색 빛으로 점멸이 되죠.

~.~



실제 점멸되는 동영상은 위와 같이 보입니다.

뭐... 자전거를 타거나 할때에 이용할 수 있거나..
혹은...
밤에 자신의 위치를 표시하는 수단으로 활용될 수 있겠죠.

~.~

그리고...

이 자가발전기 손전등의 발전은...

~.~

한손으로 휴대폰촬영을 해서 좀 어색하긴 하지만..



좌우당간...

좌측의 손잡이를 아주 세지는 않지만...
몇분 돌려주면...
충분한 전력을 생산할 수 있네요.

밤에는 움직이면서...
계속 돌리니...

쭈욱 사용할 수 있고...

집에 한개쯤 두면...
가끔 손전등 필요시에 사용하기도 좋더군요.

아!

야영가서도 유용하게 사용되지 않을까합니다.

~.~

마지막으로 총평...

1. 머.. 반영구적일 것 같지는 않다. LED 수명이 길기는 하나.. ~.~
2. 오히려, 회전하는 손잡이가 먼저 부러질듯... ㅇㅇ; <- 이거 부러지면 끝이다.
3. 구입한 가격은 3천원... 머, 옥션뒤져보니 2500~5000원까지 다양한 제품들이 존재한다.
    재미삼아 구입해본다면 찬성... ㅋㅋ

2008년 11월 19일 수요일

손예진... 송혜교... 글쎄? 잘하는 것만 잘하면 안될까?


뭐... 두분의 팬들이 보게되면 '분노'할 이야기일 수도 있지만... ~.~
'도전'은 아름답지만...

'성공과 실패'는 결과일 뿐이고...

대중이 원하는 모습에 적당하게 어울려주는 것이...
그것이 '연예인'이지 않을까요?

배용준의 신비주의 전략또한...
일본 팬들이나 뭐.. 좌우당간, 그런 '이미지'를 소비하는 '고객'들이 존재하기 때문에..
아!

머 그역시.. '팬'들이 원하는 것 아닌가요?

멋진 장동건이 '태풍'에서 나온 거친 캐릭터보다는...

'귀여운 여인'의 '리차드 기어'와 같은 '캐릭터'의 모습을 기대하는 것은...
저뿐만이 아닐 것 같은데...

ㅇㅇ;

정말 잘생긴 그 외모로...
좀 멋진 연기를 해서...
수많은 사람들에게 '환상'을 좀 심어주면 안될까요?

뭐...

마찬가지로...

손예진씨나 송혜교씨나 나름 스타파워가 막강한 분들...

그냥...

대중이 좀더 원하는 이미지의 소비에 대해서도 조금은 신경써주시기를...
'연기'공부를 굳이...
'실제 드라마나 영화'에서 할 필요는 없지 않을까요?
( 머.. 이 대목에서 '돌'맞을 수도 있지만.. ㅋㅋ )

머...

그 포부는 포부이고...
'결과'는 결과일뿐...

너무 심각하게 받아들일 필요도 없으니까요.

ㅋㅋ

걍...

연예인이란 직업자체에서 오는 '포스'나... '환상'...
그런것도 어느정도 지켜주는 것이...

'스타'연예인들이 해야할 일들이 아닌지..
그냥 생각해봅니다.

[SA강좌] Part 4-8 Table Module 패턴

테이블 모듈(Table Module) 패턴

테이블 모듈 패턴의 정의

데이터베이스 테이블 또는 뷰에 있는 모든 행에 대한 비즈니스 로직을 다루기 위한 단일 인스턴스 패턴이다.

그림 Ⅴ-11. 테이블 모듈 패턴의 구조

테이블 모듈 패턴의 설명

테이블 모듈 패턴은 데이터베이스에 있는 테이블 마다 하나의 클래스에 대응하는 도메인 로직을 구성한다. 또한, 클래스의 단일 인스턴스는 데이터에 행동 할 수 있는 다양한 프로시저를 포한한다. 도메인 모듈 패턴과 비교되는 주요한 구분은 만일 많은 주문에 대한 처리를 원하는 경우 도메인 모듈 패턴은 주문 마다 하나의 주문 개체를 가지게 된다. 반면, 테이블 모듈 패턴은 모든 주문을 처리하기 위해 하나의 개체만을 가진다.

언제 이 패턴을 사용하는가?

테이블 모듈 패턴은 매우 테이블 지향 데이터에 기반한다. 그러므로, 레코드 집합 패턴을 사용하는 데이터 집합의 접근을 할 때 유용하다.

그러나, 테이블 모듈 패턴은 복잡한 로직을 구조화하는 개체들의 모든 능력을 제공하지는 않는다. 인스턴스 대 인스턴스 관계를 직접적으로 가지 않고, 다향성은 잘 작업되지 않는다. 이러한 이유로 복잡한 도메인 로직을 처리하기 위해서는 도메인 모델 패턴이 더 좋은 선택이 된다.

만일 도메인 모델 패턴에 있는 개체와 데이터베이스 테이블이 관계적으로 유사하면, 활동 레코드 패턴을 사용하는 도메인 모델 패턴을 사용하는 것이 좋다. 테이블 모듈 패턴은 도메인 모델 패턴과 활동 레코드 패턴을 사용하는 도메인 모델 패턴 보다 더 잘 작업한다.

[SA강좌] Part 4-7 Domain Model 패턴

도메인 모델(Domain Model) 패턴

도메인 모델 패턴의 정의

도메인 모델 패턴은 행동과 데이터가 협력하는 도메인의 개체 모델 패턴이다.

그림 Ⅴ-10. 도메인 모델 패턴의 구조

도메인 모델 패턴의 설명

나쁜 비즈니스 로직은 매우 복잡하다. 비즈니스 규칙과 로직은 많은 다른 사례와 행동에 편향적인 설명을 한다. 도메인 모델 패턴은 내부적으로 연결된 개체들의 망을 생성한다. 주문 양식에 있는 협력체 만큼이나 크거나 단일 라인 만큼 작은 각 개체는 몇몇 의미있는 개체를 표현한다.

도메인 모델 패턴은 언제 사용하는가?

만일 도메인 모델 패턴 사용을 생각한다면, 데이터베이스와 상호작용을 위한 첫 번째 선택은 데이터 매핑 패턴이다. 이 패턴은 데이터베이스에서 도메인 모델 패턴이 독립되도록 유지하고, 도메인 모델과 데이터베이스 스키마 차이가 발생하는 사례를 조작하기 위한 접근을 제공한다.

도메인 모델을 사용할 때, 서비스 레이어 패턴을 고려해야 한다. 이 패턴은 도메인 모델 패턴이 API에서 멀어지도록 한다.

도메인 모델 패턴의 적용 예제 : 세금 계산

직접적인 인식은 예제가 가지고 있는 행동과 데이터의 모든 클래스를 인식하는 것이다. 만일 개체의 값이 임의 데이트를 인식하면, 세금 인식 클래스는 검색을 위한 간단한 메서드를 아래와 같이 포함하게 된다.

class RevenueRecognition ...

private Money amount;

private MfDate date;

public RevenueRecognition(Money amount, MfDate date) {

this.amount = amount;

this.date = date;

}

public Money getAmount() {

return amount;

}

boolean isRecognizable(MfDate asOf) {

return asOf.after(date) || asOf.equals(date);

}

얼마나 많은 세금이 특정 일자에 인식 되었는지를 계산하는 것은 계약과 세금 인식 클래스를 포함한다.

class Contract ...

 

private List revenueRecognitions = new ArrayList();

public Money recognizedRevenue(MfDate asOf) {

Money result = Money.dollars(0);

Iterator it = revenueRecognitions.iterator();

while (it.hasNext()) {

RevenueRecognition r = (RevenueRecognition) it.next();

if (r.isRecognizableby(asOf))

result = result.getAmount();

}

return result;

}

도메인 모델에서 공통점을 찾기는 것은 얼마나 간단한 작업들이 다중 클래스들과 상호작용을 하는지를 인식하는 것이다.

class Contract ...

 

private Product product;

private Money revenue;

private MfDate whenSigned;

private Long id;

public Contract(Product product, Money revenue, MfDate whenSigned) {

this.product = product;

this.revenue = revenue;

this.whenSigned = whensinged;

}

 

class Product ...

 

private String name;

private RecognitionStrategy recognitionStrategy;

public Product(String name, RecognitionStrategy recognitionStrategy) {

this.name = name;

this.recognitionStrategy = recognitionStrategy;

}

public static Product newWordProcessor(String name) [

return new Product(name, new CompleteRecognitionStrategy());

}

public static Product newSpreadsheet(String name) {

return new Product(name, new TreeWayRecognitionStrategy(60,90));

}

public static Product newDatabase(String name) {

return new Product(name, new TreeWayRecognitionStrategy(30,60));

}

 

class RecognitionStrategy ...

 

abstract void calculateRevenueRecognitions(Contract contract);

 

class CompleteRecognitionStrategy ...

 

void calculateRevenueRecognitions(Contract contract) {

contract.addRevenueRecognitions(new RevenueRecognition(contract.getRevenue(),

contract.getWhenSigned());

}

 

class TreeWayRecognitionStrategy ...

 

 

private int firstRecognitionOffset;

private int secondRecognitionOffset;

public ThreeWayRecognitionStrategy(int firstRecognitionOffset,

int secondRecognitionOffset)

{

this.firstRecognitionOffset = firstRecognitionOffset;

this.secondRecognitionOffset = seondRecognitionOffset;

}

void calculateRevenueRecognitions(Contract contract) {

Money[] allocation = contract.getRevnue().allocate(3);

contract.addRevenueRecognition(new RevenueRecognition

(allocation[0], contract.getWhenSigned());

contract.addRevenueRecognition(new RevenueRecognition

(allocation[1], contract.getWhenSigned().addDays(firstRecognitionOffset)));

contract.addRevenueRecognition(new RevenueRecognition

(allocation[2], contract.getWhenSigned().addDays(firstRecognitionOffset)));

}

 

class Tester ...

 

private Product word = Product.newWordProcessor("Thinking Word");

private Product calc = Product.newSpreadsheet("Thinking Calc");

private Product db = Product.newDatabase("Thinking DB");

일단 모든 것이 설정되면, 세금 인식 계산은 전략 서브클래스의 임의 지식을 요청한다.

 

class Contract ...

 

public void calculateRecognitions() {

product.calculateRevenueRecognition(this);

}

 

class Product ...

 

void calculateRevenueRecognition(Contract contract) {

recognitionStrategy.calculateRevenueRecognition(contract);

}

[SA강좌] Part 4-6 Transaction Script 패턴

트랜잭션 스크립트(Transaction Script) 패턴

트랜잭션 스크립트 패턴의 정의

개별 프로시저가 프리젠테이션 레이어에서 단일 요청을 관리할 때 비즈니스 로직을 프로시저로 사용하여 조직화하는 패턴이다.

그림 Ⅴ-9. 트랜잭션 스크립트 패턴의 구조

트랜잭션 스크립트 패턴의 설명

대부분의 어플리케이션은 트랜잭션의 연속으로 생각된다. 트랜잭션은 특별한 방법에 의해 조직된 정보를 보여주고, 다른 것으로 변화시킨다. 클라이언트와 서버 시스템 사이에 상호 작용은 비즈니스 로직의 많은 부분을 포함하고 있다. 몇몇 경우는 데이터베이스에 있는 정보를 화면에 보여주는 것 같이 단순 할 수 있다. 다른 경우는 다수의 검증과 계산의 단계들을 포함할 수 있다.

트랜잭션 스크립트는 단일 프로시저, 데이터베이스 직접 호출 또는 씬 데이터베이스 레퍼와 비슷하게 모든 비즈니스 로직을 조직화한다. 각 트랜잭션은 자신의 트랜잭션 스크립트를 갖는다. 뿐만 아니라 공통 서브 작업들은 서브프로시저로 나누어 진다.

트랜잭션 스크립트 패턴은 언제 사용하는가?

트랜잭션 스크립트의 장점은 단순성에 있다. 이러한 방법으로 로직을 구조화하는 것은 단지 로직의 작은 단위를 가지는 어플리케이션을 위해 자연스러운 것 이다. 그리고, 이 것은 수행과 이해에서 매우 적은 과부하를 포함한다.

비즈니스 로직은 점점 더 복잡해지고 있다. 그러나, 비즈니스 로직을 잘 설계된 상태로 유지하는 것은 어렵다. 하나 특별한 문제점은 트랜잭션들 사이의 중첩성 이다.

주의 깊은 분해는 많은 이러한 문제점들을 완화해준다. 그러나, 더욱 복잡한 비즈니스 도메인은 도메인 모델 패턴의 작성을 필요로 한다. 도메인 모델 패턴은 코드를 구조화하데 더 많은 선택을 주고, 가독성을 증가하고, 중복성을 감속한다.

트랜잭션 스크립트 패턴의 적용 예제 : 세금 계산

이 예제는 두 가지 트랜잭션 스크립트를 사용한다. 하나는 계약을 위해 세금을 계산하는 것이고, 다른 하나는 계약에서 특정 일자에 의해 계산된 세금 금액을 알려주는 것이다. 데이터베이스는 세 가지의 테이블을 가지고 있다. 제품을 위한 테이블, 계약을 위한 테이블, 그리고 세금 인식을 위한 테이블이다.

 

CREATE TABLE products(ID int primary key, name varchar, type varchar)

CREATE TABLE contracts(ID int primary key, product int, revenue decimal, dateString date)

CREATE TABLE revenueRecognitions(contract int, amount decimal, recognizedOn Date,

PRIMARY KEY (contract, recognizedOn))

 

첫 번째 트랜잭션 스크립트는 특정 일자의 세금의 합계를 계산하는 것이다. 계산을 위해 두 단계를 거치게 된다. 세금 인식 테이블에서 적절한 행을 선택한다. 그리고, 합계를 구한다.

많은 트랜잭션 스크립트 설계들은 데이터베이스에 직접적으로 조작을 위한 스크립트를 가지고 있다. 예를 들어서 프로시저에 SQL 코드를 넣는 것이다. 테이블 데이터 게이트웨이 패턴은 SQL 질의어를 포함하고 있는 간단한 예이다. 이 예제는 매우 간단하다. 각 테이블을 위해 하나 이상의 단일 게이트웨이를 사용한다. 아래의 예제는 게이트웨이에서 검색 메서드를 정의하고 있다.

 

class GateWay ...

 

private static final String findRecognitionsStatement =

"SELECT amount " +

" FROM revenueRecognitions " +

" WHERE contract = ? AND recognizedOn <= ? ";

private Connection db;

 

public ResultSet findRecognitionsFor(long contractID, MfDate asof) throws SQLException {

PreparedStatement stmt = db.preparedStatement(findRecognitionsStatement);

stmt = db.preparedStatment(findRecognitionsStatement);

stmt.setLong(1, contractID);

stmt.setDate(2, asof.toSqlDate());

ResultSet result = stmt.executeQuery();

return result;

}

 

게이트웨이에서 결과 집합으로 전달된 것을 근간으로 합계를 구하는 스크립트는 다음과 같다.

 

class RegonitionService ...

 

public Money recognizedRevenue(long contractNumber, mfDate asOf) {

Money result = Money.dollars(0);

try {

Result rs = db.findRecognitionsFor(contractNumber, asOf);

while(rs.next()) {

result = result.add(Money.dollars(rs.getBigDecimal("amount")));

}

return result;

} catch(SQLException e) {throw new ApplicationException(e);

}

}

 

이와 같이 간단히 계산을 하는 경우 메모리 상의 스크립트는 금액을 합하는 집합 함수를 사용하는 SQL문 호출로 대치될 수 있다. 존재하는 계약 테이블에서 세금 인식을 계산하기 위해서, 아래와 같이 코드를 나누었다. 서비스의 스크립트는 비즈니스 로직을 수행한다.

 

class RegonitionService ...

 

public void calculateRevenueRecognitions(long contractNumber) {

try {

ResultSet contracts = db.findContract(contractName);

contracts.next();

Money totalRevenue = Money.dollars(contracts.getBigDecimal("revenue");

MfDate recognitionDate = new MfDate(contracts.getDate("dateSigned"));

String type = contracts.getString("type");

if(type.equls("S")) {

Money[] allocation = totalRevenue.allocate(3);

db.insertRecognition(contractNumber, allocation[0], recognitionDate);

    db.insertRecognition(contractNumber, allocation[1], recognitionDate.addDate(60));

    db.insertRecognition(contractNumber, allocation[2], recognitionDate.addDate(90));

} else if (type.equals("W")) {

db.insertRecognition(contractNumber, totalRevenue, recognitionDate);

} else if (type.equals("D")) {

Money[] allocation = totalRevenue.allocate(3);

db.insertRecognition(contractNumber, allocation[0], recognitionDate);

    db.insertRecognition(contractNumber, allocation[1], recognitionDate.addDate(30));

    db.insertRecognition(contractNumber, allocation[2], recognitionDate.addDate(60));

}

} catch(SQLException e) { throw new ApplicationException(e));

}

}

 

Money 패턴을 사용하여 세금 수집을 수행헀다는 것에 주목하자. 테이블 데이터 게이트웨이 패턴은 SQL 지원을 제공한다. 계약 테이블 검색을 위한 코드는 아래와 같다.

 

class GateWay ...

 

private static final String findContractStatement =

" SELECT " +

" FROM contract c, product p " +

0]

]

ttutri " WHERE ID = ? AND c.product = p.ID ";

 

public ResultSet findContract(long contractID) throws SQLException {

PreparedStatement stmt = db.preparedStatement(findContractStatement);

stmt.setLong(1, contractID);

ResultSet result = stmt.executeQuery();

return result;

}

 

두 번째로 입력을 위해서 코드를 추가하는 것은 아래와 같다.

 

class GateWay ...

 

public void insertRecognition(long contractID, Money amount, MfDate asof) throws SQLException {

PreparedStatement stmt = db.preparedStatement(insertRecognitionStatment);

stmt.setLong(1, contractID);

stmt.setBigDate(2, amount);

stmt.setDate(3, asof.toSqlDate());

stmt.executeUpdate();

}

private static final String insertRecognitionStatement =

"- INSERT INTO revenueRecognitions VALUE(?, ?, ?)";

 

자바 시스템에서 인식 서비스는 일반 클래스 또는 세션 빈이 될 수 있다. 도메인 모델 패턴의 예제와 비교를 하면, 위의 예제가 매우 간단하다는 것을 할 수 있다.