2012-07-27 4 views
11

DAO 패턴에 대한 많은 정보를 찾아 보았습니다. 하지만 대부분의 설명이 전체 이야기를 말하지 않는 것처럼 느껴집니다. 그 말은 실제로 DAO를 어디에서 사용하겠습니까? 그래서 예를 들어 나는 사용자 클래스와 저장하고 올바른 방법이다, 나를 위해 사용자를 복원 할 수있는 해당 UserDAO있는 경우 :DAO 패턴 및 모델 객체

  • 컨트롤러는 사용자 개체를 만들고에 UserDAO에 전달을 데이터베이스

  • 컨트롤러에 저장하면 사용자 개체를 만들고 해당 생성자에서 사용자 개체는이 코드 냄새와 당신이

  • 데이터베이스에 자체를 저장하기 위해 userDAO를 호출합니다 컨트롤러가 사용자 생성을 요청하는 "UserManager"클래스가 없습니다. 컨트롤러가 담당하는 모든 올바른 모델 객체에 요청을 위임 때문에 UserManager는 사용자를 만들고 여기에

세 번째 옵션은 최고입니다처럼 정말 기분을 저장 UserDAO 요청에 대한 책임 . 좋아하는 방법은 무엇입니까? 내가 여기서 뭔가를 놓치고 있니?

답변

12

있어 그를 확인하시기 바랍니다, 첫 번째 방법은 유일하게 올바른 하나입니다. 그 이유는 가장 분명한 책임을지며 가장 혼란스럽지 않은 프로그래머들이다. (Adam Bien은 이미 EntityManager에 구현 된 원래의 DAO 패턴과 추가 DAO가 대부분 불필요한 "파이프"라고 생각한다.)

접근법 2은 모델을 DAO에 바인딩하여 "업스트림 종속성"을 만듭니다. 제 말은 대개 모델이 별도의 패키지로 배포되며 지속성에 대한 세부 사항을 모르고 있어야한다는 것입니다. 당신이 묘사하고있는 것과 비슷한 패턴이 Active Record pattern입니다. Ruby on Rails에서 널리 사용되지만 Java에서 동등한 우아함과 단순성으로 구현되지 않았습니다.

접근 방식 3 - UserManager의 요점은 무엇입니까? 귀하의 예제에서 Manager는 2 개의 작업을 수행합니다.이 작업은 User 팩토리의 의무를 지니 며 지속성 요청을위한 프록시입니다. 공장인데 공장이 필요한 경우 추가 작업을 부과하지 않고 UserFactory으로 이름을 지정해야합니다. 프록시에 관해서 - 왜 당신은 그것을 필요로해야합니까?

IMHO 대부분의 클래스 ...Manager은 냄새가 있습니다. 이름 자체는 클래스에 명확한 목적이 없다고 제안합니다. 수업을 ...Manager으로 지명 할 때마다 필자는 더 나은 이름을 찾거나 내 건축에 대해 열심히 생각할 수있는 신호가됩니다.

+1

이 항목을 추가하기 만하면됩니다. 나는 또한 세션/트랜잭션을 관리하는 UserServices 객체를 생성한다. 그런 다음 실제로 UserServices에서 호출 된 쿼리를 수행하는 책임이있는 UserDAO 있습니다. – sbrattla

+0

@sbrattla - 사용자 트랜잭션을 사용하는 경우, 이는 분명히 의미가 있습니다. 나는 OP가 그들을 언급하지는 않았지만, EJB 트랜잭션을 자동적으로 가정하고 있었다. Kneejerk :) – kostja

+0

당신이 동의하지 않으면 @ 톰 - 정성 들여주세요 – kostja

0

데이터 액세스 개체 (DAO)는 응용 프로그램의 데이터 액세스 계층에 가까이 사용해야합니다. 데이터 액세스 개체가 실제로 데이터 액세스 작업을 수행합니다.그래서 그것은 데이터 액세스 레이어의 일부입니다.

DAO 이전의 아키텍처 계층은 프로젝트마다 다를 수 있습니다.

컨트롤러는 기본적으로 요청 흐름을 제어합니다. 그래서 그들은 UI에 가깝습니다. 관리자 인 Handler는 나쁜 생각이지만 컨트롤러와 DAO 사이에 레이어를 추가 할 수 있습니다. 따라서 컨트롤러는 요청이나 외출 (데이터 온 전성, 보안, 현지화, i18n, JSON으로 변환 등)에서 오는 데이터를 사전 처리합니다. 도메인 객체 (이 경우 사용자)의 형태로 서비스에 데이터를 전송합니다. 이 서비스는이 사용자의 비즈니스 논리를 호출하거나 일부 비즈니스 논리에 사용합니다. 그리고 나서 그것을 DAO에 전달할 것입니다. 당신이 등을하는 JSP, 웹 서비스, 핸드 헬드 장치,

0

처럼 여러 클라이언트를 지원하는 경우 컨트롤러 레이어에서 비즈니스 로직을 갖는

는 가정하면 컨트롤러가 "C"MVC에 의미 좋지 않다, 세 번째 옵션은 권리입니다 접근. 일반적으로 Controller 코드는 프레임 워크의 규칙을 확장하거나 따르는 역할을합니다. MVC의 이상 중 하나는 실제로 컨트롤러 인 프레임 워크를 교체하는 것이 상대적으로 쉽다는 것입니다. 컨트롤러는 모델과 뷰 레이어 사이에서 데이터를 앞뒤로 이동해야합니다.

모델 관점에서 컨트롤러는 domain model 앞에 앉아 service layer - a contextual boundary -와 상호 작용해야합니다. UserManager 개체는 도메인 계층의 공용 API 인 서비스 계층의 일부로 간주되는 조각의 예입니다.

0

첫 번째 방법은; IMHO, 컨트롤러 DAO 개체에 대한 메서드를 호출하는 좋은 디자인이 아닙니다. 컨트롤러는 비즈니스에 대한 "서비스"수준의 객체를 요구해야합니다. 이러한 "서비스"가 데이터를 유지하는 방법은 컨트롤러에서 중요하지 않습니다.

두 번째 방법은; 때로는 객체를 생성하기를 원할 수 있으므로 생성자의 의무와 지속적인 의무가 이와 같이 단단히 결합되어서는 안됩니다.

마지막으로, 관리자 또는 서비스 개체는 계층화 된 아키텍처에 대한 좋은 추상화입니다. 이렇게하면 비즈니스 흐름을 적절한 클래스 및 메서드로 그룹화 할 수 있습니다.

그러나 Play에서는 사례 클래스의 컴패니언 개체도 DAO로 사용할 수 있습니다. 이러한 객체의 싱글 톤 특성이 좋은 후보가됩니다.

case class TicketResponse(appId: String, ticket: String, ts: String) 

object TicketResponse{ 
    implicit val ticketWrites = Json.writes[TicketResponse] 

    def save(response: TicketResponse) = { 

    val result = DB.withConnection { 
     implicit connection => 

     SQL("insert into tickets(ticket, appid, ts)" 
      + " values ({ticket},{appid},{ts})") 
      .on('ticket -> response.ticket, 'appid -> response.appId, 'ts -> response.ts).executeInsert() 
    } 

    } 

}