2008년 12월 2일 화요일

MS의 시장지배력은 어느선까지 떨어질까?... 꿈꾸는자의 생각의 파편들...

오늘 아침 다음의 기사를 보니..

http://media.daum.net/digital/internet/view.html?cateid=1077&newsid=20081202075106916&p=akn
'추락하는 '윈도', 흔들리는 'MS''라는 기사가 올라왔다.

MS IE의 시장지배력이 70% 벽이 무너지고...
윈도우즈도... 89.62%로... 90%의 벽이 무너졌다.

그동안 공룡처럼 PC시장을 지배하던 지배자에게 '틈'이 생긴것이다.

애플의 맥이 다시금 조금씩 살아나고있고...
파폭도 20%가 넘는 점유율을 보인다.
( 머, 비정상적인 국내사정은 제외하자... 어차피.. 국내의 웹은 정신나간 시장이기 때문에... 기술적으로 논할 가치도 없다. )

.
.
.

개발자의 입자에서 본다면...
시장 지배력이 흔들거리는 모습을 보면 오히려 희망이 생긴다.

춘추전국시대가 다시금 돌아올 것인가?

모바일이 더욱더 성장하면서...
넷북을 모바일이 먹어치우는 상황이 되면서...
공룡 MS가 지배하던 시대는 '암흑의 중세시대'로 칭해질 것으로 생각되어진다.

절대권력을 휘두루던...
암흑시대가 지나가고...

르네상스가 벌어지는 현상아닐까?
~.~

개인 크리에이터들이 늘어나고...
춘추전국시대가 되면서...

다시금 개발자들이 대우받는 시대가 올것으로 보인다.

시장이 단일 기술로 통일되어 있는 현재...
특히, 대한민국의 IT 정보기술은 정말 낙후되고...
대학에서도 초급수준 이하의 기술자들만 양산하게 되는 현상을 보였는데...

시대가 춘추전국이 되면서...
보다 경험있고, 이론이 탄탄하며.. 창의적인 아이디어로 무장한
새로운 개발자들이 세상에 선을 보일것으로 예측한다.

국내의 개발환경에 대해서 매우 실망하는 이유도 그때문이요...
문화없는 IT관련 업체들의 매몰성에 대해서도 실망한다.

이 세계가 변하려면...
천상.. 국내에서 무언가가 변하기 보다는..
외국의 시장상황이 변하면서...

새로운 환경을 보일것으로 예측해본다.

MS의 OS점유율이 60%이하로 떨어지고...
IE의 점유율이 50%이하로 떨어지는 시점이....

새로운 IT의 르네상스의 시작이라고 생각한다.

새로운 시대에...
새로운 모습의 개발자로 다시 태어나기를!!!

[SA강좌] Part 4-13 Data Mapper패턴

데이터 매퍼(Data Mapper) 패턴

 

데이터 매퍼 패턴의 정의

매퍼의 레이어는 개체와 데이터베이스 사이에 데이터를 이동시킨다.

그림 Ⅴ-16. 데이터 매퍼 패턴의 구조

데이터 매퍼 패턴의 설명

개체와 관계형 데이터베이스는 데이터를 구조화하는 메커니즘이 서로 다르다. 집합과 상속과 같은 개체의 많은 부분들이 관계형 데이터베이스에는 존재하지 않는다.

데이터 매퍼는 데이터베이스에서 메모리 위에 있는 개체를 분리하는 소프트웨어 레이어 이다.

데이터 매퍼 패턴은 언제 사용하는가?

데이터 매퍼를 위한 주요한 이슈는 데이터베이스 스키마와 독립적으로 포함된 개체 모델을 원할 때이다.

데이터 매퍼 패턴의 예제 : 간단한 데이터베이스 매퍼

 

class Person

 

private String lastName;

private String firstName;

private int numberOfDenedents;

 

데이터베이스 스키마는 다음과 같다.

 

cateate table people (

ID int primary key,

lastname varchar,

firstname varchar,

number_of_dependnets int

)

 

class PersonMapper ...

 

protected String findStatement() {

return "SELECT " + COLUMNS +

" FROM people " +

" WHERE id = ? ";

}

public static final String COLUMNS = " id, lastname, firstname, number_of_dependents ";

public Person find(Long id) {

return (Person) abstractFind(id);

}

public find(long id) {

return find(new Long(id));

}

 

class AbstractMapper ...

 

protected Map loadedMap = new HashMap();

abstract protected String findStatment();

