2017-02-24 11 views
1

소유하고있는 엔티티를 처리하는 서비스를 분리하는 디자인 패턴이나 규칙을 찾고 있습니다. 테마 만들기를 처리하는 ThemeService이 있다고 가정 해 보겠습니다. 처음에는 ThemeService이 각 사용자의 UserData에 대한 테마를 유지하지만 요구 사항이 변경되고 테마는 ThemeCollection과 같은 다른 항목에 의해 소유됩니다. 내 문제는 각각의 ThemeService은 "소유하고있는"엔티티가 무엇이든 밀접하게 연결되어 있다는 것입니다. 예 :소유 한 업체의 서비스를 분리하는 디자인 패턴은 무엇입니까?

public class ThemeService{ 
    //coupled to UserData 
    createTheme(Theme t, UserData u); 
    getTheme(String name, UserData u); 
    hasTheme(String name, Userdata u); //Theme name unique within a userdata. 
    validateTheme(Theme t, UserData u); //unique name per user, valid colors, etc. 
} 

public class UserDataService{ 
    ThemeService tService; //component for themes 

    getUsername(UserData u); 
    addTheme(Theme t, UserData u){ tService.createTheme(t, u); } 
    getTheme(String name, UserData u){ tService.getTheme(name, u); } 
    hasThemes(String name, UserData u){ tService.hasTheme(name, u); } 
} 

이제 ThemeService는 UserData와 밀접하게 연결됩니다. 요구 사항이 적 변경 및 테마가 다른 기업에 속할 수있는 경우, ThemeCollection 예를 들어, 다음 정말 ThemeService에서 많은 코드를 다시 사용할 수 없으며, 지금 ThemeCollection 물건에 대한 더 많은 코드가 필요합니다

public class ThemeService{ 
    //...continued or in another ThemeService class... 
    createTheme(Theme t, ThemeCollection c); 
    getTheme(String name, ThemeCollection c); 
    hasTheme(String name, ThemeCollection c); 
    validateTheme(Theme t, ThemeCollection c); 
} 

public class ThemeCollectionService{ 
    ThemeService tService; 

    getCollectionName(ThemeCollection c); 
    addTheme(Theme t, ThemeCollection c){ tService.createTheme(t, c); } 
    getTheme(String name, ThemeCollection c){ tService.getTheme(name, c); } 
    hasThemes(String name, ThemeCollection c){ tService.hasTheme(name, c); } 
} 

I을 "Themeable"과 같은 것을 구현하는 일반적인 매개 변수를 사용하도록 유혹 될 것입니다. 그러나,이 엔티티는 인터페이스 구현 할 것 : 나는 내 엔티티 클래스에서 비즈니스 로직을 원하지 않기 때문에하여 Themeable 인터페이스 등을 얻을 생성, 검증에 포함되지 않습니다

public class ThemeService{ 
    createTheme(Theme t, Themeable owner); 
    getTheme(String name, Themeable owner); 
    hasTheme(String name, Themeable owner); 
    validateTheme(Theme t, Themeable owner); 
} 

@Entity 
public class UserData implements Themeable{ 
    getUsername(); 
    getThemes(); //From Themable 
} 

@Entity 
public class ThemeCollection implements Themeable{ 
    getUsername(); 
    getThemes(); //From Themable 
} 

을하는해야 잘하면 순수한 데이터 구조 (모델의 비즈니스 로직을 로버트 마틴 (Robert Martin)의 "클린 코드 (Clean Code)"에 따르면 엉뚱한 것으로 간주하고, 몇 가지 표준을 따르려고 노력하고있다).

이것을 분리하는 표준 방법, 패턴, 규칙 등이 있습니까? 내가 가지고있는 것이 더 많거나 적은 "괜찮은"것입니까, 아니면 프로덕션 환경에서 눈살을 찌푸리게합니까? 나는 "일을 끝내고"모듈화되고 재사용 가능한 코드로 돌아가려고 노력하고있다. 그래서 어떤 도움이나 조언도 크게 환영받을 것이다.

편집 : "서비스가 두 개의 엔티티에 연결된 이유는 무엇입니까?"

소유하고있는 엔티티와 소유 된 엔티티를 '꿰매기'위한 장소가 필요합니다. 예를 들어, UserData를위한 createTheme :

public void createTheme(Theme t, UserData u){ 
    entityManager.persist(t); 

    if(!hasTheme(t.name(), u){ 
     u.getThemes().add(t); 
     entityManager.merge(u); 
    } 
} 

그래서이 기능은 UserData를 결합하고, 유사한 "테마 소유자는"유사한 코드를 가질 것이다.

+0

귀하의 서비스가 두 개의 사업체에 연결된 이유는 무엇입니까? 이 이유를 밝힐 수있는 코드를 게시 할 수 있습니까? –

+0

@NiklasP 질문 끝에 짧은 스 니펫을 추가했습니다. – GuitarStrum

+0

이것은 질문에 대한 대답이 아닙니다. 'UserData'가 참으로 ** 'Theme'을 소유하고 있다면, 새로운 테마를 추가하는 것이'UserData' 엔티티를 갱신하는 것 이외의 것을 포함할까요? 당신이 언급 한 '바느질'은 아마'UserDataService'에서 이루어져야합니다. – crizzis

답변

1

좋은 접근 방식은 사용자로부터 테마 수집의 개념을 분리하는 것입니다. 그런 다음 당신은 : 테마 관리와 관련된

이러한 방법으로
Class Theme 
Class ThemeCollection //all theme managment things go here 
Class UserData //has a member of type ThemeCollection 

, functionalites이 ThemeCollection에있는 다른 엔티티간에 공유 할 수 있습니다.

+0

그게 내 문제는 ThemeCollection 또한 단지 데이터 구조입니다. ThemeCollection은 ServiceLayer가 데이터 구조에서 추상화 한 자체를 유지하고 소유자를 병합하는 방법을 알아야합니다. ThemeCollection을 데이터베이스 측의 소유자에게 스티치하는 서비스는 여전히 소유자를 병합하기 위해 소유자를 알아야하는 커플 링 문제가 있습니다. – GuitarStrum

+0

ThemeCollection에 새 테마를 추가 할 때 소유자는 자신을 업데이트 할 필요가 없습니다. 왜냐하면 이미 ThemeCollection과의 관계를 유지했으며 그 안에 무엇이 있는지 신경 쓰지 않기 때문입니다. ThemeCollection 만 병합됩니다. – sara

+0

네,하지만 이전 코멘트에서 의미 한 것은 ThemeCollection이 Theme에있는 것과 같은 위치에 있다는 것입니다 : ThemeCollection은 여전히 ​​UserData와 앞으로 잠재적으로 다른 엔티티에 묶일 필요가 있습니다. – GuitarStrum