2014-05-15 2 views
2

매우 하드 코딩 된 Java 구현에서 매우 모듈화 된 스칼라 구현으로 이동하고 있으며 내 응용 프로그램의 일부를 번역하지 못했습니다.사례 객체를 기반으로 한 매개 변수

내가보고있는 함수는 형식 문자열에서 메시지를 생성합니다. 데이터베이스에서 관련 정보를 찾고이를 사용하여 문자열을 형식화합니다.

public static String getHumanizedMessage(Type type, User user, Long relatedId){ 
    switch(type.getTypeName()){ 
    case NEW_FOO:{ 
     Foo foo = Foo.findById(relatedId); 
     return String.format(type.getMessage(), user.name, foo.name); 
    } 
    case BAR_SHARED:{ 
     Bar bar = Bar.findById(relatedId); 
     Baz baz = Baz.findById(relatedId); 
     return String.format(type.getMessage(), user.name, bar.name, baz.name); 
    } 
    default: 
     break; 
    } 
    return null; 
} 

그래서 사물의 스칼라 측에, 나는 모두가 기본 Type에서 확장 할 경우 개체를 사용하여 다른 유형을 구현하기 위해 노력했습니다.

sealed class Type(val name: String) 

case object NewFoo extends Type("New Foo") 
case object BarShared extends Type("Bar Shared") 

문제는 내 응용 프로그램은 내가 액세스 Foo.findById, Bar.findById 또는 Baz.findById이없는 내 MessageService에 모듈 인 상태입니다. 매개 변수 목록에 적절한 문자열을 수신하고 싶습니다. 그러나 볼 수 있듯이 매개 변수의 수는 Type에 따라 다릅니다. 필자는 매개 변수를 선택적으로 만들 수 있지만 그 함수를 호출하는 모든 사용자는 형식을 기반으로 필요한 매개 변수를 알아야합니다. 나는 그것을 좋아하지 않습니다. 각 유형마다 다른 함수 이름을 사용할 수 있다고 가정합니다. 그러나 더 좋은 방법이 있다면 차라리 사용하지 않을 것입니다.

+2

정말 마지막 단락을 따라갈 수없는 것 같습니다. 정확히 무엇을하고 싶으십니까? 이 'MessageService'는 무엇입니까? 적절한 문자열을 어디에서 받고 싶습니까? – DCKing

+0

프로젝트를 기능을 제공하는 모듈이있는 모듈로 나눕니다. 'findById'와 같은 데이터베이스 메소드를 호출하기 위해'UserService' 나'BarService'에 접근 할 수없는'MessageService'에서 이런 일이 일어나고 있습니다.따라서 필자의'getHumanizedMessage'는'relatedId'를 매개 변수로 가져 와서 필요한 객체를 찾을 수 없습니다. 나는'String' 매개 변수를 가져 가고 싶습니다. 그러나 필요한 문자열의 수가 항상 같지는 않을 것입니다. – mgeiger

답변

1

Type 형식의 지식을 인코딩해야 할 수도 있습니다. MessageService 불가지론자를 어떤 데이터가 들어오는 지 계속 유지하려는 것이 목표 인 경우 같은 자체의 형식을 각 유형이 필요합니다

trait MessageType { 
    val name: String 
    def format(relatedId: Long): String 
} 

case class FooMessageType(foo: Foo) extends MessageType { 
    val name = "Foo" 
    def format(relatedIid: Long) = { 
    val foo = Foo.findById(relatedId) 
    "This is ${foo.name}" 
    } 
} 

이 그런 다음 MessageServiceMessageType 인터페이스에 대해 알고 것이고, 구현은 그 다른 모듈에 제공 될 것입니다. 시작할 때 MessageService에 대한 각 모듈의 MessageTypes 등록을 허용해야 할 수도 있습니다.

1

getHumanizedMessage()은 처음에는 하나의 방법이었습니다. switch 문으로 인해 한 함수에서 완전히 다른 두 가지 작업을 수행합니다. 왜 쪼개지 그래?

당신은 쓸 수 있습니다 : 당신은 여전히 ​​쉽게 매치 문에 대한 sealed 구현을 사용할 수 있습니다

def getHumanizedMessage(foo: Foo, user: User) = String.format(NewFoo.getMessage(), user.name, foo.name) 
def getHumanizedMessage(bar: Bar, baz: Baz, user: User) = String.format(BarShared.getMessage(), bar.name, baz.name, user.name) 
0

, 당신은 그냥 기본으로 추상 클래스가 필요합니다. 그런 다음 케이스를 확장 할 수 있습니다

sealed abstract class MessageType { 
    val name: String 
    def findById[A](relatedId: Long): A 
} 

는 객체 또는 경우에 클래스는 사용 사례에 따라 :

case class BarShared(defaultName: String) extends MessageType { 
    val name: String = defaultName 
    def findById(relatedId: Long) BarShared = {...} 
} 

봉인 된 클래스 어울리는로 :

case object NewFoo extends MessageType { 
    val name: String = "NewFoo" 
    def findById(relatedId: Long): NewFoo = {...} 
} 

하거나 인수를 제공하려는 경우 명령문은 확장으로 정의하지 않는 한 디폴트를 필요로하지 않습니다.

관련 문제