protected DomainObject abstractFind(Long id) {

DomainObject result = (DomainObject) loadedMap.get(id);

if (result != null) return result;

PreparedStatment findStatement = null;

try {

findStatement = DB.prepare(findStatment);

findStatement.setLong(1, id.longValue();

ResultSet rs = findStatement.executeQuery();

rs.next();

result = load(rs);

return result;

} catch(SQLException e) {

throw new ApplicationException(e);

} finally {

DB.cleanUp(findStatement);

}

}

검색 메서드는 로드 메서드를 호출한다.

 

class AbstractMapper ...

 

protected DomainObject load(ResultSet rs) throws SQLException {

Long id = new Long(re.getLong(1));

if (loadedMap.contractKey(id) return (DoaminObject) loadedMap.get(id);

DomainObject result = doLoad(id, rs);

loadedMap,put(id, result);

return result;

}

abstract protected DomainObject doLoad(Long id, ResultSet rs) throws SQLExecption;

 

class PersonMapper ...

 

protected DomainObject doLoad(Long id, ResultSet rs) throws SQLException {

String lastNameArg = rs.getString(2);

String firstNameArg = rs.getString(3);

int numDependentsArg = rs.getInt(4);

return new Person(id, lastNameArg, firstNameArg, numDependentsArg);

}

일치 맵(Identity Map) 패턴이 abstractFind와 load 메서드에 의해 두번 확인됨을 주의한다.

 

class PersonMapper ...

 

private static String findLastNameStatment =

" SELECT " + COLUMNS +

" FROM people " +

" WHERE UPPER(lastName) LIKE UPPER(?) " +

" ORDER BY lastname ";

public List findByLastName(String name) {

PreparedStatement stmt = null;

ResultSet rs = null;

try {

stmt = DB.prepare(findLastNameStatement);

stmt.setString(1, name);

rs = stmt.executeQuery();

return loadAll(rs);

} catch(SQLException e) {

throw new ApplicationException(e);

} finally {

DB.cleanUp(stmt, rs);

}

}

 

class AbstractMapper ...

 

protected loadAll(ResultSet rs) throws SQLException {

List result = new Array();

while (rs.next())

result.add(load(rs));

return result;

}

 

 

class AbstractMapper ...

 

public List findMany(StatementSource source) {

PreparedStatment stmt = null;

ResultSet rs = null;

try {

stmt = DB.prepare(source.sql());

for (int i = 0; i < source.paraments().length; i++)

stmt.setObject(i+1, source.paraments()[i]);

rs = stmt.executeQuery();

return loadAll(rs);

} catch(SQLException e) {

throw new ApplicationException(e);

} finally {

DB.cleanUp(stmt, rs);

}

 

interface StatmentSource ...

 

String sql();

Object[] paraments();

 

class PersonMapper ...

 

public List findByLastName2(String pattern) {

return findMany(new FindByLastName(pattern));

}

static class FindByLastName impletements StatemnetSource {

private String lastname;

public FindByLastName(String name) {

this.lastName = lastName;

}

public String sql() {

return

" SELECT + " COLUMNS +

" FROM people " +

" WHERE BY lastname ";

}

public object[] parameters() {

Object[] result = { lastName; }

return result;

}

}

 

 

class PersonMapper ..

 

private static final String updateStatementString =

" UPDATE people " +

" SET lastname = ?, firstname = ?, number_of_dependents = ?" +

" WHERE id = ? ";

public void update(Person subject) {

PreparedStatement updateStatement = null;

try {

updateStatement = DB.prepare(updateStatementString);

updateStatement.setString(1, subject.getLastName());

updateStatement.setString(2, subject.getFirstName());     

updateStatement.setInt(3, subject.getNumberOfDependents());

updateStatement.setInt(4, subject.getID(),intValue());

updateStatement.execute();

} catch(Exception e) {

throw new ApplicationException(e);

} finally {

DB.cleanUp(updateStatement);

}

}

 

입력을 위한 몇몇 코드는 레이어 수퍼형에 보관된다.

 

class AbstractMapper ...

 

public Long insert(DomainObject subject) {

PreparedStatment updateStatement = null;

try {

insertStatement = DB.prepare(insertStatment());

subject.setID(findNextDatabaseId());

insertStatement.setInt(1, subject.getID().intValue());

doInsert(subject, insertStatement);

insertStatement.execute();

loadMap.put(subject.getID(), subject);

return subject.getID());

} catch(SQLException e) {

throw new ApplicationException(e);

} finally {

DB.cleanUp(updateStatemet);

}

}

abstract protected String insertStatement();

abstract protected void doInsert(DomainObject subject, PreparedStatement insertStatement)

throws SQLException;

 

class PersonMapper ...

 

protected String insertStatement() {

return "INSERT INTO people VALUES(?,?,?,?)";

}

protected void doInsert(DomainObject abstractSubject,

PreparedStatement stmt)

throws SQLException

{

Person subject = (Person) abstractSubject;

stmt.setString(2, subject.getLastName());

stmt.setString(3, subject.getFirstName());

stmt.setInt(4, subject.getNumberOfDependents());

}

2008년 12월 1일 월요일

작년 크리스마스 파티음식들... 올해에는 과연 어떤 것들을?

작년의 크리스마스의 사진들을 다시 한번 정리해서.. ~.~
올해의 크리스마스에는 어떤 파티음식들이 만들어지려나...


크리스마스를 위한 케익과...
개인용 스테이크...
와인잔..
그리고, 셀러드...


나름 이쁘게 올라갔죠?
~.~


올해에도 멋진 크리스마스가 되어야 할텐데...
~.~


올해에는...
준비된 와인도 있겠다...
다른 메뉴들은 어떤 것들을 준비해야할려나...


스테이크 위에...
생크림도..
~.~


게맛살이 올라간...
맛깔스러운 셀러드도...


나름 향초로...
분위기를 만들어 볼려고 했는데...

~.~


이 메뉴는...
아이들을 위한 메뉴죠..

~.~

하나참치에서 나오는 참치초밥...

일산의 하나참치...
정말 맛깔스러운 참치집...

그리고...

멋진 느낌의 참치초밥...


윤기가  자르르 흐르는...
멋진 참치 초밥 아닌가요?


여러 각도로 찍고 싶었지만...
한자리에서 찍은 관계로...

~.~


좀더 줌인...
(후루룩... ㅇㅇ )


멋진 느낌이죠?

ㅇㅇ...

ㅡㅡ;

참치...
초밥...

먹고프다...

오옷! 울 와이프가 Hirosue Ryoko를 닮았다구... ~.~




오옷! 74%... ~.~

수철이는 누구를 더 닮았을까요? ㅋㅋ...


MyHeritage: Look-alike Meter - Pedigree - Family history

ㅋㅋ... 수철이는 좀더 아빠를 닮았다네요.. ㅋㅋㅋㅋ

아버지와 어머니중 누구를 더 닯았을까요? ㅋㅋ...


MyHeritage: Look-alike Meter - Geneology - Roots

이것도 재미있네요.. ㅎㅎ