복붙노트

[SCALA] 어떻게 하드 코딩없이 케이크 패턴 의존성 주입을해야합니까?

SCALA

어떻게 하드 코딩없이 케이크 패턴 의존성 주입을해야합니까?

난 그냥 읽고 케이크 패턴의 기사를 즐겼다. 하지만, 내 마음에, 의존성 주입을 사용하는 주요 이유 중 하나는 당신이 구성 요소는 XML 파일이나 명령 줄 중 하나를 인수로 사용되는 달라질 수 있다는 것입니다.

어떻게 DI의 측면은 케이크 패턴으로 처리? 나는 모든 본 적이 예제는 정적의 특성을 혼합 포함한다.

해결법

  1. ==============================

    1.당신이 객체에 혼합 특성을 변화 어떤 조건에 따라 서로 다른 객체를 만들려면 특성에 혼합하기 때문에, 스칼라에 정적으로 이루어집니다.

    당신이 객체에 혼합 특성을 변화 어떤 조건에 따라 서로 다른 객체를 만들려면 특성에 혼합하기 때문에, 스칼라에 정적으로 이루어집니다.

    의이 정식 케이크 패턴의 예를 보자. 귀하의 모듈 특성으로 정의하고, 응용 프로그램은 혼합 기능의 무리와 함께 간단한 객체로 구성되어

    val application =
        new Object
    extends Communications
       with Parsing
       with Persistence
       with Logging
       with ProductionDataSource
    application.startup
    

    그 라인은 당신의 모든 모듈 간 종속성이 존재 독특하고 잘 입력하면 컴파일 이제 그 모든 모듈은 자신의 모듈 간 종속성을 정의하는 좋은 자기 타입 선언이있다. 특히, 지속성 모듈은 아무것도 구현 지속성 또한 데이터 소스, 추상적 인 모듈 특성을 구현해야한다고 말한다 자체 유형이 있습니다. ProductionDataSource는 데이터 소스에서 상속 때문에, 모든의 위대한 및 해당 응용 프로그램의 구성 선은 컴파일합니다.

    하지만 당신은 테스트 용으로 일부 로컬 데이터베이스를 가리키는 다른 데이터 소스를 사용하기 위해 무엇을해야할까요? 당신은 단지 몇 가지 속성 파일에서로드 다른 구성 매개 변수와 ProductionDataSource를 다시 사용할 수 없습니다 것을 더 가정한다. 당신이이 경우에서하는 것은 데이터 소스를 확장하는 새로운 형질 TestDataSource을 정의하고, 대신에 혼합이다. 당신은 명령 줄 플래그에 따라 이렇게 동적으로 할 수 있습니다.

    val application = if (test)
      new Object
        extends Communications
          with Parsing
          with Persistence
          with Logging
          with TestDataSource
    else
      new Object
        extends Communications
          with Parsing
          with Persistence
          with Logging
          with ProductionDataSource
    
    application.startup
    

    이제 응용 프로그램이 여러 축에 그것의 건축을 변경해야하는 경우 특히, 좀 더 자세한 우리가 원하는 것보다 보인다. 적어도 고통을 최소화하고 논리의 나머지 부분으로부터 분리되도록 좋은면, 당신은 일반적으로 당신은 단지 (또는 최악의 경우 한 번에 식별 가능한 구성 요소 라이프 사이클 당) 응용 프로그램에서 같은 조건 건설 논리의 하나 개의 덩어리가있다.

  2. ==============================

    2.스칼라는 스크립트 언어입니다. 그래서 구성 XML은 스칼라 스크립트가 될 수 있습니다. 그것은 형태 보증하지-A-서로 다른 언어입니다.

    스칼라는 스크립트 언어입니다. 그래서 구성 XML은 스칼라 스크립트가 될 수 있습니다. 그것은 형태 보증하지-A-서로 다른 언어입니다.

    간단하게 시작 보면 :

    scala -cp first.jar:second.jar startupScript.scala
    

    못하는 것보다 너무 다르다 :

    java -cp first.jar:second.jar com.example.MyMainClass context.xml
    

    당신은 항상 DI를 사용할 수 있지만 또 하나의 도구가 있습니다.

  3. ==============================

    3.짧은 대답은 스칼라가 현재 동적 유지 mixin에 대한 내장 지원하지 않는다는 것입니다.

    짧은 대답은 스칼라가 현재 동적 유지 mixin에 대한 내장 지원하지 않는다는 것입니다.

    컴파일러는 훨씬 쉽게 작업하고 새로운 기능을 때 나는 그것이 2.9 릴리스 될 때까지 보류 현재 비록,이 기능을 지원하기 위해 자동 프록시 - 플러그인 작업입니다.

    한편, 가장 좋은 방법은 동일한 기능은 다음 래퍼 클래스로 동적으로 추가 동작을 구현하는 포장 멤버로 다시 암시 적 변환을 추가하여 거의 정확하게 달성했다.

  4. ==============================

    4.자동 프록시 플러그인을 사용할 수있을 때까지, 효과를 얻을 수있는 한 가지 방법은 위임을 사용하는 것입니다 :

    자동 프록시 플러그인을 사용할 수있을 때까지, 효과를 얻을 수있는 한 가지 방법은 위임을 사용하는 것입니다 :

    trait Module {
      def foo: Int
    }
    
    trait DelegatedModule extends Module {
      var delegate: Module = _
      def foo = delegate.foo
    }
    
    class Impl extends Module {
      def foo = 1
    }
    
    // later
    val composed: Module with ... with ... = new DelegatedModule with ... with ...
    composed.delegate = choose() // choose is linear in the number of `Module` implementations
    

    그러나 이것의 단점은 좀 더 자세한 점이다, 조심, 당신은 당신이 특징 내부에 바르를 사용하는 경우 초기화 순서에주의해야한다. 또 다른 단점은 경로 의존적 유형은 위의 모듈 내에있는 경우, 당신이 쉽게 위임을 사용할 수 없습니다 것입니다.

    변경 될 수있는 다른 구현의 수가 많은 경우, 그것은 아마 모든 가능한 조합의 경우를 나열하는 것보다 당신에게 더 적은 코드를 요할 것이다.

  5. ==============================

    5.리프트 그것은 대부분 스칼라 코드입니다. 내장 그 라인을 따라 뭔가를 가지고 있지만, 당신은 몇 가지 런타임 제어 할 수 있습니다. http://www.assembla.com/wiki/show/liftweb/Dependency_Injection

    리프트 그것은 대부분 스칼라 코드입니다. 내장 그 라인을 따라 뭔가를 가지고 있지만, 당신은 몇 가지 런타임 제어 할 수 있습니다. http://www.assembla.com/wiki/show/liftweb/Dependency_Injection

  6. from https://stackoverflow.com/questions/5172188/how-do-you-do-dependency-injection-with-the-cake-pattern-without-hardcoding by cc-by-sa and MIT license