본문 바로가기
IT/mendix

고급 도메인 모델 1, 2

by 가능성1g 2025. 6. 24.
반응형

프로젝트 시작

- Mendix Academy 에는 Mendix Studio Pro 9.12.4 버전이 올라와 있는데, 최신-_- 의 버전으로 컴버트 해서 올립니다!

현재 기준 : 10.23.0

SoccerSquad10.23.0.zip
9.33MB
SoccerSquad10.23.0.z01
19.53MB

 

 

. 멘딕스 스튜디오 프로 10.23.0 열기

. Import App Package를 클릭합니다.

. 다운로드한 SoccerSquad.mpk 파일을 열기로 클릭합니다.

. 로컬에서 열기로 선택 하고 확인

 

엔티티를 상속을 하는 이유

Mendix의 상속은 일반화(generalization) 이라고 불리며, 이는 엔티티가 다른 엔티티를 상속받는 것을 말합니다. 

다음은 상속의 예 입니다!

. 개는 동물을 상속 받았습니다.

. 자동차는 탈것을 상속받습니다.

. 기밀 유지 계약은 일반 계약을 상속 받습니다. 

 

Mendix의 System 엔티티에도 여러 예제들이 있습니다.

Account 엔티티의 경우 System.User 를 상속 받습니다. 

 

 

위의 자동차는 탈것을 상속받는것의 예제 구성입니다. ( 기차도 추가됨! )

일반화를 추가하면 ( 상속을 추가하면 ) 특수화된 엔티티 ( 상속을 받은 하위 엔티티 )는 어트리뷰트, 어소시에이션, 이벤트 처리 마이크로플로우, 유효성 검사 규칙 및 기타 속을 모두 받습니다. 이렇게 하므로써, 논리를 재사용하고, 엔티티를 깨끗하게 관리 하고, 에플리케이션을 좀더 편하게 관리할 수 있습니다. 

 

또 다른 예로, 고객은 직원과 동일한 몇가지 특성을 가지므로, Employee 및 Customer 를 일반화 하여 Person 엔티티를 만드는 것이 좋을 수 있습니다. 하지만 고객목록이나 직원목록을 단일목록으로 표현할때 Person을 쓰거나, 어트리뷰트만 이용하기 위해 일반화를 사용하면 안됩니다.

 

Mendix 의 Generalization 은 코딩에서 추상화나 인터페이스를 사용하듯이 사용하면 안됩니다.

 

일반화(상속) 구성

특수화 할 엔티티의 속성에 있는 Generalization 에 일반화 엔티티를 설정하면됩니다. 

아래 예는 Train 엔티티에 Vehicle 을 지정하는 화면 입니다.

 

 

일반화를 사용하여 도메인 모델 확장하기

Adrian의 현재 앱은 각 팀의 팀 구성원만 관리합니다. 각 팀에는 팀을 관리하고 지원하는 직원이 있습니다. 직원은 팀 구성원, 사람과 같지만 코치 인증 및 라이선스 번호와 같은 팀 구성원과 다른 특정 정보를 가지고 있습니다. 이 실습에서는 팀 구성원과 직원을 모두 동등하게 처리하되 특수한 세부 정보를 사용할 수 있도록 상속을 사용하여 직원과 함께 앱을 확장합니다.

 

1. SoccerSquad 도메인 모델 열기

2. 엔티티 추가 Person , Staff

  • Person
    • FullName(String/200)
    • EmailAddress(String/200)
  • Staff
    • Function(Enumeration/ Head coach-감독, Assistant coach-수석코치, Coalkeeper coach-골키퍼 코치, Team manager - 팀 매니저, Medical staff - 의료진, Equipment staff 장비담당)
    • LicenseNumber(String/200)

3. Staff 와 Player 에  Person을 Generalization 으로 지정합니다. -> EmailAddress 중복 오류가 발생합니다.

4. Player 엔티티의 EmailAddress 속성을 EmailAddressOld 로 변경합니다.

5. Staff_Team 으로 association 을 추가 합니다.  ( Staff *-> Team )

6. 엔티티 접근을 셋팅합니다.

  • Person & Staff
    • Administrator/TeamMember 에 
      • access
      • Allow creating & deleting object 
      • Full read, full write
  • Player
    • 새로 추가된 속성에
    • full read and write

 

* 스탭 페이지 만들기

Staff 엔티티의 Generalization 으로 Person 지정해서 도메인 모델을 확장했습니다. 이제 Staff 을 추가할 수 있는 페이지를 만들어 봅시다. 

1. Team_NewEdit 페이지를 엽니다.

