2011-04-12 6 views
4

내 애플리케이션에 Order, Product, Customer 등의 비즈니스 클래스가 포함되어 있으며 데이터베이스에 저장/가져오고 싶습니다.유형 클래스가있는 스칼라의 DAO

일반적으로이 용도로는 DAO 패턴을 사용합니다.

trait DAO[T] { 
    def create(t:T) 
    ... // other CRUD operations 
} 
... 
// DAO implementations for specific business objects 
implicit object OrderDAO extends DAO[Order] { 
    def create(o:Order) {...} 
    ... // other CRUD operations 
} 
... 
// create a business object in the database 
def create[T](t:T)(implicit dao:DAO[T]) {dao.create(t)}

이제 내 문제는 모든 DAOs은을 사용하는 것을 : 지금은 형 클래스 패턴을 사용하고자하는 OrderDAO, ProductDAO 등 : 그건 우리가 모든 비즈니스 클래스의 DAO 인터페이스와 구현을 정의한다 DataSource 인스턴스 (데이터베이스 연결 팩토리)이므로 DAOsobjects으로 정의 할 수 없습니다. 내가 DataSource의 싱글 톤 인스턴스를 만들고 초기화시 모두 DAOs으로 전달해야합니다.

def dataSource():DataSource = {...}
가 어떻게 형 클래스DAOs을 구현하는 것이 :

은의 우리가이 DataSource 생성하는 기능을 갖고 있다고하자?

답변

1

모든 DAO를 보유하고 데이터 소스로 초기화하는 개체를 만드는 것이 어떻습니까? 여분의 간접 참조가 작동하지만

나는 (아직) 스칼라의 종속성 주입 처리하는 가장 좋은 방법을 모르는 그러나 이것은뿐만 아니라 당신을 위해 작동 할 수 있습니다

1

http://www.assembla.com/wiki/show/liftweb/Dependency_Injection 사샤에 동의합니다. 리프트 방식으로 작동합니다 :

trait DataSource 

class MyDataSource extends DataSource 

object DataSources { 
    @volatile var dataSource:() => DataSource =() => new MyDataSource 
} 

을 같은 방법으로 당신이 테스트 용이성을 잃지 않고 object를 사용할 수 있습니다.

+0

흥미 롭습니다. 설명해 주시겠습니까? – Michael

+0

죄송합니다. 코드에 오류가 있습니다. def가 아닌 var이어야합니다. 편집했습니다. – tonek

+0

이러한 접근 방식을 사용하면 실제로 데이터 소스의 함수 팩토리를 보유하는 DataSources 변수에 정의 할 수 있습니다. 프로덕션 코드에서는 객체 DataSources에 정의 된 변수의 기본값을 사용할 수 있습니다. 그러나 테스트에서 원하는대로 반환하도록 변수를 다시 정의 할 수 있습니다. – tonek

2

나는 타입 클래스가 여기에가는 길이라고 생각하지 않는다. 유형 클래스는 기능을 설명하기위한 것이지 DI를 대체하는 것이 아닙니다.

예를 들어 DAO가 키 - 값 저장소에 쓰는 경우 클래스를 키와 값의 맵으로 변환 할 수있는 기능이 필요할 수 있습니다.

이러한 경우 유형 클래스는 다음과 같습니다

trait KeyValuable[T] { 
    def toMap(t: T): Map[String, String] 
} 

을 그리고 당신이 환경에 관계없이 올바른 구현과 각 비즈니스 클래스를 제공 할 수 있습니다 분명하다. 유형을 상속하는 기능으로, 사용 방법에 구속되지 않습니다.