2007년 11월 07일
[간이번역] Mapping to Relational Databases
http://www.informit.com/articles/article.aspx?p=30661&rl=1
P of EAA의 DB관련 패턴들을 어떻게 써야 하는지 알 수 있는 좋은 글 같아서 퍼왔습니다.
중간 중간 중요한 부분만 대략 번역해볼께요.
시간도 없고...
----------------------------------------------------------------------------------
Enterprise Application Architecture: Mapping to Relational Databases
* By Martin Fowler.
* Jan 24, 2003
* Sample Chapter is provided courtesy of Addison Wesley Professional
데이터베이스가 아주 많이 쓰이고 중요해서 이것과 커뮤니케이션 하는게 큰 문제다.
The role of the data source layer is to communicate with the variouspieces of infrastructure that an application needs to do its job. Adominant part of this problem is talking to a database, which, for themajority of systems built today, means a relational database. Certainlythere's still a lot of data in older data storage formats, such asmainframe ISAM and VSAM files, but most people building systems todayworry about working with a relational database.
관계형 DB가 성공한 큰 이유 중 하나는 SQL이다. 표준이지만 벤더마다 다르기도...
One the biggest reasons for the success of relational databases isthe presence of SQL, a mostly standard language for databasecommunication. Although SQL is full of annoying and complicatedvendor-specific enhancements, its core syntax is common and wellunderstood.
Architectural Patterns
P fo EAA의 첫 패턴 묶음은 도메인 로직이 DB에 접근하는 방법에 대한 것이다. 여기서 선택한 것이 계속 영향을 미치니 신중해야 한다.
The first set of patterns comprises the architectural patterns,which drive the way in which the domain logic talks to the database.The choice you make here is far-reaching for your design and thusdifficult to refactor, so it's one that you should pay some attentionto. It's also a choice that's strongly affected by how you design yourdomain logic.
SQL이 유명하지만 많은 개발자들이 SQL을 모른다. SQL을 코드에 넣으면 복잡하고 유지보수와 테스트 하기 힘들다. DBA들은 SQL을 뽑아보기 원한다.
Despite SQL's wide spread use in enterprise software, there are still pit falls in using it. Many application developers don't understand SQL well and, as a result, have problems defining effective queries and commands. Although various techniques exist for embedding SQL in a programming language, they're all some what awkward. It wouldbe better to access data using mechanisms that fit in with the application development langauge. Database administrations (DBAs) alsolike to get at the SQL that accesses a table so that they can understand how best to tune it and how to arrange indexes.
이런 이유로 SQL을 도메인 로직에서 분리해 다른 클레스에 저장하는게 좋다. 좋은 방법은 DB의 테이블 구조에 맞게 클레스들을 구성하는 것이다. 이들 클레스들은 테이블에 대한 Gateway(466)의 형태가 될 것이다. 나머지 어플리케이션은SQL에 대해 알 필요가 없다.
For these reasons, it's wise to separate SQL access from the domainlogic and place it in separate classes. A good way of organizing these classes is to base them on the table structure of the database so that you have one class per database table. These classes then form a Gateway (466) to the table. The rest of the application needs to know nothing about SQL, and all the SQL that accesses the database is easy to find. Developers who specialize in the database have a clear placeto go.
Gateway(466)을 어떻게 사용할지는 두가지 주요 방법이 있다. 가장 분명한 방법은 쿼리의 결과로 얻은 각 열이 한 인스턴스를 갖게하는 것이다. Row Data Gateway(152)는 데이터를 중심으로 사고하는 객체지향에 본질적으로 부합하는 방법이다.
There are two main ways in which you can use a Gateway (466). The most obvious is to have an instance of it for each row that's returned by aquery (Figure 3.1). This Row Data Gateway (152) is an approach that naturally fits an object-oriented way of thinking about the data.
많은 환경이 Record Set(508)을 제공한다. 이는 테이블과 열(row)를 표현하는 일반적인 데이타 구조이다. Record Set(508)을 사용할 경우 테이블당 한 클레스만 필요하다. Table Data Gateway(144)는 DB를 쿼리해 Record Set(508)을 반환하는 메소드를 제공한다.
Many environments provide a Record Set (508)?that is, a generic data structure of tables and rows that mimics the tabular nature of adatabase. Because a Record Set (508) is a generic data structure,environments can use it in many parts of an application. It's quite common for GUI tools to have controls that work with a Record Set(508). If you use a Record Set (508), you only need a single class for each table in the database. This Table Data Gateway (144) (see Figure3.2) provides methods to query the database that return a Record Set(508)
난 간단한 어플리케이션에서도 Gateway 패턴을 쓰는 경향이 있다. SQL과 도메인 로직의 명박한 구별은 매우 도움이 된다.
Even for simple applications I tend to use one of the gate way patterns. A glance at my Ruby and Python scripts will confirm this. Ifind the clear separation of SQL and domain logic to be very helpful.
Table Module(125)를 선택했다면 Table Data Gateway(144)에 Record Set(508)를 쓰는 것은 잘 맞는 것이 사실이다. 이것은 stored procedure을 염두에 둘 때에도 사용 할 수 있는 패턴이다. 많은 설계자들이 명시적인 SQL 구문 대신 stored procedure를 사용하기 좋아한다. 이럴 때 Table DataGateway(144)를 써서 stored procedure 호출을 캡슐화 하는게 좋다.
The fact that Table Data Gateway (144) fits very nicely with RecordSet (508) makes it the obvious choice if you are using Table Module(125). It's also a pattern you can use to think about organizing stored procedures. Many designers like to do all of their database access through stored procedures rather than through explicit SQL. In this case you can think of the collection of stored procedures as defining a Table Data Gateway (144) for a table. I would still have an in-memory Table Data Gateway (144) to wrap the calls to the stored procedures,since that keeps the mechanics of the stored procedure callencapsulated.
만약 Domain Model (116)을 사용한다면 가지고 놀 수 있는 몇가지 옵션이 더 있다. 물론 Row Data Gateway(152)이나 Table Data Gateway(144)를 Domain Model(116)과 함께 사용할 수도 있다. 하지만 내 입에는 이 방법이 지나치게 간접적이거나 오히려 불충분하게 보일 때가 있다.
If you're using Domain Model (116), some further options come into play. Certainly you can use a Row Data Gateway (152) or a Table Data Gateway (144) with a Domain Model (116). For my taste, however, that can be either too much indirection or not enough.
간단한 어플리케이션에서 Domain Model(116)은 복잡하지 않은데 사실 상 한 테이블 당 한 도메인 클레스로 구성한다. 이런 도메인 객체는 종종 그리 복잡하지 않은 비지니스 로직만 갖는다. 이런 경우 각 도메인 객체가 데이터베이스를 읽거나 쓰는 책임을 갖는게 합리적이다. 이것이 바로 Active Record(160)이다. Active Record(160)을 다른 관점에서 생각해 보면 이것은 먼저 Row Data Gateway(152)를 만들고 이 클레스에 도메인 로직을 추가하는 - 특히 여러Transaction Scripts(110)에 걸쳐 있는 중복된 코드를 보게 되었을 때 - 것이 된다.
In simple applications the Domain Model (116) is an uncomplicatedstructure that actually corresponds pretty closely to the databasestructure, with one domain class per database table. Such domain objects often have only moderately complex business logic. In this case it makes sense to have each domain object be responsible for loading and saving from the database, which is Active Record (160) (see Figure3.3). Another way to think of the Active Record (160) is that you start with a Row Data Gateway (152) and then add domain logic to the class, particularly when you see repetitive code in multiple TransactionScripts (110).
이런 종류의 상황에서 Gateway(466)를 사용한 간접적인 처방은 큰 도움이 안된다. 도메인 로직이 보다 복잡해지면서 리치 Domain Model(116)을 향해 나아가게 된다. 간단한 접근 방법은 Active Record(160)을 쪼개기 시작하는 것이다. 도메인 로직을 보다 작은 클래스로 인수분해 하면서 테이블과의 1:1 대응은 약해지기 시작한다. 관계형 DB는 상속을 지원하지 않으니까 GOF의 스트레이티지 패턴이나 다른 멋진 OO 패턴을 쓰기 힘들어진다. 도메인 로직이 깐깐해져가면서 당신은 언제나 DB와의 연동 없이 이를 테스트 할 수 있기 원할 것이다.
In this kind of situation the added indirection of a Gateway (466) doesn't provide a great deal of value. As the domain logic gets more complicated and you begin moving toward a rich Domain Model (116), the simple approach of an Active Record (160) starts to break down. The one-to-one match of domain classes to tables starts to fail as you factor domain logic into smaller classes. Relational databases don't handle inheritance, so it becomes difficult to use strategies [Gang ofFour] and other neat OO patterns. As the domain logic gets feisty, you want to be able to test it without having to talk to the database all the time.
이 모든 것들이 Domain Model(116)이 점점 커져가면서 간접적이 되도록 압력을 준다. 이런 경우 Gateway(466)가 몇가지 문제들을 해결해 주기는 하지만 Domain Model(116)과 DB 스키마가 겹합되는 문제가 여전히 남아 있다. 결과적으로 Gateway(466)의 필드를 도메인 객체의 필드로의 변환 작업이 생기고 이것이 도메인 객체를 복잡하게 만든다.
All of these forces push you to in'direction as your Domain Model(116) gets richer. In this case the Gateway (466) can solve some problems, but it still leaves you with the Domain Model (116) coupled to the schema of the database. As a result there's some transformation from the fields of the Gateway (466) to the fields of the domain objects, and this transformation complicates your domain objects.
보다 좋은 방법은 도메인 객체와 DB 테이블을 맵핑시키는 작업의 모든 책임을 담당하는 레이어를 만들어 DomainModel(116)와 DB를 완전히 격리 시키는 것이다. Data Mapper(165)는 Domain Model(116)과 DB간의 모든 읽고 쓰는 작업을 처리한다. 이것은 가장 복잡한 DB 맵핑 아키텍쳐이지만 두 레이어를 완전히 격리시키는 이점이있다.
A better route is to isolate the Domain Model (116) from thedatabase completely, by making your indirection layer entirelyresponsible for the mapping between domain objects and database tables.This Data Mapper (165) (see Figure 3.4) handles all of the loading andstoring between the database and the Domain Model (116) and allows bothto vary independently. It's the most complicated of the databasemapping architectures, but its benefit is complete isolation of the twolayers.
난 Domain Model(116)을 위한 최우선 영속화 메카니즘으로 Gateway(466)를 사용하도록 추천하지않는다. 도메인 로직이 단순하고 클래스와 테이블이 긴밀하다면 Active Record(160)가 단순한 방법이다. 보다복잡하다면 Data Mapper(165)가 필요하다.
I don't recommend using a Gateway (466) as the primary persistence mechanism for a Domain Model (116). If the domain logic is simple and you have a close correspondence between classes and tables, ActiveRecord (160) is the simple way to go. If you have something more complicated, Data Mapper (165) is what you need.
이 패턴들은 서로 간에 완전히 배타적이지는 않다. Data Mapper(165)를 기본적인 영속화 메카니즘으로 쓴다면 데이터 Gateway(466)을 외부 인터페이스를 다루듯 테이블이나 서비스를 감싸기 위해 사용할 수 있다.
These patterns aren't entirely mutually exclusive. In much of this discussion we're thinking of the primary persistence mechanism, by which we mean how you save the data in some kind of in-memory model to the database. For that you'll pick one of these patterns; you don't want to mix them because that ends up getting very messy. Even if you're using Data Mapper (165) as your primary persistence mechanism, however, you may use a data Gateway (466) to wrap tables or services that are being treated as external interfaces.
계속 테이블이라는 단어를 썼지만 뷰, stored procedure를 통해 캡슐화된 쿼리, 공통적으로 사용되는 다이나믹 쿼리들에 적용될 수 있다.
In my discussion of these ideas, both here and in the patterns themselves, I tend to use the word "table." However, most of thesetechniques can apply equally well to views, queries encapsulatedthrough stored procedures, and commonly used dynamic queries. Sadly,there isn't a widely used term for table/view/query/stored procedure,so I use "table" because it represents a tabular data structure. Iusually think of views as virtual tables, which is of course how SQLthinks of them too. The same syntax is used for querying views as for querying tables.
Updating obviously is more complicated with views and queries, asyou can't always update a view directly but instead have to manipulate the tables that underlie it. In this case encapsulating the view/querywith an appropriate pattern is a very good way to implement that updatelogic in one place, which makes using the views both simpler and more reliable.
One of the problems with using views and queries in this way is that it can lead to inconsistencies that may surprise developers whodon't understand how a view is formed. They may perform updates on two different structures, both of which update the same underlying tables where the second update overwrites an update made by the first. Providing that the update logic does proper validation, you shouldn't get inconsistent data this way, but you may surprise your developers.
가장 복잡한 Domain Model(116)까지도 영속화 할 수 있는 가장 단순한 방법은 OO DB를 쓰는 것이다.
I should also mention the simplest way of persisting even the mostcomplex Domain Model (116). During the early days of objects manypeople realized that there was a fundamental "impedance mismatch"between objects and relations. Thus, there followed a spate of efforton object-oriented databases, which essentially brought the OO paradigmto disk storage. With an OO database you don't have to worry aboutmapping. You work with a large structure of interconnected objects, andthe database figures out when to move objects on or off disks. Also,you can use transactions to group together updates and permit sharingof the data store. To programmers this seems like an infinite amount oftransactional memory that's transparently backed by disk storage.
OO DB는 생산성을 향상 시킨다.
The chief advantage of OO databases is that they improveproductivity. Although I'm not aware of any controlled tests, anecdotalobservations put the effort of mapping to a relational database ataround a third of programming effort?a cost that continues duringmaintenance.
대부분의 프로젝트가 OO DB를 사용하지 않는데 이유는 위험 때문이다. 관계 DB는 검증된 기술이다.
Most projects don't use OO databases, however. The primary reasonagainst them is risk. Relational databases are a well-understood andproven technology backed by big vendors who have been around a longtime. SQL provides a relatively standard interface for all sorts oftools. (If you're concerned about performance, all I can say is that Ihaven't seen any conclusive data comparing the performance of OOagainst that of relational systems.)
OO DB를 쓰지못한다 해도 Domain Model(116)을 사용한다면 O/R Mapping 도구를 사는 것을 심각하게 고려해야 한다. Data Mapper(165)를 만드는 것은 무지 복잡하다. 상용 O/R Mapper들은 좋다.
Even if you can't use an OO database, you should seriously considerbuying an O/R mapping tool if you have a Domain Model (116). While thepatterns in this book will tell you a lot about how to build a DataMapper (165), it's still a complicated endeavor. Tool vendors havespent many years working on this problem, and commercial O/R mappingtools are much more sophisticated than anything that can reasonably bedone by hand. While the tools aren't cheap, you have to compare theirprice with the considerable cost of writing and maintaining such alayer yourself.
관계 DB와 작업할 수 있는 OO DB 스타일 레이를 제공하는 움직임들이 있는데 Java에서는 JDO가 있지만 아직 초기라서 어떻게 될지 모르겠다.
There are moves to provide an OO-database-style layer that can workwith relational databases. JDO is such a beast in the Java world, butit's still too early to tell how they'll work out. I haven't had enoughexperience with them to draw any conclusions for this book.
하지만 도구를 사더라도 이 패턴들을 인식하는 것은 좋은 생각이다. 좋은 O/R 도구는 여러 옵션들을 제공하는데 이 패턴들은 선택하고 이해하는데 도움이 된다. 도구가 모든 수고를 날려 버릴 것으로 생각하지 말아라. 도구가 많이 완화시켜 주지만 여전히 O/R 도구를 사용하고 튜닝하는데 있어 작지만 중요한 일단의 작업이 남아있는 것을 발견 할 것이다.
Even if you do buy a tool, however, it's a good idea to be aware of these patterns. Good O/R tools give you a lot of options in mapping toa database, and these patterns will help you understand when to use thedifferent choices. Don't assume that a tool makes all the effort go away. It makes a big dent, but you'll still find that using and tuning an O/R tool takes a small but significant chunk of work.
P of EAA의 DB관련 패턴들을 어떻게 써야 하는지 알 수 있는 좋은 글 같아서 퍼왔습니다.
중간 중간 중요한 부분만 대략 번역해볼께요.
시간도 없고...
----------------------------------------------------------------------------------
Enterprise Application Architecture: Mapping to Relational Databases
* By Martin Fowler.
* Jan 24, 2003
* Sample Chapter is provided courtesy of Addison Wesley Professional
데이터베이스가 아주 많이 쓰이고 중요해서 이것과 커뮤니케이션 하는게 큰 문제다.
The role of the data source layer is to communicate with the variouspieces of infrastructure that an application needs to do its job. Adominant part of this problem is talking to a database, which, for themajority of systems built today, means a relational database. Certainlythere's still a lot of data in older data storage formats, such asmainframe ISAM and VSAM files, but most people building systems todayworry about working with a relational database.
관계형 DB가 성공한 큰 이유 중 하나는 SQL이다. 표준이지만 벤더마다 다르기도...
One the biggest reasons for the success of relational databases isthe presence of SQL, a mostly standard language for databasecommunication. Although SQL is full of annoying and complicatedvendor-specific enhancements, its core syntax is common and wellunderstood.
Architectural Patterns
P fo EAA의 첫 패턴 묶음은 도메인 로직이 DB에 접근하는 방법에 대한 것이다. 여기서 선택한 것이 계속 영향을 미치니 신중해야 한다.
The first set of patterns comprises the architectural patterns,which drive the way in which the domain logic talks to the database.The choice you make here is far-reaching for your design and thusdifficult to refactor, so it's one that you should pay some attentionto. It's also a choice that's strongly affected by how you design yourdomain logic.
SQL이 유명하지만 많은 개발자들이 SQL을 모른다. SQL을 코드에 넣으면 복잡하고 유지보수와 테스트 하기 힘들다. DBA들은 SQL을 뽑아보기 원한다.
Despite SQL's wide spread use in enterprise software, there are still pit falls in using it. Many application developers don't understand SQL well and, as a result, have problems defining effective queries and commands. Although various techniques exist for embedding SQL in a programming language, they're all some what awkward. It wouldbe better to access data using mechanisms that fit in with the application development langauge. Database administrations (DBAs) alsolike to get at the SQL that accesses a table so that they can understand how best to tune it and how to arrange indexes.
이런 이유로 SQL을 도메인 로직에서 분리해 다른 클레스에 저장하는게 좋다. 좋은 방법은 DB의 테이블 구조에 맞게 클레스들을 구성하는 것이다. 이들 클레스들은 테이블에 대한 Gateway(466)의 형태가 될 것이다. 나머지 어플리케이션은SQL에 대해 알 필요가 없다.
For these reasons, it's wise to separate SQL access from the domainlogic and place it in separate classes. A good way of organizing these classes is to base them on the table structure of the database so that you have one class per database table. These classes then form a Gateway (466) to the table. The rest of the application needs to know nothing about SQL, and all the SQL that accesses the database is easy to find. Developers who specialize in the database have a clear placeto go.
Gateway(466)을 어떻게 사용할지는 두가지 주요 방법이 있다. 가장 분명한 방법은 쿼리의 결과로 얻은 각 열이 한 인스턴스를 갖게하는 것이다. Row Data Gateway(152)는 데이터를 중심으로 사고하는 객체지향에 본질적으로 부합하는 방법이다.
There are two main ways in which you can use a Gateway (466). The most obvious is to have an instance of it for each row that's returned by aquery (Figure 3.1). This Row Data Gateway (152) is an approach that naturally fits an object-oriented way of thinking about the data.
많은 환경이 Record Set(508)을 제공한다. 이는 테이블과 열(row)를 표현하는 일반적인 데이타 구조이다. Record Set(508)을 사용할 경우 테이블당 한 클레스만 필요하다. Table Data Gateway(144)는 DB를 쿼리해 Record Set(508)을 반환하는 메소드를 제공한다.
Many environments provide a Record Set (508)?that is, a generic data structure of tables and rows that mimics the tabular nature of adatabase. Because a Record Set (508) is a generic data structure,environments can use it in many parts of an application. It's quite common for GUI tools to have controls that work with a Record Set(508). If you use a Record Set (508), you only need a single class for each table in the database. This Table Data Gateway (144) (see Figure3.2) provides methods to query the database that return a Record Set(508)
난 간단한 어플리케이션에서도 Gateway 패턴을 쓰는 경향이 있다. SQL과 도메인 로직의 명박한 구별은 매우 도움이 된다.
Even for simple applications I tend to use one of the gate way patterns. A glance at my Ruby and Python scripts will confirm this. Ifind the clear separation of SQL and domain logic to be very helpful.
Table Module(125)를 선택했다면 Table Data Gateway(144)에 Record Set(508)를 쓰는 것은 잘 맞는 것이 사실이다. 이것은 stored procedure을 염두에 둘 때에도 사용 할 수 있는 패턴이다. 많은 설계자들이 명시적인 SQL 구문 대신 stored procedure를 사용하기 좋아한다. 이럴 때 Table DataGateway(144)를 써서 stored procedure 호출을 캡슐화 하는게 좋다.
The fact that Table Data Gateway (144) fits very nicely with RecordSet (508) makes it the obvious choice if you are using Table Module(125). It's also a pattern you can use to think about organizing stored procedures. Many designers like to do all of their database access through stored procedures rather than through explicit SQL. In this case you can think of the collection of stored procedures as defining a Table Data Gateway (144) for a table. I would still have an in-memory Table Data Gateway (144) to wrap the calls to the stored procedures,since that keeps the mechanics of the stored procedure callencapsulated.
만약 Domain Model (116)을 사용한다면 가지고 놀 수 있는 몇가지 옵션이 더 있다. 물론 Row Data Gateway(152)이나 Table Data Gateway(144)를 Domain Model(116)과 함께 사용할 수도 있다. 하지만 내 입에는 이 방법이 지나치게 간접적이거나 오히려 불충분하게 보일 때가 있다.
If you're using Domain Model (116), some further options come into play. Certainly you can use a Row Data Gateway (152) or a Table Data Gateway (144) with a Domain Model (116). For my taste, however, that can be either too much indirection or not enough.
간단한 어플리케이션에서 Domain Model(116)은 복잡하지 않은데 사실 상 한 테이블 당 한 도메인 클레스로 구성한다. 이런 도메인 객체는 종종 그리 복잡하지 않은 비지니스 로직만 갖는다. 이런 경우 각 도메인 객체가 데이터베이스를 읽거나 쓰는 책임을 갖는게 합리적이다. 이것이 바로 Active Record(160)이다. Active Record(160)을 다른 관점에서 생각해 보면 이것은 먼저 Row Data Gateway(152)를 만들고 이 클레스에 도메인 로직을 추가하는 - 특히 여러Transaction Scripts(110)에 걸쳐 있는 중복된 코드를 보게 되었을 때 - 것이 된다.
In simple applications the Domain Model (116) is an uncomplicatedstructure that actually corresponds pretty closely to the databasestructure, with one domain class per database table. Such domain objects often have only moderately complex business logic. In this case it makes sense to have each domain object be responsible for loading and saving from the database, which is Active Record (160) (see Figure3.3). Another way to think of the Active Record (160) is that you start with a Row Data Gateway (152) and then add domain logic to the class, particularly when you see repetitive code in multiple TransactionScripts (110).
이런 종류의 상황에서 Gateway(466)를 사용한 간접적인 처방은 큰 도움이 안된다. 도메인 로직이 보다 복잡해지면서 리치 Domain Model(116)을 향해 나아가게 된다. 간단한 접근 방법은 Active Record(160)을 쪼개기 시작하는 것이다. 도메인 로직을 보다 작은 클래스로 인수분해 하면서 테이블과의 1:1 대응은 약해지기 시작한다. 관계형 DB는 상속을 지원하지 않으니까 GOF의 스트레이티지 패턴이나 다른 멋진 OO 패턴을 쓰기 힘들어진다. 도메인 로직이 깐깐해져가면서 당신은 언제나 DB와의 연동 없이 이를 테스트 할 수 있기 원할 것이다.
In this kind of situation the added indirection of a Gateway (466) doesn't provide a great deal of value. As the domain logic gets more complicated and you begin moving toward a rich Domain Model (116), the simple approach of an Active Record (160) starts to break down. The one-to-one match of domain classes to tables starts to fail as you factor domain logic into smaller classes. Relational databases don't handle inheritance, so it becomes difficult to use strategies [Gang ofFour] and other neat OO patterns. As the domain logic gets feisty, you want to be able to test it without having to talk to the database all the time.
이 모든 것들이 Domain Model(116)이 점점 커져가면서 간접적이 되도록 압력을 준다. 이런 경우 Gateway(466)가 몇가지 문제들을 해결해 주기는 하지만 Domain Model(116)과 DB 스키마가 겹합되는 문제가 여전히 남아 있다. 결과적으로 Gateway(466)의 필드를 도메인 객체의 필드로의 변환 작업이 생기고 이것이 도메인 객체를 복잡하게 만든다.
All of these forces push you to in'direction as your Domain Model(116) gets richer. In this case the Gateway (466) can solve some problems, but it still leaves you with the Domain Model (116) coupled to the schema of the database. As a result there's some transformation from the fields of the Gateway (466) to the fields of the domain objects, and this transformation complicates your domain objects.
보다 좋은 방법은 도메인 객체와 DB 테이블을 맵핑시키는 작업의 모든 책임을 담당하는 레이어를 만들어 DomainModel(116)와 DB를 완전히 격리 시키는 것이다. Data Mapper(165)는 Domain Model(116)과 DB간의 모든 읽고 쓰는 작업을 처리한다. 이것은 가장 복잡한 DB 맵핑 아키텍쳐이지만 두 레이어를 완전히 격리시키는 이점이있다.
A better route is to isolate the Domain Model (116) from thedatabase completely, by making your indirection layer entirelyresponsible for the mapping between domain objects and database tables.This Data Mapper (165) (see Figure 3.4) handles all of the loading andstoring between the database and the Domain Model (116) and allows bothto vary independently. It's the most complicated of the databasemapping architectures, but its benefit is complete isolation of the twolayers.
난 Domain Model(116)을 위한 최우선 영속화 메카니즘으로 Gateway(466)를 사용하도록 추천하지않는다. 도메인 로직이 단순하고 클래스와 테이블이 긴밀하다면 Active Record(160)가 단순한 방법이다. 보다복잡하다면 Data Mapper(165)가 필요하다.
I don't recommend using a Gateway (466) as the primary persistence mechanism for a Domain Model (116). If the domain logic is simple and you have a close correspondence between classes and tables, ActiveRecord (160) is the simple way to go. If you have something more complicated, Data Mapper (165) is what you need.
이 패턴들은 서로 간에 완전히 배타적이지는 않다. Data Mapper(165)를 기본적인 영속화 메카니즘으로 쓴다면 데이터 Gateway(466)을 외부 인터페이스를 다루듯 테이블이나 서비스를 감싸기 위해 사용할 수 있다.
These patterns aren't entirely mutually exclusive. In much of this discussion we're thinking of the primary persistence mechanism, by which we mean how you save the data in some kind of in-memory model to the database. For that you'll pick one of these patterns; you don't want to mix them because that ends up getting very messy. Even if you're using Data Mapper (165) as your primary persistence mechanism, however, you may use a data Gateway (466) to wrap tables or services that are being treated as external interfaces.
계속 테이블이라는 단어를 썼지만 뷰, stored procedure를 통해 캡슐화된 쿼리, 공통적으로 사용되는 다이나믹 쿼리들에 적용될 수 있다.
In my discussion of these ideas, both here and in the patterns themselves, I tend to use the word "table." However, most of thesetechniques can apply equally well to views, queries encapsulatedthrough stored procedures, and commonly used dynamic queries. Sadly,there isn't a widely used term for table/view/query/stored procedure,so I use "table" because it represents a tabular data structure. Iusually think of views as virtual tables, which is of course how SQLthinks of them too. The same syntax is used for querying views as for querying tables.
Updating obviously is more complicated with views and queries, asyou can't always update a view directly but instead have to manipulate the tables that underlie it. In this case encapsulating the view/querywith an appropriate pattern is a very good way to implement that updatelogic in one place, which makes using the views both simpler and more reliable.
One of the problems with using views and queries in this way is that it can lead to inconsistencies that may surprise developers whodon't understand how a view is formed. They may perform updates on two different structures, both of which update the same underlying tables where the second update overwrites an update made by the first. Providing that the update logic does proper validation, you shouldn't get inconsistent data this way, but you may surprise your developers.
가장 복잡한 Domain Model(116)까지도 영속화 할 수 있는 가장 단순한 방법은 OO DB를 쓰는 것이다.
I should also mention the simplest way of persisting even the mostcomplex Domain Model (116). During the early days of objects manypeople realized that there was a fundamental "impedance mismatch"between objects and relations. Thus, there followed a spate of efforton object-oriented databases, which essentially brought the OO paradigmto disk storage. With an OO database you don't have to worry aboutmapping. You work with a large structure of interconnected objects, andthe database figures out when to move objects on or off disks. Also,you can use transactions to group together updates and permit sharingof the data store. To programmers this seems like an infinite amount oftransactional memory that's transparently backed by disk storage.
OO DB는 생산성을 향상 시킨다.
The chief advantage of OO databases is that they improveproductivity. Although I'm not aware of any controlled tests, anecdotalobservations put the effort of mapping to a relational database ataround a third of programming effort?a cost that continues duringmaintenance.
대부분의 프로젝트가 OO DB를 사용하지 않는데 이유는 위험 때문이다. 관계 DB는 검증된 기술이다.
Most projects don't use OO databases, however. The primary reasonagainst them is risk. Relational databases are a well-understood andproven technology backed by big vendors who have been around a longtime. SQL provides a relatively standard interface for all sorts oftools. (If you're concerned about performance, all I can say is that Ihaven't seen any conclusive data comparing the performance of OOagainst that of relational systems.)
OO DB를 쓰지못한다 해도 Domain Model(116)을 사용한다면 O/R Mapping 도구를 사는 것을 심각하게 고려해야 한다. Data Mapper(165)를 만드는 것은 무지 복잡하다. 상용 O/R Mapper들은 좋다.
Even if you can't use an OO database, you should seriously considerbuying an O/R mapping tool if you have a Domain Model (116). While thepatterns in this book will tell you a lot about how to build a DataMapper (165), it's still a complicated endeavor. Tool vendors havespent many years working on this problem, and commercial O/R mappingtools are much more sophisticated than anything that can reasonably bedone by hand. While the tools aren't cheap, you have to compare theirprice with the considerable cost of writing and maintaining such alayer yourself.
관계 DB와 작업할 수 있는 OO DB 스타일 레이를 제공하는 움직임들이 있는데 Java에서는 JDO가 있지만 아직 초기라서 어떻게 될지 모르겠다.
There are moves to provide an OO-database-style layer that can workwith relational databases. JDO is such a beast in the Java world, butit's still too early to tell how they'll work out. I haven't had enoughexperience with them to draw any conclusions for this book.
하지만 도구를 사더라도 이 패턴들을 인식하는 것은 좋은 생각이다. 좋은 O/R 도구는 여러 옵션들을 제공하는데 이 패턴들은 선택하고 이해하는데 도움이 된다. 도구가 모든 수고를 날려 버릴 것으로 생각하지 말아라. 도구가 많이 완화시켜 주지만 여전히 O/R 도구를 사용하고 튜닝하는데 있어 작지만 중요한 일단의 작업이 남아있는 것을 발견 할 것이다.
Even if you do buy a tool, however, it's a good idea to be aware of these patterns. Good O/R tools give you a lot of options in mapping toa database, and these patterns will help you understand when to use thedifferent choices. Don't assume that a tool makes all the effort go away. It makes a big dent, but you'll still find that using and tuning an O/R tool takes a small but significant chunk of work.
# by | 2007/11/07 21:09 | 프로그래밍 이야기 | 트랙백 | 덧글(0)
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]