2. Tab Container 에서 오른쪽 클릭해서 탭을 추가합니다. 이름은 스탭으로 합니다.

3. 스탭 탭에 컨테이너를 추가 하고 아래와 같이 설정 합니다.

4. 컨테이너에 create button 을 추가 하고 아래와 같이 구성 한다.

  • 엔티티 : Team/Staff_Team/Staff
  • Caption : 스탭 추가
  • Button style : Success
  • Events > On click page : 신규 페이지 추가 - 이름 Staff_NewEdit ( Form horizontal/PopupLayout(Atlas )
  • 페이지에 Administrator 와 TeamMember 접근 규칙 추가

5. 컨테이너 아래에 빌딩 블록 List 1 추가

6. 데이터 소스로 Team/Staff_Team/Staff 지정 ( 자동 추가 하지 말것!! )

7. Staff/FullName 이 표시되도록 수정

8. 오른쪽 화살표 버튼(chevron link button) 에 Staff_NewEdit 연결

9. 웹 프로그램 실행

10. Adrian/Mendix123 으로 로그인

11. 스탭을 팀에 추가 해서 확인

* 상속이 DB 구조에 미치는 영향

아래 2개의 엔티티가 별도로 있는경우 고유한 테이블과 고유한 ID를 가지고 있는 상태입니다.

Car 가 Vehicle 을 Generalization 하게 되면, 아래 2가지 변경사항이 생깁니다.

1. Car 의 ID 가 Vehicle 에 동기화 되어서, Vehicle에 Car ID 가 생깁니다.

2. Vehicle에 Car 를 참조하는 컬럼이 추가 됩니다. 

Vehicle 개체를 생성하면 참조컬럼은 자신을 참조하게 됩니다.

Car 를 만들면, Vehicle과 Car 에 동일한 ID 로 모두 생성되고, 각 엔티티의 속성이 저장됩니다.

Train 객체를 만들면, 역시 Vehicle 과 Train 에 동일한 ID로 생성되고, 각 고유 엔티티의 속성이 저장됩니다.

즉, 상속을 지정한 엔티티는 부모/자식 두개의 테이블에 저장 됩니다. 두테이블은 동일한 ID를 사용합니다.

런타임 객체는 모든 속성을 포함하는 단일객체 입니다. 

 

* 상속 및 페이지

상속은 두개 이상의 개체 형식이 공통 동작을 공유하고, 동일한 프로세스를 처리하게 할 수 있습니다. 

샘플 앱에서 Adrian은 이 기능을 모든 팀선수와 스탭에게 이메일을 통한 알람을 보낼때 이용하려고 합니다. 

상속을 이용하면, 부모의 목록을 표시할 수 있습니다. 그리고 자식 엔티티의 특수한 사항은 별도 세부보기를 통해서 확인이 가능하게 됩니다. 

 

Car 엔티티 예시를 살펴보겠습니다. 탈것으로 기본뷰를 만들고 Car, Train 으로 별도 목록 표기가 가능합니다.

 

** 실습하기 **

1. Person_Overview 페이지를 엽니다.

2. List View 의 데이터 소스로 Person 을 설정합니다.

3. List View 의 내용을 삭제 하고 빌딩블록 List 2 항목을 추가합니다.

4. 텍스트 2개를 각각 Person/FullName, Person/EmailAddress 로 설정합니다. 

5. List View 속성에서 Templates 탭을 엽니다.

6. Player, Staff 2개의 템플릿을 추가 합니다.

7. List View 를 오른쪽 클릭해서 Templates > Template for 'Player' 를 선택하고, 내용을 모두 지운 후, 빌딩 블록 List 2 Item 을 추가합니다.

8. 첫번째 텍스트 위젯은 Player/ShirtNumber - Player/Name 으로 설정 하고, 두번째는 Player/EmailAddressOld 로 설정합니다. 

9. 7과 같이 해서 Staff 템플릿을 선택하고, 내용 지우고, 빌딩 목록 List 2 Item 으로 합니다.

10. 첫번째 텍스트 위젯은 Staff/FullName - Staff/Function 으로 하고, 두번째는 Staff/EmailAddress 로 표시하도록 합니다.

11. Deploy 후 실행합니다.

12. Adrian/Mendix123 으로 로그인 합니다.

13. 수정한 Person 페이지가 정상인지 확인합니다.

* Object Type decision 사용하기

자식 엔티티를 구별하고 사용하는 방법에 대해 설명합니다. 이렇게 하면 다양한 자식 엔티티와 일치하는 마이크로 플로우를 생성할 수 있습니다. 

 

* Object Type Decision

다음 Microflow 를 검토해 보겠습니다. Vehicle 객체로 시작해서 하위 객체의 편집 페이지를 열어야 합니다.

Vehicle 개체가 상속 대상인지 확인하려면 Object Type decision을 사용할 수 있습니다. Object Type decision 은 녹색 다이아몬드 모양입니다.

- 결정순서

Object Type decision 에는 두개이상의 시퀀스 흐름, 즉 부모 엔티티( Vehicle )와 empty  가 필요 합니다. 모든 자식 엔티티를 쓸 필요는 없습니다. 

상속에 따른 결정이니, 자식이 없는 경우 부모의 흐름에 따릅니다. 즉, Car와 Train 은 모두 Vechicle 입니다. Train 이 없다면, Vehicle 로 처리되는 식입니다.

- 모범사례

오류 방지를 위해서 empty 를 항상 선언하세요!

 

예를 들어, Vehicle 을 검색 했는데, 아무것도 반환되지 않았을 경우 비어있는지 확인하지 않고 Object Type decision을 실행합니다. 따라서 empty 를 확인하고, 오류를 기록해야 합니다.

 

* Object Casting

자식 엔티티에 접속을 하기 위해서는 엑세스 권한 관련으로 캐스팅을 해야 합니다. 즉 Vehicle 부모 엔티티를 Car 또는 Train 으로 캐스팅을 해야 Car 또는 Traion 의 속성에 접근이 가능합니다. 

- 모범 사례

상속을 사용하면, 재사용 가능한 함수를 쉽게 만들 수 있습니다. 자식 엔티티가 새로 생겼을 경우 마이크로 플로우에 쉽게 해당 자식 엔티티의 특수 처리를 추가 할 수 있습니다. 

예을 들어, 커밋 후 이벤트를 자식 엔티티 마다 구성할 수 있습니다. 또한 모든 부모 엔티티에 대한 처리를 추가 해서 공통 흐름을 만들 수도 있어, 일관성과 유지 관리 용이성이 크게 향상됩니다. 

 

*** 실습 ***

* Object Type Decision 을 사용하여 다른 편집 페이지를 열기

List View 에서 행을 클릭하면, 자식 엔티티에 따라 해당 하는 편집페이지가 열리도록 구현합니다.

1. Person_Overview 를 오픈합니다.

2. List View 를 더블클릭 하여, on click 에 call micro flow 를 선택합니다. 그리고 신규로 ACT_Person_OpenEditPage 를 만듭니다.

3. ACT_Person_OpenEditPage 를 오픈합니다.

4. Object Type decision 을 추가합니다. ( 녹색 다이아몬드 ) 그리고 입력객체로 Person 을 선택합니다. 

5. 처음 하나의 빨간색 시퀀스 흐름에 오른쪽 클릭하고 SoccerSquad.Person 을 선택합니다. 

6. 두개의 end event(빨간동그라미) 를 추가해서, 각각 SoccerSquad.Player, SoccerSuad.Stff 로 설정합니다.

7. Object Type decision 아래쪽에 end event 를 추가합니다. 자동으로 empty 로 됩니다. 

아래 모양과 같아야 합니다.

8. SoccerSquad.Person 시퀀스 flow 에 activity 를 추가합니다.

Show Page Activity 를 추가하고 전달할 객체로 Person 을 선택합니다.

9. Page 에 신규로 해서 Person_NewEdit, PopupLayout , Form Horizontal 을 선택합니다.

10. SoccerSquad.Player 시퀀스 flow activity를 추가합니다.

Cast 를 추가하고 객체 이름을 Player 로 합니다. Show Page 를 추가하고 페이지는 Player_NewEdit를 설정합니다.

11. SoccerSquad.Staff 시퀀스 flow에 activity 를 추가합니다.

10과 동일하게 하면됩니다. Staff 으로만 바꿉니다.

12. 권한으로 Administrator 와 TeamMember 를 추가합니다.

최종 마이크로플로우 모습입니다.

13. deploy 해서 앱실행을 합니다.

14. Adrian/Mendix123 로 로그인합니다.

15. 편집 테스트를 해봅니다!

 

* 상속 vs 로직에서 1-1 사용

상속보다 1-1 관계가 더 나은 경우를 알아봅시다.

상속은 다른 개체의 자식을때 사용됩니다. 그리고 항상 단일 객체로 사용되고 처리됩니다. Vehicle 과 Car 그리고 Person 과 Player, Staff 에 대해서 구현했습니다.

Adrian이 팀별로 로고를 추가해서 확장하는 경우를 생각해보겠습니다. Team 엔티티가 Image 엔티티를 상속하도록 설정하는 것과 별도의 이미지 엔티티를 만들어 이미지를 업로드 하는 방법입니다. 

 

* "is" vs "has"

-. 자식 엔티티가 부모의 엔티티의 전문화 버전이 맞습니까?

-. 전문화된, 즉 자신 엔티티가 부모의 속성, 연결, 동작을 항상 사용해야만 합니까?

 

이것을 Vehicle 과 Person 상황에서는 '예'가 될것입니다. Vehicle 의 무게와 색상도 Car 의 속성이며, 무게와 색상이 없는 Car는 없습니다. 또는 Person 전체이름과 이메일주소도 Player와 Staff 의 속성이고 전체이름이 없는 Player는 없습니다. 

 

하지만, 이것을 Team 과 Logo 의 경우에 적용하면 '아니오' 가 됩니다. Logo 가 모든 경우에 Team이 필요한 것은 아닙니다. Team 데이터를 사요할때 Logo가 필요하지 않은 경우가 많습니다. Team은 항상 Logo로 표시되어야 한다고는 말할 수 있습니다. Team 성과에 대한 보고서를 실행하고 마이크로플로우를 통해 Team 데이터를 가져오기 시작할때 Logo는 필요하지 않습니다. 따라서 Team 은 Logo 를 가지지만(has)  Team이 Logo 이다(is)는 맞지 않습니다. 

따라서 가장 좋은 방법은 이미지를 업로드하고 저장하기 위해 Logo 엔티티가 System.Image를 상속하는 것입니다. 그런 다음 Team과 Logo 엔티티 사이에 1-1 연결을 추가하여 각 Team이 Logo를 가질 수 있도록 합니다.

 

* 영향

상속과 1-1 연결 사이에는 큰 차이가 있습니다. 주요 차이점은 상속은 "is" 관계인 반면 1-1 연결은 "might have" 관계라는 것입니다. "is" 관계는 Car 가 Vehicle의 한 유형임을 의미하고, "might have" 관계는 Team이 Logo를 가질 수 있지만 필수는 아님을 의미 합니다.

 

- 데이터 베이스

상속을 처리할 때 두 엔티티는 데이터베이스에 두개의 테이블이 있는 단일 엔티티를 나타냅니다. 두 테이블은 부모 엔티티와 자식 엔티티 입니다. 

이에 비해 1-1 관계는 하나로 사용할 수 있는 두개의 엔티티 입니다. 1-1 관계의 경우 3개의 테이블이 있습니다. ( 2개의 엔티티 및 개체ID를 사용하는 연결을 포함하는 조인 테이블 ). 엔티티는 서로 관계를 가질 수 있습니다.

-. 성능

테이블의 갯수와 관계가 다르기 때문에, 두 옵션이 성능에 미치는 영향이 다릅니다.

 

상속을 처리 할 때, 자식 엔티티를 검색하면 모든 데이터는 두개의 테이블에서 검색 됩니다.

1-1 연결된 엔티티를 검색 할때는 검색데이터만 검색합니다.  연결된 데이터는 기본적으로 검색 되지 않으므로 두 엔티티 중 하나만 검색할때 데이터 전송에 미치는 영향이 적습니다. 그러나 두 엔티티가 항상 검색 된다고 하면 세개의 테이블을 모두 검색해야 하며, 이는 상속관련 2개의 테이블 검색 보다 느립니다. 

엔티티를 별도로 변경하거나 사용한다면 1-1 연결이 가장 좋습니다. 1-1 연결을 사용하면 필요한 것만 검색/변경할 수 있어서, 개별적으로 관리할때 상속 시나리오보다 빠릅니다. 상속은 항상 두 엔티티 모두에서 검색/변경 됩니다. 

항상 두 엔티티가 모두 필요하다면, 상속의 최상의 방법입니다. 상속은 최적화 되어 있어어 2개의 엔티티를 검색한다면 1-1 연결보다 빠릅니다. 

 

-. 동작

또한 Object Type decision 을 이용한다면 상속이 좋습니다.

1-1 관계인 경우, 논리를 재사용하려면 개발자가 더 많은 생각과 작업을 수행해야 하며, 연결 검사 또는 추가 열거형 값을 기반으로 decision 을 추가 해야 합니다. 

 

-. 객체의 라이프사이클

상속은 부모/자식 엔티티가 모두 자동으로 생성/검색/삭제 그리고 커밋 됩니다. 

1-1 연결은 수동으로 처리해야 합니다. 

 

여기까지 완성한 버전 입니다.

SoccerSquad10.23.0_Fin.z01
19.53MB
SoccerSquad10.23.0_Fin.zip
9.38MB

 

반응형