Vietnam National University, Hanoi
VNU University of Engineering and Technology
LE MINH DUC
A Unified View Approach to Software Development Automation
Doctor of Philosophy Dissertation in Information Technology
Hanoi - 2020
ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
LÊ MINH ĐỨC
PHƯƠNG PHÁP TIẾP CẬN KHUNG NHÌN HỢP NHẤT CHO TỰ ĐỘNG HÓA PHÁT TRIỂN PHẦN MỀM
LUẬN ÁN TIẾN SĨ NGÀNH CÔNG NGHỆ THÔNG TIN
Hà Nội - 2020
Vietnam National University, Hanoi
VNU University of Engineering and Technology
LE MINH DUC
A Unified View Approach to Software Development Automation
Specialisation: Software Engineering
Code: 9480103.01
Doctor of Philosophy Dissertation in Information Technology
Supervisors:
1. Assoc. Prof., Dr. Nguyen Viet Ha 2. Dr. Dang Duc Hanh
Hanoi – 2020
ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
LÊ MINH ĐỨC
PHƯƠNG PHÁP TIẾP CẬN KHUNG NHÌN HỢP NHẤT CHO TỰ ĐỘNG HÓA PHÁT TRIỂN PHẦN MỀM
Chuyên ngành: Kỹ thuật Phần mềm Mã số: 9480103.01
LUẬN ÁN TIẾN SĨ NGÀNH CÔNG NGHỆ THÔNG TIN
NGƯỜI HƯỚNG DẪN KHOA HỌC:
1. PGS. TS. Nguyễn Việt Hà 2. TS. Đặng Đức Hạnh
Hà Nội – 2020
Declaration
I hereby declare that the materials presented in this dissertation are my own work, conducted under the supervision of Assoc. Prof., Dr. Nguyen Viet Ha and Dr. Dang Duc Hanh, at the Faculty of Information Technology, University of Engineering and Technology, Vietnam National University, Hanoi. All the research data and results presented in this dissertation are authentic and (to the best of my knowledge) have not previously been published in any academic publications by other authors.
Le Minh Duc
Abstract
An important software engineering methodology that has emerged over the past twenty years is model-based software development. At the heart of this methodology lies two complementary methods: model-driven software engineering (MDSE) and domain-driven design (DDD). While the aim of MDSE is ambitiously broad, DDD’s goal is more modest and direct but not less important – to apply model-based engineering techniques to tackle the complexity inherent in the domain requirements. The state-of-the-art DDD method includes a set of principles for constructing a domain model that is feasible for implementation in a target programming language. However, this method lacks the solutions needed to address the following important design questions facing a technical team when applying DDD in object oriented programming language (OOPL) platforms: (i) what constitues an essentially expressive domain model and (ii) how to effectively construct a software from this model. The dissertation aims to address these limitations by using annotation-based domain-specific language (aDSL), which is internal to OOPL, to not only express an essential and unified domain model but generatively construct modular software from this model.
First, we propose an aDSL, named domain class specification language (DCSL), which consists in a set of annotations that express the essential structural constraints and the essential behaviour of a domain class. We carefully select the design features from a number of authoritative software and system engineering resources and reason that they form a minimum design space of the domain class.
Second, we propose a unified domain (UD) modelling approach, which uses DCSL to express both the structural and behavioural modelling elements. We choose UML activity diagram language for behavioural modelling and discuss how the domain-specific constructs of this language are expressed in DCSL. To demonstrate the applicability of the approach we define the UD modelling patterns for tackling the design problems posed by five core UML activity flows.
Third, we propose a 4-property characterisation for the software that are constructed directly from the domain model. These properties are defined based on a conceptual layered software model that includes the domain model at the core, an intermediate module layer surrounding this core and an outer software layer.
Fourth, we propose a second aDSL, named module configuration class language (MCCL), that is used for designing module configuration classes (MCCs) in a module-based software architecture. An MCC provides an explicit class-based definition of a set of module con- figurations of a given class of software modules. The MCCs can easily be reused to create different variants of the same module class, without having to change the module class design. Fifth, we develop a set of software tools for DCSL, MCCL and the generators associated with these aDSLs. We implement these tools as components in a software framework, named jDomainApp, which we have developed in our research.
To evaluate the contributions, we first demonstrate the practicality of our method by applying it to a relatively complex, real-world software construction case study, concerning organisational process management. We then evaluate DCSL as a design specification lan- guage and evaluate the effectiveness of using MCCL in module-based software construction. We focus the latter evaluation on module generativity.
We contend that our contributions help make the DDD method more concrete and more complete for software development. On the one hand, the method becomes more concrete with solutions that help effectively apply the method in OOPL platforms. On the other hand, the method is more complete with solutions for the design aspects that were not originally included.
Tóm tắt
Trong vòng hai thập kỷ gần đây, phương pháp luận phát triển phần mềm dựa trên mô
hình nổi lên là một phương pháp luận quan trọng trong kỹ nghệ phần mềm. Ở trung
tâm của phương pháp luận này có hai phương pháp có tính bổ trợ nhau là: kỹ nghệ
phần mềm hướng mô hình (model-driven software engineering (MDSE)) và thiết kế
hướng miền (domain-driven design (DDD)). Trong khi MDSE mang một mục tiêu
rộng và khá tham vọng thì mục tiêu của DDD lại khiêm tốn và thực tế hơn, đó là
tập trung vào cách áp dụng các kỹ thuật của kỹ nghệ dựa trên mô hình để giải quyết
sự phức tạp vốn có trong yêu cầu miền. Phương pháp DDD hiện tại bao gồm một
tập các nguyên lý để xây dựng một mô hình miền ở dạng khả thi cho triển khai viết
mã trên một ngôn ngữ lập trình đích. Tuy nhiên phương pháp này còn thiếu các giải
pháp cần thiết giúp giải đáp hai câu hỏi quan trọng mà người phát triển phần mềm
thường gặp phải khi áp dụng DDD vào các nền tảng ngôn ngữ lập trình hướng đối
tượng (object oriented programming language (OOPL)): (i) những thành phần nào
cấu tạo nên một mô hình miền có mức độ diễn đạt thiết yếu? và (ii) xây dựng một
cách hiệu quả phần mềm từ mô hình miền như thế nào? Luận án này đặt mục đích
khắc phục hạn chế trên của DDD bằng cách sử dụng ngôn ngữ chuyên biệt miền dựa
trên ghi chú (annotation-based domain-specific language (aDSL)), được phát triển
trong OOPL, để không chỉ biểu diễn một mô hình miền hợp nhất thiết yếu mà còn để
xây dựng phần mềm có tính mô-đun từ mô hình miền này.
Thứ nhất, luận án đề xuất một aDSL, tên là ngôn ngữ đặc tả lớp miền (domain
class specification language (DCSL)), bao gồm một tập các ghi chú để biểu diễn các
ràng buộc cấu trúc thiết yếu và các hành vi thiết yếu của lớp miền. Tác giả đã cẩn
thận lựa chọn các đặc trưng thiết kế từ một số nguồn tài liệu học thuật có uy tín về
kỹ nghệ phần mềm và kỹ nghệ hệ thống và lập luận rằng các đặc trưng này tạo thành
một không gian thiết kế tối giản cho lớp miền.
Thứ hai, luận án đề xuất một phương thức tiếp cận mô hình hóa miền hợp nhất,
trong đó sử dụng DCSL để biểu diễn các thành phần mô hình hóa cấu trúc và hành
vi. Luận án đã chọn ngôn ngữ biểu đồ hoạt động UML cho mô hình hóa hành vi và
trình bày cách biểu diễn các đặc trưng chuyên biệt trạng thái của ngôn ngữ này bằng
DCSL. Để chứng tỏ tính thực tiễn của cách tiếp cận, luận án định nghĩa một tập mẫu
mô hình hóa miền hợp nhất cho các bài toán thiết kế liên quan trực tiếp đến năm
luồng hoạt động UML cơ bản.
Thứ ba, luận án đề xuất một mô tả đặc điểm gồm bốn tính chất cho phần mềm
được xây dựng trực tiếp từ mô hình miền. Bốn tính chất này được định nghĩa dựa trên
mô hình khái niệm phần mềm dạng phân lớp, bao gồm mô hình miền ở lớp lõi, một
lớp mô-đun trực tiếp bao quanh lớp lõi và một lớp phần mềm ở ngoài.
Thứ tư, luận án đề xuất một aDSL thứ hai, tên là ngôn ngữ lớp cấu hình mô-đun
(module configuration class language (MCCL)), dùng để thiết kế các lớp cấu hình
mô-đun (module configuration classes (MCCs)) trong một kiến trúc phần mềm dựa
trên mô-đun. Mỗi MCC cung cấp một định nghĩa dạng lớp cho một tập các cấu hình
mô-đun của một lớp mô-đun. Các MCC có thể dễ dàng sử dụng lại để tạo ra các biến
thể của một lớp mô-đun mà không cần sửa thiết kế bên trong của mô-đun.
Thứ năm, luận án phát triển một bộ công cụ dành cho DCSL, MCCL và các bộ
sinh mã của các ngôn ngữ này, dưới dạng các thành phần của một phần mềm khung,
tên là JDOMAINAPP. Để đánh giá các kết quả trên, luận án trước hết trình diễn tính
thực tiễn của phương pháp bằng cách áp dụng vào một trường hợp nghiên cứu tương
đối phức tạp về phát triển phần mềm, liên quan đến quản lý quy trình tổ chức. Tiếp
theo, luận án đánh giá DCSL từ khía cạnh một ngôn ngữ đặc tả và đánh giá hiệu quả
việc sử dụng MCCL trong xây dựng mô-đun phần mềm một cách tự động. Chúng tôi
cho rằng, các đóng góp của luận án giúp phương pháp DDD trở nên cụ thể và đầy đủ
hơn. Một mặt, phương pháp trở nên cụ thể hơn với các giải pháp giúp áp dụng một
cách hiệu quả vào các nền tảng OOPL. Mặt khác, phương pháp trở nên đầy đủ hơn
với các giải pháp cho các khía cạnh thiết kế chưa được xem xét tới.
Acknowledgement
I would first like to thank my supervisors, Assoc. Prof. Nguyen Viet Ha and Dr. Dang Duc Hanh, for their instructions and guidance throughout my research and the development of this dissertation. I would also like to thank all the teachers at the Faculty of Information Technology (University of Engineering and Technology, Hanoi) for the very kind support that I have received throughout my research study at the department.
I am deeply grateful for my home university (Hanoi University) for providing the PhD studentship and a gracious teaching arrangement, that has enabled me to have the time to complete the required course works and research. I am also very grateful for the financial support that I have additionally received from the MOET’s 911 fund and the NAFOSTED project (grant number 102.03-2015.25), led by Assoc. Prof. Nguyen Viet Ha.
I would also like to thank all of my colleagues and fellow PhD students for the many meaningful and entertaining discussions. Last but not least, I wish to thank my family for the sacrifices that they have made and for all the love and encouragement that they have given me during my PhD study.
Contents
Glossary v
List of Figures vii
List of Tables ix
1
Introduction 1.1 Problem Statement
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 Motivating Example . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.2 Domain-Driven Design Challenges . . . . . . . . . . . . . . . . . 1.1.3 Research Statement . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Research Aim and Objectives . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Research Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4 Dissertation Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 3 3 5 7 7 8 12
2 State of the Art
2.1 Background . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 Model-Driven Software Engineering . . . . . . . . . . . . . . . . . 2.1.2 Domain-Specific Language . . . . . . . . . . . . . . . . . . . . . . 2.1.3 Meta-Modelling with UML/OCL . . . . . . . . . . . . . . . . . . 2.1.4 Domain-Driven Design . . . . . . . . . . . . . . . . . . . . . . . . 2.1.5 Model-View-Controller Architecture . . . . . . . . . . . . . . . . . 2.1.6 Comparing and Integrating MDSE with DDD . . . . . . . . . . . . 2.1.7 A Core Meta-Model of Object-Oriented Programming Language . . 2.1.8 Using Annotation in MBSD . . . . . . . . . . . . . . . . . . . . . 13 13 13 15 17 22 27 28 29 33
i
2.2 Domain-Driven Software Development with aDSL . . . . . . . . . . . . . 2.2.1 DDD with aDSL . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.2 Behavioural Modelling with UML Activity Diagram . . . . . . . . 2.2.3 Software Module Design . . . . . . . . . . . . . . . . . . . . . . . 2.2.4 Module-Based Software Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Summary . . . . . 35 36 36 40 41 45
3 Unified Domain Modelling with aDSL
. . Introduction . 3.1 3.2 DCSL Domain .
. . . 3.3 DCSL Syntax .
3.4.1 3.4.2 Behaviour Space Semantics 3.4.3 Behaviour Generation for DCSL Model
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 Essential State Space Constraints . . . . . . . . . . . . . . . . . . 3.2.2 Essential Behaviour Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 Expressing the Pre- and Post-conditions of Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.2 Domain Terms 3.4 Static Semantics of DCSL . . . . . . . . . . . . . . . . . . . . . . . . . . State Space Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 Dynamic Semantics of DCSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6 Unified Domain Model 3.6.1 Expressing UDM in DCSL . . . . . . . . . . . . . . . . . . . . . . 3.6.2 UD Modelling Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.7 Summary . . . . . 46 46 47 47 48 49 56 57 57 58 64 68 71 72 73 76 87
4 Module-Based Software Construction with aDSL . . Introduction . . .
4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Software Characterisation . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 An Abstract Software Model . . . . . . . . . . . . . . . . . . . . . 4.2.2 Instance-based GUI . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.3 Model reflectivity . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.4 Modularity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.5 Generativity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 88 89 90 91 92 92 94
ii
4.5 MCC Generation .
4.3 Module Configuration Domain . . . . . . . . . . . . . . . . . . . . . . . . 4.3.1 One Master Module Configuration . . . . . . . . . . . . . . . . . . 4.3.2 The ‘Configured’ Containment Tree . . . . . . . . . . . . . . . . . 4.3.3 Customising Descendant Module Configuration . . . . . . . . . . . 4.4 MCCL Language Specification . . . . . . . . . . . . . . . . . . . . . . . . Specification Approach . . . . . . . . . . . . . . . . . . . . . . . . 4.4.1 4.4.2 Conceptual Model . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.3 Abstract Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.4 Concrete Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.1 Structural Consistency between MCC and Domain Class . . . . . . 4.5.2 MCCGEN Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6 Summary . . . . . . 95 95 95 96 97 97 98 104 110 114 114 114 116 118
5 Evaluation
. 5.1
. .
.
Performance Analysis
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Implementation . 5.1.1 UD Modelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.2 Module-Based Software Construction . . . . . . . . . . . . . . . . 5.2 Case Study: ProcessMan . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.1 Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.2 Case and Subject Selection . . . . . . . . . . . . . . . . . . . . . . 5.2.3 Data Collection and Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.4 Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 DCSL Evaluation . 5.3.1 Evaluation Approach . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.2 Expressiveness . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.3 Required Coding Level . . . . . . . . . . . . . . . . . . . . . . . . 5.3.4 Behaviour Generation . . . . . . . . . . . . . . . . . . . . . . . . 5.3.5 . . . . . . . . . . . . . . . . . . . . . . . . 5.3.6 Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4 Evaluation of Module-Based Software Construction . . . . . . . . . . . . . 5.4.1 Module Generativity Framework . . . . . . . . . . . . . . . . . . . 119 119 119 121 122 122 122 123 123 127 127 129 132 133 134 134 135 135
iii
5.4.2 M P1: Total Generativity . . . . . . . . . . . . . . . . . . . . . . . 5.4.3 M P2–M P4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.4 Analysis of MCCGen . . . . . . . . . . . . . . . . . . . . . . . . 5.4.5 Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.5 Summary . . 137 138 143 144 144
6 Conclusion
6.1 Key Contributions . 6.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 146 147
Bibliography 150
Appendices
A Helper OCL Functions for DCSL’s ASM 158
B MCCL Specification
164 164 167 B.1 Library Rules of the MCCL’s ASM . . . . . . . . . . . . . . . . . . . . . B.2 Two MCCs of ModuleEnrolmentMgmt . . . . . . . . . . . . . . . . . . . .
C DCSL Evaluation Data
. . C.1 Expressiveness Comparison Between DCSL and the DDD Frameworks C.2 Level of Coding Comparison Between DCSL and the DDD Frameworks . . 171 171 173
iv
Glossary
aDSL Annotation-Based DSL, page 36
ASM Abstract Syntax Meta-model, page 17
AtOP Attribute-Oriented Programming, page 35
BISL Behaviour Interface Specification Language, page 35
CSM Concrete Syntax Meta-model, page 17
DCSL Domain Class Specification Language, page 51
DDD Domain-Driven Design, page 22
DDDAL DDD with aDSLs, page 8
DSL Domain-Specific Language, page 15
JML Java Modelling Language, page 36
MCC Module Configuration Class, page 99
MCCL Module Configuration Class Language, page 99
MDA Model-Driven Architecture, page 13
MDD Model-Driven Development, page 13
MDE Model-Driven Engineering, page 13
MDSE Model-Driven Software Engineering, page 13
v
MVC Model-View-Controller, page 27
OCL Object Constraint Language, page 18
OOPL Object-Oriented Programming Language, page 29
PIM Platform-Independent Model, page 14
PSM Platform-Specific Model, page 14
SDM Semantic Domain Meta-model, page 17
UDM Unified Domain Model, page 76
UML Unifield Modelling Language, page 18
UML/OCL UML made precise with OCL, page 18
vi
List of Figures
1.1 A partial domain model of CourseMan. . . . . . . . . . . . . . . . . . . . 1.2 An overview of DDDAL (with an emphasis on phases 1 and 2). . . . . . . . 3 9
38
ment management activity.
2.1 The essential ASM of UML (synthesised from seven meta-models of UML [57]). 18 20 2.2 The OCL expression meta-model (Adapted from §8.3 [56]). . . . . . . . . 28 2.3 A UI class of the domain class Student (Source: [45]). . . . . . . . . . . . 2.4 The UML-based ASM of OOPL. . . . . . . . . . . . . . . . . . . . . . . . 30 2.5 The meta-model of UML activity modelling language (Adapted from §15.2.2 of the UML specification [57]). . . . . . . . . . . . . . . . . . . . . . . . . 2.6 The UML activity models of five basic variants of the CourseMan’s enrol- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39 2.7 The MOSA model of CourseMan. 43 2.8 A ModuleEnrolmentMgmt’s view containing a child ModuleStudent’s view. 44
50 55
75
management activity.
77 78
management activity.
3.1 The abstract syntax model of DCSL. . . . . . . . . . . . . . . . . . . . . . 3.2 A DCSL model for a part of the CourseMan domain model. . . . . . . . . (A: Left) The UML activity and class models of a CourseMan software 3.3 variant that handles the enrolment management activity; (B: Right) The . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . UDM that results. 3.4 The sequential pattern form (top left) and an application to the enrolment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 The sequential pattern form view of enrolment management activity. . . . . 3.6 The decisional pattern form (top left) and an application to the enrolment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.7 The decisional pattern form view of enrolment management activity. 79 80
vii
. . agement activity.
81 82
agement activity. . .
83 84
agement activity. . .
3.8 The forked pattern form (top left) and an application to the enrolment man- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.9 The forked pattern form view of enrolment management activity. 3.10 The joined pattern form (top left) and an application to the enrolment man- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.11 The joined pattern form view of enrolment management activity. 3.12 The merged pattern form (top left) and an application to the enrolment man- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.13 The merged pattern form view of enrolment management activity. 85 86
89
90
. .
4.1 A detailed view of DDDAL’s phase 2 with software module construction. . 4.2 An abstract UML-based software model: (core layer) domain model, (middle layer) module and (top layer) software. . . . . . . . . . . . . . . . . . . . . 4.3 The GUI of CourseMan software prototype generated by jDomainApp: (1) main window, (2-4) the UDM’s GUI for EnrolmentMgmt, Student, and . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enrolment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4 The CM of MCCL. 4.5 105
91 98 (A-shaded area) The transformed CM (CMT ); (B-remainder) Detailed design of the key classes of CMT . 109 . . . . . . . . . . . . . . . . . . . . . . . . . 4.6 The annotation-based ASM. 4.7 The view of a (stand-alone) ModuleStudent object. . . . . . . . . . . . . . 111 4.8 The customised view of ModuleEnrolmentMgmt (as configured in Listing 4.2).113
5.1 A partial CourseMan’s GUI that is generated by DomainAppTool. 5.2 ProcessMan’s domain model. 5.3 A partial MCC Model for process structure. 5.4 The view of ModuleEnrolmentMgmt of the software in Figure 5.1. 5.5 An example CourseMan software that has substantially been customised. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 124 125 138 141
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 160 A.1 Utility class ExprTk. . A.2 Utility class Tk.
viii
List of Tables
2.1 Meta-mapping between OOPL and UML/OCL . . . . . . . . . . . . . . . 33
. . . . . . . . . . . . . . . . . . . . . 3.1 The essential state space constraints 3.2 The essential behaviour types . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Well-formedness constraints of DCSL . . . . . . . . . . . . . . . . . . . . 3.4 The boolean state space constraints of DCSL . . . . . . . . . . . . . . . . 3.5 The non-boolean state space constraints of DCSL . . . . . . . . . . . . . . 3.6 The core structural mapping rules . . . . . . . . . . . . . . . . . . . . . . 3.7 Translating Domain Field properties into JML’s class invariants . . . . . . . 48 49 59 60 63 67 72
107 4.1 Mapping from CM to CMT . . . . . . . . . . . . . . . . . . . . . . . . . .
128
5.1 The expressiveness aspects and domain properties of interest 5.2
. . . 130
5.3
132 133 135 140 . . . . . . . . (A-left) Comparing DCSL to DDD patterns; (B-right) Comparing DCSL to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AL and XL . (A-left) Summary of max-locs for DCSL, AL and XL; (B-right) Summary of typical-locs for DCSL, AL and XL . . . . . . . . . . . . . . . . . . . . 5.4 BSpaceGen for CourseMan . . . . . . . . . . . . . . . . . . . . . . . . . 5.5 Module pattern classification . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6 Module generativity values of two CourseMan’s modules in M P2–M P4
C.1 Comparing the expressiveness of DCSL to AL, XL . . . . . . . . . . . . . C.2 Comparing the max-locs of DCSL to AL, XL . . . . . . . . . . . . . . . . C.3 Comparing the typical-locs of DCSL to AL, XL . . . . . . . . . . . . . . . 171 173 174
ix
Chapter 1
Introduction
There is no doubt that an important software engineering research area over the last two decades is what we would generally call model-based software development (MBSD) – the idea that a software can and should systematically be developed from abtractions, a.k.a models, of the problem domain. MBSD brings many important benefits, including ease of problem solving and improved quality, productivity and reusability. Perhaps a most visible and novel software engineering development that falls under the MBSD umbrella is model-driven software engineering (MDSE) [9, 16, 38, 67]. Another more modest and direct development method is domain-driven design (DDD) [22, 62, 75].
Very early on, Czarnecki [16] stated that MDSE is a type of generative software devel- opment (GSD). The key benefits of MDSE are to significantly improve reusability and pro- ductivity in producing software for different implementation platforms. These are basically achieved by constructing the high-level (platform-independent) software models before-hand and then very efficiently, typically with the help of proven automated techniques and tools, applying these models to a new platform to generate the software for it. This application step makes extensive use of reusable assets, including software frameworks, components, architectures and models [16].
While the MDSE’s goal is ambitiously broad and encompassing, DDD [22] focuses more specifically on the problem of how to effectively use models to tackle the complexity inherent in the domain requirements. DDD’s goal is to develop software based on domain models that not only truly describe the domain but are technically feasible for implementation. According to Evans [22], object-oriented programming language (OOPL) is especially suited for use with DDD. This is not surprising, given that Booch [8] had ealier pointed out two
1
main reasons why OOPL would result in domain models that are inherently expressive and feasible. First, object naturally represents the (abstract) entities that are conceived to exist in real-world domains. Second, the construct of object used in OOPL is also a basic construct of high-level analysis and design modelling languages that are used to conceptualise and analyse the domain.
The domain model, which is primarily studied under DDD and a type of model engineered in MDSE, is in fact the basis for specifying what had been called in the language engineering community as domain-specific language (DSL) [74]. The aim of DSL is to express the domain using concepts that are familiar to the domain experts. A key requirement in DSL engineering is to enable the domain experts and the technical team to focus on building the domain model, not having to worry about the technicality of language design.
A type of DSL, called annotation-based DSL (aDSL) [25, 54], appears to satisfy this requirement. aDSL is an application of the annotation feature of modern OOPLs in DSL engineering. Before this, however, annotation (called attribute in C# [33]) was used in attribute-oriented programming (AtOP) [12, 13] to express meta-attributes and in behaviour interface specification language (BISL) [32] to define the specification structure. A key benefit of aDSL is that it is internal to the host OOPL and thus does not require a separate syntax specification. This helps significantly reduce development cost and increase ease-of- learning.
In fact, simple forms of aDSL have been used quite extensively in both DDD and MDSE communities. In DDD, annotation-based extensions of OOPLs have been used to develop [17, 60]) that support the development of not only the domain software frameworks (e.g. model but the final software. The design rules in these models are expressed by a set of annotations. In MDSE, annotation sets are used to construct platform-specific models of software [4, 76, 77, 78].
Our initial research started out with an MBSD-typed investigation into a practical problem of how to improve the productivity of object-oriented software development [8, 43, 49, 51] using a Java-based design language for the domain model [44] and a software architectural model [45]. Placing these works in the context of DDD, MDSE and aDSL have given us an opportunity to advance our research to tackle a broader and more important problem concerning the DDD method for object-oriented software.
2
1.1 Problem Statement
In this section, we will discuss the key challenges facing DDD for the object-oriented problem domains and define a research statement that is tackled in this disseration. We motivate our discussion using a software example, which we will also use throughout the dissertation to illustrate the concepts that are being presented.
1.1.1 Motivating Example
Figure 1.1: A partial domain model of CourseMan.
Our motivating example is a course management problem domain (abbr. CourseMan), which describes a compact, yet complete, domain that includes both structural and behavioural aspects. Figure 1.1 shows a partially completed CourseMan domain model expressed in the form of a UML class diagram [57]. Notationwise, in this dissertation, when it is necessary
3
to highlight the type of model element we will use a/an/the with name of the element type to refer to a particular element, and the plural form of this name to refer to a collection of elements. Further, we will use normal font for high-level concepts and fixed font for domain-specific and technical concepts.
The bottom part of Figure 1.1 shows four classes and two association classes of Course- Man. Class Student represents the domain concept Student, who registers to study in an academic instituition. Class CourseModule represents the Course Modules1 that are offered by the institution. Class ElectiveModule represents a specialised type of CourseModule. Class SClass represents the student class type (morning, afternoon, or evening) for students to choose. Association class SClassRegistration captures details about the many-many association between Student and SClass. Finally, association class Enrolment captures details about the many-many association between Student and CourseModule.
The top part of Figure 1.1 (the area containing a star-like shape with this label “?”) shows six other classes that are intended to capture the design of an activity called enrolment management. We know some design details (the attributes shown in the figure) and the following description about the six classes. We will give more details about the activity later in Chapter 2.
– HelpRequest: captures data about help information provided to students.
– Orientation: captures data about orientation programs for newly-registered students.
– Payment: captures data about payment for the intuition fee that a student needs to
make.
– Authorisation: captures data about the decision made by an enrolment officer con- cerning whether or not to allow a student to undertake the registered course modules.
– EnrolmentApproval: captures data about the decision made by the enrolment officer
concerning a student’s enrolment.
1 we use class/concept name as countable noun to identify instances.
– EnrolmentMgmt: represents the enrolment management activity. This activity involves registering Students, enrolling them into CourseModules and registering them into SClasses. In addition, it allows each Student to raise a HelpRequest.
4
1.1.2 Domain-Driven Design Challenges
Let us now outline the key challenges facing domain modelling in DDD and software devel- opment from the domain model. Understanding these challenges leads us to formulate a set of open issues for the research statement that we tackle in this dissertation.
Essential Constraints
The UML note boxes in Figure 1.1 shows examples of 11 kinds of constraints concerning class, field and association. These constraints appear frequently in real-world domain models [34, 48, 49, 57]. We describe these constraints below:
1. Class Payment is immutable, i.e. all objects of this class are immutable.
2. Field Student.name is mutable, i.e. its value can be changed.
3. Student.name is not optional, i.e. its value must be specified for each object.
4. Student.name does not exceed 30 characters in length.
5. Student.name is not unique, i.e. its value may duplicate among objects.
6. Student.id is an id field.
7. Student.id is auto, i.e. its value is automatically generated.
8. The minimum value of CourseModule.semester is 1.
9. The maximum value of CourseModule.semester is 8.
10. The association constraint, e.g. with respect to the enrols-in association, a Student is enrolled in zero or no more than 30 CourseModules, and a CourseModule is enrolled in by zero or more Students.
11. The minimum value of CourseModule.semester in ElectiveModule is 3.
These constraints are primitive in the sense that they are applied independently to a single model element (e.g. class Student and Student.id). The key design questions concerning these constraints are: (i) are they essential to real-world domain models? and (ii) how do we represent these constraints in the domain model using an aDSL?
5
Essential Behaviour Types
When we consider constraints in designing the domain model, we are effectively constraining the state space of each domain class in the model. For this state space, two orthogonal design questions that can be raised are: (i) what are the essential types of behaviour that operate on a constrained state space? and (ii) how do we specify the behaviour types directly in each domain class, in such a way that can help capture the relationship with the state space?
Let us take class Student in Figure 1.1 as an example. Given the constrained state space that is structured around the class and its two attributes (id and name), what are the essential operations that must be defined for this class? More specifically, is the constructor Student(Student, String) shown in the figure sufficient for creating Student objects that the software needs? What are the basis for defining the other three operations of the class, namely getId, setName and getName? Are there any other essential operations that we need to add to this class?
Regarding to modelling the behaviour type, how do we specify the behaviours of, say, the constructor Student(Student, String) and the operations setName and getName so that they make explicit the connections to the attribute Student.name? Clearly, such connections help validate the essentiality of the behaviours, while making the design of Student easier to comprehend.
Software Construction from the Domain Model
Software construction from the domain model requires this model to essentially support both structural and behavioural modelling elements. UML [57] includes three behavioural modelling languages: state machine and interaction and activity diagrams. The first challenge is how to factor in the domain model the behavioural modelling structure (e.g. activity class and activity graph structure of an activity)? For the CourseMan example in Figure 1.1, for instance, how do we define the activity class EnrolmentMgmt and the activity graph structure of the concerned activity? This would cover the area labelled ‘?’ in the figure.
Another challenge with software construction is what software architecture can be suitable and how to use it to effectively construct software from the domain model? This challenge needs to be addressed in the context of a well-accepted fact that software construction can not be fully automated [26]. The generally accepted position is that a GUI-based tool is employed to assist the development team in the construction process.
6
The constructed software plays two important roles. First, it is used during domain model development to enable the development team to iteratively and interactively build the domain model. As discussed in [22], this phase is central to DDD. For the CourseMan example, for instance, the software would need to present a GUI that truly reflects the domain model structure. Further, it should support partially completed models, such as the one shown in Figure 1.1, and should evolve with the model as it is updated through the development iterations.
Second, the software is reused during production software development to quickly develop the production-quality software. For instance, the production-quality CourseMan software would be constructed not only from the finalised domain model but from the software components (e.g. architectural components, view layouts and view fields) that were used during the development of the domain model.
1.1.3 Research Statement
DDD is a design method that tackles the complexity that lies at the heart of software de- velopment. However, in the context of the challenges presented above, we argue that there are still important open issues concerning the object-oriented problem domains that need to be addressed. These issues fall into two main areas: domain modelling and software development from the domain model. First, the domain model does not define the essential structural elements and lacks support for behavioural modelling. Second, there has been no formal study of how aDSL is used in DDD. This is despite the fact that annotation is being used quite extensively in implementations of the method in the existing DDD software frameworks. Third, there has been no formal study of how to construct software from the domain model. In particular, such a study should investigate generative techniques (similar to those employed in MDSE) that are used to automate software construction.
1.2 Research Aim and Objectives
In this dissertation, we aim to address the issues mentioned in the research statement above by formally using aDSL to not only construct an essential and unified domain model but generatively construct modular software from this model. We claim that attaining this aim would help make the DDD method not only more concrete but more complete for object-
7
oriented software development purposes. On the one hand, the method would become more concrete with specific solutions that help the technical team effectively apply the method in the OOPL platforms. On the other hand, the method would become more complete with solutions for the design aspects that were not originally included. We organise our research with the following objectives:
1. To investigate and design a unified domain model that includes the essential elements
for both the structural and behavioural modelling aspects.
2. To investigate and characterise the software that is constructed from the domain model. This should include properties that are specific to software construction with DDD.
3. To investigate and define a generative and modular software construction approach.
4. To investigate and design suitable aDSL(s) for the unified domain model and for
software construction.
5. To implement a support tool, which includes the aDSL(s) and their generators.
1.3 Research Approach
We take the view that software is a system and apply the system approach [14, 19] to both engineer the software and to tackle the stated research problem. Churchman [14] generically defines system as “...a set of parts coordinated to accomplish a set of goals”. This definition means that system refers to both object and abstract construct of the human mind [19].
First, to engineer complex software requires a software engineering approach, which, according to Dekkers [19], is a type of system engineering approach. A complex software is one whose behaviour and interaction between the software components are initially not well-defined. A main characteristic of the system engineering approach for such software is that it is broken down into stages, which are performed in a disciplined manner to build the system. We adapt the iterative software engineering method [43, 70] to define an enhanced DDD method, shown in Figure 1.2 and which we call DDD with aDSLs (DDDAL).
2 paper 5 listed in the Publications section.
In principle, DDDAL consists of three phases that are performed in sequence and it- eratively. All three phases are supported by a software framework named jDomainApp 2.
8
Figure 1.2: An overview of DDDAL (with an emphasis on phases 1 and 2).
Phases 1 and 2 are the two key phases of the method and are depicted in Figure 1.2 with more details. The elements that are drawn using dashed lines in the figure are not within the research scope of this dissertation. Conceptually, phase 1 takes as input the (typically incomplete) structural and behavioural requirements from the domain experts and produce as output a domain model, called UDM. The purpose of phase 2 is to generate a software prototype that reflects the domain model in such a way that the project team can, in phase 3, intuitively review the model, the software and the associated requirements. The subsequent iterations repeat at phase 1 with an update on the domain model. The process is stopped when the domain model satisfies the requirements. From here, it is used to develop the production software. The generated software prototype is reusable for this development.
Consequently, our research approach in this dissertation is a system meta-approach, whose aim is to define a subset of elements for the first two phases of DDDAL. We consider these two phases as two sub-problems of our research problem (defined in Section 1.1), which are tackled by carrying out the research objectives (defined in the previous section). We will discuss in more detail below our research approach for tackling these two sub-problems.
9
Sub-Problem 1: Unified Domain Modelling with aDSL
This sub-problem is tackled by performing the research objectives 1, 4 and 5. We conduct a literature survey on the essential structural and behavioural features of the domain class and apply modelling and abstraction [19] to construct a unified domain model (UDM) that incorporates both types of features. We call the process for constructing UDM UD In the spirit of DDD, we encourage but do not force the use of any high- modelling. level modelling languages for expressing the input requirement sets. In our method, the designer works closely with the domain expert to map the input requirements, together with any accompanied high-level models, to the UDM and expresses this UDM in an aDSL. This collaboration is performed iteratively with the help of a GUI-based software prototype that is constructed directly from the UDM. We design the structural aspect of the UDM using UML class diagram and the behavioural aspect using UML activity diagram. We choose UML activity diagram because it has long been demonstrated to be domain-expert- friendly [20] and that it is tightly linked to the other two UML behavioural diagrams (state machine and interaction diagram [57]). To express UDM, we propose an aDSL named Domain Class Specification Language (DCSL). We apply modelling to specify DCSL and implement this language as part of the jDomainApp framework. We evaluate DCSL in terms of expressiveness, required coding level and constructibility.
Sub-Problem 2: Module-Based Software Construction with aDSL
It consists of This sub-problem is addressed by performing the objectives 2, 3, 4 and 5. two smaller problems: (2.a) to construct the software modules from the UDM and (2.b) to construct software from these modules. We perform a literature survey on DDD, DDD frameworks and software design properties. We then characterise a software in terms of four essential properties. We focus primarily on tackling problem (2.a). We conduct a literature survey on modular software development and adopt a module-based software architecture to explicitly model software in terms of a set of modules. Software modules are instantiated from module classes. The core component of each module class is a domain class. To automatically construct the module class, we focus on the module configurations and capture their design in a module configuration class (MCC). We then apply modelling and abstraction to specify an aDSL, named Module Configuration Class Language (MCCL), to express the MCCs. We implement MCCL as a component of the jDomainApp framework and evaluate module-based
10
software construction with MCCL.
The jDomainApp framework has an implementation for the sub-problem (2.b). However,
we do not discuss sub-problem (2.b) in detail in this dissertation.
Contributions
We summarise below five main contributions of our dissertation that concern the two sub- problems presented above. As the contributions will show, the term “unified view” in the dissertation’s title refers to our aDSL-centric view of automated software construction from the domain model: (i) domain model is expressed using an aDSL, named DCSL; (ii) software module construction is automated by using another aDSL, named MCCL.
Unified domain modelling with aDSL:
(cid:172) Domain Class Specification Language (DCSL): an aDSL for designing domain class It consists in a set of annotations that express the essential
in the domain model. structural constraints and essential behaviour of domain class.
(cid:173) A unified domain modelling approach: uses DCSL to construct a unified domain model that incorporates state-specific modelling elements of UML activity diagram.
Module-based software construction with aDSL:
(cid:174) A 4-property software characterisation: to provide a structured guidance for the
construction of software from the domain model.
(cid:175) Module Configuration Class Language (MCCL): an aDSL for designing the config- uration classes for software modules. Each of these classes serves as a template for creating the configurations of a module class.
(cid:176) Tool support: to evaluate the aforementioned contributions and to ease the adoption of our overall DDDAL method in real-world software projects, we implement DCSL, MCCL and the associated generators as components in the jDomainApp software framework.
11
1.4 Dissertation Structure
This dissertation is organised into 6 chapters that closely reflect the stated contributions. In Chapter 2, we systematically present the background knowledge concerning the concepts, methods, techniques and tools that are most relavant to the research problem and necessary for explaining our contributions in the rest of this dissertation. We also highlight the limitations of the existing DDD method and the works concerning the use of aDSL with MDSE and DDD.
In Chapter 3, we describe our contributions concerning UD modelling. Taking the view that domain class design is the basis for UDM construction, we first specify DCSL for expressing the essential structural and behavioural features of the domain class. We then use DCSL to define UDM. After that, we present a set of generic UD modelling patterns that can be applied to construct UDMs for real-world domains.
In Chapter 4, we explain our contributions concerning module-based software construc- tion. We first set the software construction context by defining a software characterisation scheme. We then specify MCCL for expressing the MCCs and present a generator for generating the MCCs.
In Chapter 5, we present an evaluation of our contributions. We first describe an imple- mentation of the research contributions as components in the jDomainApp framework. We then describe a real-world software development case study which we have developed using the implemented components. After that, we present two evaluations: one is for DCSL and the other is for module-based software construction.
In Chapter 6, we conclude the dissertation with a summary of the research problem, the contributions that we made and the impacts that these have on advancing the DDD method. We also highlight a number of ideas and directions for future research in this area.
12
Chapter 2
State of the Art
In this chapter, we present a methodological study of the literatures that are relevant to this dissertation. We have two main objectives. The first objective is to gather authoritative guidance for and to define the relevant foundational concepts, methods, and techniques. The second objective is to identify significant, unresolved issues that can be addressed in our research. In particular, we highlight the limitations of the existing DDD method and the works concerning the use of aDSL with MDSE and DDD.
2.1 Background
We begin in this section with a review of the relevant background concepts, methods and techniques concerning MDSE, DDD and OOPL. In particular, we highlight the role of aDSL (which is derived from OOPL) as the underlying theme that connects MDSE and DDD.
2.1.1 Model-Driven Software Engineering
Historically, model-driven software engineering (MDSE) evolves from a general system engineering method called model-driven engineering (MDE) . MDE in turn was invented on the basis of model-driven architecture (MDA) [55]. Early works, especially by Kent et al. [38] and Schmidt [67], use the term MDE. A recent book by Brambilla et al. [9] In particular, they relate MDSE to a form of defines MDSE as a more specialised term. MDE and highlights the differences between the latter and two other related terms (MDA and model-driven development (MDD)) that are also commonly used in the literature. Basically,
13
MDD is smaller in scope than MDE (the letter ‘D’ means development, while ‘E’ means engineering). MDA, on the other hand, is a particular realisation of MDD by the Object Management Group (OMG)1.
Since our aim in this dissertation is to study the development of software systems, we will limit our focus to just MDSE. Before reviewing the related work, let us clarify the meaning of two basic and related terms: domain and domain model. We adopt the following recent definition of both terms from Brambilla et al. [9].
Definition 2.1. Domain (a.k.a problem domain) is a field of expertise that needs to be examined to solve a problem. Domain model is the conceptual model of the domain.
The work by Kent et al. [38] serves as a good light-weight introductory background for MDSE, not only because of the timing of its publication but because it broadly covers MDE and does so on the basis of an initial draft specification of the MDA by OMG. They define MDA as “...an approach to IT system specification that separates the specification of system functionality from the specification of the implementation of that functionality on a specific technology platform” [55]. This means that the same system model of the functionality can be applied to different implementation platforms. The two types of specification in the above definition are represented by two types of model: platform-independent model (PIM) (the system functionality) and platform-specific model (PSM) (the platform).
MDA defines four types of model transformations between PIM and PSM and suggests that, to ease maintenance, these transformations be automated as much as possible. The first model transformation type is PIM-to-PIM, which is used for design refinement. The second type is PIM-to-PSM, which is for realising PIM in a particular platform. The third type is PSM-to-PSM, which is for platform model refinement. The fourth type is PSM-to-PIM, which is for reverse engineering PIMs from PSMs of an existing platform.
1 http://www.omg.org
Next, Kent et al. suggest that meta-modelling be used to specify the languages that are used to express models. This is attractive because it effectively reuses MDE to define itself. A meta-model is a model that expresses the shared structure of a set of related models. Among the key points about meta-modelling are: (i) language definitions are just models (called meta-models) with mappings defined between them, (ii) meta-modelling can be used to specify the abstract and concrete syntax, and the semantics of a language and (iii) meta-modelling is achievable with an object-oriented modelling language (e.g. MOF [58]).
14
Schmidt [67] both reinforces the work by Kent et al. and discusses another important contribution of MDE to software development. He argues that MDE had a potential for addressing the abstraction gap problem, through effective domain modelling. This prob- lem arised from a fact that software languages were primarily concerned with the solution spaces and, thus, were inadequate for effectively expressing the domain concepts. Schmidt next states that MDE technologies should be developed to use domain-specific modelling language (DSML) (a type of domain-specific language (DSL) [39] that is defined through meta-modelling) to construct models and transformation engine and generator to auto- matically produce other software development artefacts from the models. Before Schmidt, Czarnecki [16] also stated that MDA/MDD is a form of generative software development. We will discuss DSL shortly in Section 2.1.2.
More recently, Brambilla et al. [9] has studied MDSE as a method and how it is applied to engineering software. They define MDSE as “...a methodology for applying the advantages of modelling to software engineering activities”. The key concepts that MDSE entails are models and transformations (or “manipulation operations” on models). This definition then serves as the basis for integrating MDSE into four well-known software development processes. MDSE may be integrated into the traditional development processes (such as waterfall, spiral, and the like) by making models the primary artefacts and by using model transformation techniques to automate (at least partially) the activites that are performed within and at the transition between different phases.
MDSE can also be integrated into agile, domain-driven design (DDD) and test-driven development processes. Within the scope of this dissertation, we are interested in the integration capability of MDSE into DDD. We will discuss this capability in Section 2.1.6.
2.1.2 Domain-Specific Language
In general, DSL [40, 50, 74] is a software language that is specifically designed for expressing the requirements of a problem domain, using the conceptual notation suitable for the domain. An important benefit of DSL is that it raises the level of abstraction of the software model to the level suitable for the domain experts and thus help them participate more actively and productively into the development process. Despite the fact that different DSLs are designed for different domains, they share some underlying properties that can be used to classify them. DSLs can be classified based on domain [39] or on the relationship with the target
15
(a.k.a host) programming language [25, 50, 74]. From the domain’s perspective, DSLs are classified as being either vertical or horizontal DSL [39]. A vertical DSL, a.k.a business- oriented DSL, targets a bounded real-world domain. For example, course management is a real-world domain of CourseMan and the completed domain model of the one shown in Figure 1.1 would form the domain model of a vertical DSL for expressing this domain.
In contrast, a horizontal DSL (a.k.a technical DSL) targets a more technical domain, whose concepts describe the patterns that often underlie a class of vertical domains which share common features. Examples of horizontal DSLs include Structured Query Language (SQL), used for writing executable queries for relational databases, and Hypertext Mark-up Language (HTML), used for writing the source code of web pages.
Regarding to the relationship with the host language [25, 40, 50, 74], DSLs are classified as being internal or external. In principle, internal DSL has a closer relationship with the host language than external DSL. A typical internal DSL is developed using either the syntax or the language tools of the host language. In contrast, a typical external DSL has its own syntax and thus requires a separate compiler to process.
MDSE with DSL
It is a little surprising that the idea of combining MDSE with DSL [16, 67] only came out about five years after the OMG’s proposal for MDA/MDD. A plausible explanation for this, as Czarnecki [16] pointed out, is that the MDSE effort until then had only been focusing on addressing the platform complexity issue. It had paid almost no attention to the domain complexity problem. A recent DSL survey [40] reveals that this issue still remains: there has been insufficient focus in DSL research on domain analysis and language evaluation and on the integration of DSL engineering into the overall software engineering process.
The general method for combining MDSE with DSL is formulated in [9]. A technical discussion on how to use meta-modelling to engineer DSLs is presented in [39]. The work in [39] proposes two variants of the meta-modelling process: for vertical DSLs, it is the domain modelling process (discussed in detail in [25]); for horizontal DSLs, it is a pattern-based modelling process.
In practice, one of the very early works [77, 78] had experimented with combining MDSE and DSL in a layered, service-oriented architecture, named SMART-Microsoft. A key feature of this work is that it defines a framework for identifying and combining the DSLs that form
16
a complete software model. More specifically, this entails a 3-step development method: (i) determine the application architecture, (ii) develop the DSLs that fit this architecture and (iii) combine the DSLs by defining transformations between them. In this method, the DSLs are designed to address different parts of the architecture and each DSL is used to create not one monolithic model but multiple partial models.
2.1.3 Meta-Modelling with UML/OCL
As discussed above, meta-modelling is a modelling approach that is applied to defining DSL. More generally, Kleppe [39] suggests that meta-modelling is applicable to any software language. This includes both DSL and general purpose language (e.g. Java [28] and C# [33]). In meta-modelling, a language specification consists in three meta-models and the rela- tions between them. The first meta-model describes the abstract syntax and is called abstract syntax meta-model (ASM). The second meta-model describes the concrete syntax and is called concrete syntax meta-model (CSM). The third meta-model describes the semantics and is called semantic domain meta-model (SDM). According to Kleppe [39], the ASM describes the conceptual structure that exists in the language’s domain, while the CSM de- scribes the linguistic structure that helps present the conceptual structure to a pre-determined population of language users. The SDM makes clear the semantic structure of the concepts. Technically, if we consider the Kleppe’s view that a (modelling or programming) language is a set of mograms (a mogram is either a model or a program (resp.) written in the language) then SDM describes “...what happens in the computer when a mogram of the language is executed”. Here, “what happens in the computer” is defined based on a representation of the computer’s run-time. This representation must allow for a precise description of the run-time state when a mogram is executed.
As a general modelling approach, there are a variety of meta-modelling languages that can be applied. A de facto language is Unifield Modelling Language (UML) [57]. UML consists in a family of languages, one of which is UML class diagram. This language, which we will refer to in this dissertation as class modelling language, is made more precise when combined with the Object Constraint Language (OCL) [56]. This combination forms an enriched language, which we will generally refer to in this dissertation as UML/OCL. In fact, UML/OCL is used in the UML specification itself [56] to define the abstract syntaxes of the languages in the UML family. Later in Section 2.2.2, we will discuss an example of
17
how UML/OCL is used to specify the activity modelling language.
In the remainder of this section, we present an essential review of UML/OCL. Our focus is on the abstract syntax of a core meta-modelling structure of UML/OCL. The meta-concepts that form this structure will be used later in this dissertation to define aDSLs. The informal semantics of the meta-concepts are given in [56, 57]. In the spirit of meta-modelling, we adopt the approach used in the UML specification to use UML/OCL to define itself. Specifically, we first construct the ASM of UML and introduce very briefly the graphical syntax. After that, we discuss OCL and, as an example, explains how OCL is used to express some syntax rules of the ASM. We conclude with a brief review of the approaches for specifying SDM.
The Essential ASM of UML
Figure 2.1: The essential ASM of UML (synthesised from seven meta-models of UML [57]).
The essential ASM for UML consists of the following meta-concepts: Class, Attribute, Association, Association End, Operation, Parameter, Association Class and Generalisation. This ASM, which is shown in Figure 2.1, suffices for our research purpose in this dissertation. A meta-concept is represented in the figure by a labelled rectangle. A relationship between two meta-concepts is represented by a line segment that connects the two corresponding rectangles. On the one hand, the ASM is derived from a combination of the core structures of seven relevant UML meta-models presented in the UML specification [57]. On the other hand, it adds two new, more specialised, meta-concepts (Attribute and Association End) for modelling the class structure.
18
The referenced meta-models come from the following sections of the UML specification:
– Abstract syntax of the root (foundational) concepts of UML (see §7.2.22)
– Abstract syntax of Classifiers (the base concept of UML’s classification) (see §9.2.2)
– Abstract syntax of Feature which includes the Parameter concept (see §9.4.2)
– Abstract syntax of Property and the related concepts (see §9.5.2)
– Abstract syntax of Operation and the related concepts (see §9.6.2)
– Abstract syntax of Class – a type of Classifier – and the related concepts (see §11.4.2)
– Abstract syntax of Association and the related concepts (see §11.5.2)
To ease look-up, we label each key element of the ASM with the section reference, within whose meta-model the element is defined. For instance, meta-concept Class is defined in the meta-model of §11.4.2.
The ASM presented in Figure 2.1 includes two new meta-concepts: Attribute and Asso- ciation End. These meta-concepts, whose rectangles are filled in gray, are sub-types of the meta-concept Property. We use the two meta-concepts to differentiate between properties that are attributes and those that serve as association ends of associations. The former participate in the containment relationship between Class and Attribute, while the latter participate in the containment relationship between Association and Association End. Further, Class has a containment relationship with Association.
The Essential OCL
2 we use the symbol § to denote sections in the UML specification. 3 we use fixed font here to be consistent with the OCL’s notation style below.
According to the OCL specification [56], OCL is a user-friendly, typed, formal language for constructing expressions on UML models. OCL expressions are side-effect-free and each has a type. Typical examples of OCL expressions are invariants and queries over a UML model. The OCL specification consists in two packages: type (§8.2) and expression (§8.3). The former defines the valid types for the expressions in the latter. In the type package, all OCL types are derived from Classifier3 (see UML specification §9.2.2). Two core OCL types
19
Figure 2.2: The OCL expression meta-model (Adapted from §8.3 [56]).
that are commonly used are CollectionType and TupleType. CollectionType has four sub-types, namely SetType, OrderedSetType, SequenceType and BagType, representing sets, order sets, sequences, and bags (resp.). CollectionType is parameterised with an element type and can be nested. A nested CollectionType is one whose element type is another CollectionType.
The TupleType conveniently combines different types to form an aggregate type, called tuple. Each part of a tuple is represented by an attribute. An attribute is typed and is uniquely identified by a name. Similar to CollectionType, TupleType is also nested. This means that the attributes in a tuple can have their types defined as TupleTypes.
The expression package, whose meta-model is shown in Figure 2.2, specifies the structure of OCL expression. Every OclExpression is typed, which is usually not explicitly stated but derived. The core structure of OclExpression is described by VariableExp and the CallExp’s type hierarchy. VariableExp is an expression that involves the declaration and (possibly initialisation) of a variable. The initialisation consists in another OclExpression, which is typically a LiteralExp (for writing a value) or a CallExp. CallExp is used to “call”, i.e. set up, another expression that either, for the subtype named FeatureCallExp, references the value of a model’s feature (e.g. attribute, operation and association end) or, for the subtype named LoopExp, performs a loop over a collection. This loop involves a
20
Variable that points to each element of the collection and one or more OclExpressions that define a condition against which the elements are checked.
An OclExpression is defined in a context of a model element (e.g. a class, an attribute, a method, etc.). It is via this element that an OclExpression can navigate the model, through association chains, to access other model elements that are of interest. A special keyword self is available in every OclExpression for referring to the contextual element. To ease writing, this keyword is implicit if omitted.
1 context Association inv :
2
self . memberEnd - > exists (
3
4
5
e | e . aggregation <> AggregationKind :: none ) implies ( memberEnd - > size () = 2 and
6
memberEnd - > exists ( aggregation = AggregationKind :: none ) )
Example 2.1. Let us illustrate OCL by showing how it is used to express an invariant on the UML’s ASM in Figure 2.1. The invariant is taken from §11.8.1.8 of the UML specification [57], which states that an aggregation is a binary association:
Line 1 uses the keyword context to specify the context of the invariant (keyword inv) to be an Association. The invariant is interpreted as being true for every Association instance (at all times). Lines 2–6 form the body of the invariant. It is an implication A → B, where A is specified at lines 2–3 and B is specified at lines 5–6. The keyword implies means →. Lines 2–3 form a CallExp that performs an operation called exists over the collection self.memberEnd. This operation returns true or false depending on whether there exists an element of the collection that satisfies the condition: e.aggregation <> AggregationKind::none. In this condition, e is a Variable that points to each collection element and AggregationKind::none means ‘not-an-aggregation’. Thus, the condition effectively means to find all Association Ends of the current Association instance that is an aggregation of some kind.
Lines 5–6 state two conditions that hold for memberEnd (which is a short-form of self.memberEnd): (line 5) it contains exactly two elements (hence the association is bi- nary) and (line 6) at least one other Association End of the current Association is not an aggregation. The second condition consists in a negated expression of the one used in A.
21
Approaches for Specifying SDM
Kleppe [39] states four general approaches to defining the SDM of a language. The first approach is denotational, which uses a mathematics-based formalism. The second approach is translational, which translates the language into another language whose semantics is known. The third approach is pragmatic, which uses a reference implementation of the language as a way of describing semantics. This is a special form of the translational approach, in which the implementation language’s semantics is known. The fourth approach is operational, which defines the run-time state structure using some form of state-transition system and maps the mogram execution to the transition actions (or operations) in this system. It is worth mentioning that Kleppe’s view of the SDM amounts to what is called in the programming language community as dynamic semantics (Chapter 7 of [39]). It is dynamic in the sense that the semantics relies on the run-time state change. From the programming language’s perspective, there is also a static semantics of a language, which does not rely on the run-time. This semantics describes the well-formedness of the language mograms and thus can be checked at compile-time. In principle, a mogram’s concrete representation (e.g. a piece of text or a graphical form) is processed to produce the mogram’s abstract form. Static semantic analysis is performed at the end of this process to check the well-formedness (including valid binding and typing) of the mogram.
2.1.4 Domain-Driven Design
The general goal of domain-driven design (DDD) [22, 75] is to develop software iteratively around a realistic model of the application domain, which both thoroughly captures the domain requirements and is technically feasible for implementation. According to Evans [22], object- oriented programming languages (OOPLs), such as Java [3, 28], are a natural fit for use with DDD. This is not surprising, given that Booch [8] had ealier pointed out two main reasons why OOPL would result in domain models that are inherently expressive and feasible. First, object naturally represents the (abstract) entities that exist in real-world domains. Second, the construct of object used in OOPL is also a basic construct of high-level analysis and design modelling languages that are used to conceptualise and analyse the domain.
In this dissertation, we use DDD to refer specifically to object-oriented DDD. Domain modelling is concerned with building a domain model for each subject area of interest of a domain. DDD considers domain model to be the core (or “heart” [22]) of software, which
22
is where the complexity lies. DDD has two key tenets [22, 75]: (1 - feasibility) a domain model is the code and vice versa, and (2 - satisfiability) the domain model satisfies the domain requirements that are captured in a shared language, called the ubiquitous language. This language is developed by both the domain experts and the technical members of the project team, in an iterative and agile process of investigating and analysing the domain requirements. In our view, these tenets are the motivation behind the main research thread in DDD that had led to the development of contemporary object-oriented DDD software frameworks (e.g. Apache-ISIS [17] (successor of Naked Objects [62]) and OpenXava [60]). The modelling languages of these works are constructed from some annotation-based extensions of OOPL.
DDD Patterns
The DDD method [22, 52] provides a set of eight design patterns that address two main problem types: (i) constructing the domain model (5 patterns) and (ii) managing the life cycle of domain objects (3 patterns). The five patterns of the first problem type include four patterns originally proposed by Evans [22] and one emerging pattern (named domain events) reported by Millet and Tune [52]. The four original patterns are: entities, value objects, services (a.k.a domain services [52]) and modules. The three patterns of the second problem type are: aggregates, factories and repositories. We argue that, unlike the pattern aggregates, the two patterns factories and repositories are strictly not specific to domain modelling. They are adaptations of well-known generic technical solutions that help improve the design quality of a software model. For these reasons, in this dissertation, the term “DDD patterns” will exclude the two patterns factories and repositories.
entities. This pattern discusses how the concept of entity, which originates from concep- tual modelling [34], should be treated with special care in DDD. The key design consideration is that entity is an object defined fundamentally by its identity. This identity, which is typi- cally represented by an identity attribute, gives the entity a “thread of continuity” thoughout its life time. Each entity has a unique identity value, which typically does not change throughout its life time. Other types of attributes, associations and other features that are associated with an entity are defined based on the identity.
For example, the 12 domain classes of the CourseMan domain model in Figure 1.1 are entity types. A domain object of each class is an entity. Although the designs of these classes are incomplete, each class is defined with an identity attribute. All but the
23
two classes CourseModule and ElectiveModule are defined with an identity attribute named id. CourseModule’s identity attribute is named code, which is inherited down to ElectiveModule.
value objects. This pattern discusses a special type of object called value object that “represents a descriptive aspect of the domain that has no conceptual identity” [22]. What value object describes (its value) is more important than its identity. An example given in [22] is the Color object provided by Java. Each object has a distinct colour value that describes a specific colour.
We argue, based on this and other similar examples in [22], that it would be better (for domain modelling purposes) to treat value object as a special type of entity that has an identifier, but this identifier is the only attribute of interest. The identifier values carry domain-specific information that are significant for a particular modelling purpose. We are not concerned with the associations that value object has with other entities, regardless of the fact that these associations typically exist in the domain model. Understanding value object this way helps easily relate the two patterns.
For example, in the CourseMan’s domain model of Figure 1.1 there are two types of value objects. Both are modelled in UML as enumeration types. The first type is named PaymentStatus, which describes a fixed set of distinct status values for the Payment transaction. Two typical payment status values are approved and rejected. The second type is AuthorzStatus, which describes a fixed set of distinct status values for Authorisation of enrolment. Similar to Payment, the typical authorisation status values are also approved and rejected.
services (a.k.a domain services [52]). This pattern describes system behaviours that do not fit the responsibility of entity. These behaviours operate on entities but typically do not need to maintain state information like entities. Therefore, these behaviours are defined in a special concept named services. Evans [22] notes that services actually exist not only in the domain model but in other parts of the software. For example, there would be infratructure services responsible for providing such low-level, shared behaviours as networking and data communication. There are also application services responsible for coordinating behaviours of domain objects from different domain classes. The distinction between this type of service and domain service is very subtle, because both service types involve coordinating the domain objects in some fashion. Basically, Evans states that if a service’s coordination logic is domain-specific then it is a domain service; otherwise it is an application service.
24
In the CourseMan’s domain model of Figure 1.1, for example, class EnrolmentMgmt It performs a domain-specific, activity-based logic which requires
is a type of service. coordinating the behaviours defined by other domain classes in the model.
domain events. This pattern describes when and how domain-specific events are mod- elled in the domain model. A domain event is an important occurrence that typically involves performing some domain logic over two or more entities (such as that performed by ser- vices). Our view is that, regarding to domain service design, services is the core pattern and domain events enhances this core behaviour. In an event, one (publisher) entity announces the event and other (subscriber) entities, who are interested in the event, are informed of the event and, in response, carry out the relevant pieces of the domain logic. The invocation of this logic can be carried out either synchronously or asynchronously (via messages). We argue that domain event may not be needed in the former case, because it simply provides an optional layer of indirection to services (at the cost of additional code). In the latter case, domain event is necessary because the publisher must not know the subscriber(s) directly. There are two main design solutions for domain events: (i) rely on the language support for events (e.g. C#’s event) and (ii) define a separate event management model that provides the publish and subscribe interface operations for entities to use. The latter solution is more generic as it can be applied regardless of the implementation language feature support.
To illustrate domain events, let us consider an event that occurs when a particular Enrolment has a “Fail” finalGrade, which means the concerned Student has failed a CourseModule. In this case, Enrolment is the publisher and EnrolmentMgmt would be a suitable subscriber of the event. The latter is because EnrolmentMgmt, as explained in the services pattern, performs the domain service logic concerning the enrolment matters.
modules. This pattern describes how the traditional concept of module in program- ming [51] is applied to the domain model. Evans [22] defines module as a sub-structure of the domain model that “brings together elements of the model with particularly rich concep- tual relationships”. If the modules of a domain model are designed with high cohesion and low coupling then the domain model can scale to handle more complex domain requirements. Evans generally suggests to use package to define modules, but allows the designer to have the flexibility of deciding what to place in each package.
For example, we would place each domain class of the CourseMan’s domain model in Figure 1.1 into its own module. The auxiliary domain classes of a domain class (e.g. PaymentStatus is auxiliary to Payment) are placed in the domain class’s module.
25
aggregates. This pattern describes a stronger logical object grouping than module in that the object group is treated as a single unit. In an aggregate, there is a root entity that acts as the access point for other objects that are internal to the aggregate. Strong dependency associations exist between the root and the internal objects, so that outside objects only need to rely on the root to obtain information about the aggregate. Outside objects may only hold transient references to internal objects (obtained from the root). These references are used only within an operation. In addition to achieving enhanced modularity, aggregates helps enforce model integrity on the object group of the aggregate.
For example, in the domain model of the CourseMan software, if we suppose that all the SClassRegistrations do not make sense outside the context of their SClasses then we could form an aggregate consisting of these two domain classes. SClass is the root entity, while SClassRegistration is internal to the aggregate.
factories. This pattern is an adaptation of the well-known software design pattern named factory [27]. A factory takes the object creation responsibility burden away from both entities and the client. This helps reduce coupling between these two components, thereby enhancing the modularity of the model.
repositories. This pattern is both an adaption and a generalisation of the object-relational mapping solution [35]. First, it is an adaption in the sense of taking the object-relational mapping and applying it to the domain model. In particular, it handles how an entity is stored in an underlying database and how to manage access to this database. Second, the pattern generalises the mapping in that it defines an abstraction layer on top of the underlying database and a set of generic operations for querying the entities. The abstraction takes the form of a repository – a space where the entities “live” and can be searched for.
DDD with DSL
The idea of combining DDD and DSL to raise the level of abstraction of the target code model has been advocated in [25] by both the DDD’s author and others. However, [25] does not discuss any specific solutions for the idea. Other works on combining DDD and DSL (e.g. Sculptor [68]) focus only on structural modelling and use an external rather than an internal DSL.
A deeper analysis of the related works concerning DDD and DSL reveals two main reasons why internal DSL is particularly suited for DDD. First, designing the domain model
26
in an internal DSL helps determine the implementation feasibility of the domain model in a target OOPL. An external DSL requires a separate syntax specification and ensuring the correctness of this specification is a non-trivial task. Second, a domain model specified in an internal DSL can be treated as a program in the target OOPL. This allows the development team to leverage the capabilities of the language platform to not only process the model but to develop the software generator. This helps significantly reduce the development effort, compared to using an external DSL.
2.1.5 Model-View-Controller Architecture
To construct software from the domain model requires an architectural model that conforms to the generic layered architecture [22, 75]. A key requirement of such model is that it positions the domain model at the core layer, isolating it from the user interface and other layers. Evans [22] suggests that the Model-View-Controller (MVC) architecture model [41, 70] is one such model. The existing DDD frameworks [17, 60, 62] support this suggestion by employing some form of MVC architecture in their designs.
More generally in practical software development, MVC or its variants are adopted so that the software can have some sort of GUI to assist the development team in constructing it. This GUI is essential to getting the user feedback, because, at least up to recently and due primarily to the human factor of the development process, software construction can not be fully automated [26]. Our position in this dissertation is that the MVC architecture is the backbone of any DDD method that adopts the layered architecture.
Technically, MVC is considered in [11] to be one of several so-called agent-based design architectures. The main benefit of MVC is that it helps make software developed in it inherently modular and thus easier to maintain. Software that are designed in MVC consists of three components: model, view and controller. The internal design of each of the three components is maintained independently with minimum impact on the other two components. Modularity can further be enhanced by applying the architecture at the module level. An example of this design is an agent-based design architecture named PAC [15]. This design creates a hierarchical design architecture, in which a software is composed from a hierarchy of software modules. A software module (called PAC object in [15] and agent in [11]) realises a coherent subset of the software functions in terms of the architectural components.
27
Figure 2.3: A UI class of the domain class Student (Source: [45]).
Conceptually, in a software designed with MVC and the DDD method, the model com- ponent is the domain model. It includes a set of domain classes that capture data about the entities of interest in the application domain. For example, the CourseMan domain model in Figure 1.1 includes 11 domain classes (ex- cluding EnrolmentMgmt) that represent 11 entities of interest. The view component of a software is a set of user interface (UI) classes that are used to present the domain classes. Each class presents to the user a coherent view of a domain class and to make it easy for her to interact with this view. For instance, Fig- ure 2.3 shows an example of a UI class for capturing data about Student objects. For each UI class, there is a controller class re- sponsible for selecting (and causing the display of) the user interface and for handling the events that are caused by user actions performed on it. When an event occurs, the controller maps it to suitable state change operation(s), such as create and update, and invokes these to yield result. For example, if the user action is to create an object (e.g. the action induced by clicking the button labelled Create in Figure 2.3) then the controller would map it to an object instantiation operation of the concerned domain class and invoke this operation to create the object. The arguments of this invocation, if any, are the data that the user entered on the user interface. In Figure 2.3, for example, data include the values “Le Van Sau”, “1/1/1990”, “Ho Chi Minh”, “sau@gmail.com”, and “1c13” that the user input in the data fields of the UI class of Student. When the state of a domain object is changed, a change notification is sent to the corresponding UI class to request it to update the display. This class can query the model for details of this change before making the update.
2.1.6 Comparing and Integrating MDSE with DDD
Understanding the comparison between MDSE and DDD helps determine the most suitable strategy for integrating the two methods. In principle, Brambilla et al. [9] suggest that MDSE
28
complements DDD by providing techniques (e.g. domain modelling and DSL engineering) which can help the development team benefit more from the domain model. They state that DDD and MDSE has two main similarities. First, both enforce the use of model in developing software. Second, both methods support models at different levels of abstraction (e.g. platform-independent and platform-dependent).
However DDD differs from MDSE in three aspects. First, DDD follows a more agile approach to domain modelling, particularly that which relies on modern advance in OOPLs. Second, while DDD focuses primarily on the design and implementation phases, MDSE’s scope is wider and covers the entire development process. Third, although DDD acknowledges the role of model engineering, it also highlights the importance of a ubiquitous language that is used by all the human actors in the process.
2.1.7 A Core Meta-Model of Object-Oriented Programming Language
It is clear that a DDD method for object-oriented software needs to use an object-oriented programming language (OOPL) as the target language for implementation. In his book [22], Evans uses Java [3, 28] to demonstrate the DDD method. We argue that because Java and another, also very popular, OOPL named C# [33] share the core features, we will generalise these features to form what we term a “generalised” OOPL. To ease notation, we will refer to this language simply as OOPL. We take the Kleppe’s view (see Section 2.1.3) that meta- modelling is applicable to any software language and apply it to review the OOPL’s ASM. In particular, we will focus on discussing the annotation feature. The concrete syntax and semantics of Java and C# are described in [28] and [33] (resp.).
Abstract Syntax
Figure 2.4 shows a UML-based ASM of OOPL. This ASM includes the core meta-concepts that are supported by Java and C#. It excludes the meta-concepts that describe the struc- ture of the method body. Our scope of interest is on the class structure, not the code. Note, in particular, the following three design features of the OOPL ASM shown in the figure. First, meta-concept Class represents both class and interface (an interface is a class that has no fields). Second, meta-concept AnnotatedElement is modelled as super- type of four non-annotation meta-concepts: Class, Field, Method and Parameter. The association between AnnotatedElement and Annotation helps capture a general rule that
29
Annotation can be attached to any of the non-annotation meta-concept. Third, meta-concept Generalisation, which is adapted from UML/OCL (discussed in Section 2.1.3), captures the subclass-superclass relationship between classes. Basically, a class may consist of one or more generalisations, each of which must be related to exactly one superclass.
Figure 2.4: The UML-based ASM of OOPL.
Definition 2.2. An OOPL model (or model for short) is a structure that conforms to (or is an instance of) the OOPL’s meta-model. Denote by e : T a model element (or instance) e of some meta-concept T .
For example, a Java model for expressing a domain sub-model of CourseMan (discussed in Section 1.1.1) would include the following three Classes: Student, CourseModule and Enrolment. These classes are instances of the meta-concept Class of Java.
Annotation
Because Annotation plays a key role in the construction of aDSL (discussed later in Sec- tion 2.1.8), we devote this section to discussing this meta-concept in detail. Annotation borrows its name from Java [3, 28]. The similar meta-concept in C# is called attribute [33]. Although annotation is syntactically defined as a Java interface it actually behaves like a class. This same view is also held for C#’s attribute. In this dissertation, we will promote Annotation to be a generic meta-concept that is applicable to both Java and C#. The reason that we choose the Java’s term will become clear shortly below.
30
Definition 2.3. Annotation (short for annotation type) is a meta-concept behaviourally equivalent to Class, that is designed for the purpose of being applied to other meta-concepts to present information about them in a uniform and structured fashion. The annotation instances are created at run-time for each model element to whose meta-concept the annotation is applied.
The application of annotation is intuitively called annotation attachment. An annotation A may be attached to more than one non-annotation meta-concepts T = {T1, ..., Tn}. We write this as AT .
When the context either does not require to identify or is clear as to what T in AT is, we
will omit it and simply write AT as A.
Example 2.2. To model that a domain class, such as Student, requires another resource to perform its behaviour, we would attach to it an annotation named Resource. For the sake of the example, we will borrow this annotation from the Java’s built-in annotation of the same name (javax.annotation.Resource). This annotation defines a reference to the target (actual) resource type. In fact, the annotation is attachable also to Field and Method. So we write: Resource{Class, Field, Method}.
An annotation consists of properties. A property is called an annotation element in Java
and a parameter in C#.
Definition 2.4. An annotation property is characterised by name, data type, and default value. Data type is one of the followings: primitive type, string, enum, class, annotation, an array of one of the previous types. We call a property an annotation-typed property if its data type is defined from annotation (i.e. is an annotation or an array thereof).
Notationwise, we use the dot notation to write annotation property; e.g. A.p denotes
property p of an annotation A.
An important note about Definition 2.4 is that the notion of annotation-typed property does not directly exist in C#. This is because in C# an annotation property cannot take an annotation as its data type. Fortunately, this shortcoming can be overcome by a simple transformation that involves “promoting” an annotation-typed property to an annotation and attaching this directly to the target meta-concept. We explain this transformation in detail in paper 4, which is listed in the Publications section. In this dissertation, we will use annotation
31
property as presented in Definition 2.4, because this definition helps bring a modular structure to annotation.
Example 2.3. To specify the name of the resource that the domain class Student (discussed in Example 2.2) requires, we use the property Resource.name. The data type of this property is String and its default value is the empty string “”.
It follows from Definition 2.4 that there exists a reference relationship between the anno- tations. We say that an annotation A directly references an annotation B if there exists one annotation-typed property of A such that the data type of this property is defined from B. Further, we say that annotation A indirectly references annotation B if there exists another annotation C such that: A directly or indirectly references C and C directly references B. In both cases, A is the referencing annotation (of B) and B is the referenced annotation (by A). The next definition makes clear the meaning of annotation instance and its connection to
the assignment of annotation to non-annotation element.
Definition 2.5. Given a model M and an annotation AT , an annotation element a of A in M is an instance of A that is assigned to an element e : Ti ∈ M (for some Ti ∈ T ). We say that a is created by assigning ATi to e, and write ATi(e) = a. Conversely, we say that the model element e is assigned with an element of A, or e is a target element of A.
When we are only interested in whether or not A(e) is defined, we write def(A(e)) and
undef(A(e)), respectively.
@Resource ( name = " language " ) public class Student {}
Example 2.4. Continuing on from the previous examples, assigning Resource to Student results in the annotation element Resource(Student) being created. Assuming that all CourseMan’s domain classes need to know the user-interaction language, then the annotation element has the property name set to “language”. In Java, we write the assignment as follows:
Mapping OOPL to UML/OCL
We conclude our review of OOPL with a brief discussion of the mapping between this language and UML/OCL. We call this mapping meta-mapping, because it maps the ASMs of the two languages. In practice, this mapping is essential for transforming a UML/OCL design
32
Table 2.1: Meta-mapping between OOPL and UML/OCL
Map#
OOPL meta-concepts
UML/OCL meta-concepts
Class
Class
M1
Attribute
Field
M2
Association End
M3
Association
Field (pair of ) Field
M4
Generalisation
Generalisation
M5
Operation
Method
M6
Parameter
Parameter
M7
into the code model of a target OOPL (e.g. Java and C#). We present the mapping in Table 2.1, which we adapted from [1, 31]. In essence, the mapping consists in a set of correspondences between the meta-concepts of the two ASMs. Each table row describes a correspondence between a pair of meta-concepts. To different between meta-concepts in the same pair (which may have the same name), we write them in the table using different font styles. The DCSL’s meta-concepts are written using fixed font. For example, meta-concept Class of DCSL is mapped to the meta-concept Class of UML/OCL.
2.1.8 Using Annotation in MBSD
After more than a decade since (annotation-supported) OOPL was introduced, three noticable methodological developments concerning the use of annotation in MBSD began to form. The first development concerns the use of annotation in programming. It occured very early on and results in a programming paradigm called attribute-oriented programming (AtOP). Another early methodological development, which also concerns code model design, revolves round behaviour interface specification language (BISL). The third and more recent development concerns the use of annotation to define annotation-based DSLs, which are internal to the host OOPL.
Attribute-Oriented Programming
In principle, AtOP [4, 12, 13, 72] extends a conventional program with a set of attributes, which capture application- or domain-specific semantics [13], [12]. These attributes are
33
represented in OOPL as annotations. It is shown in [72], with empirical evidence and based on an observation, that programmers’ mental models do overlap and that the practice of recording the programmer’s intention of the program elements using annotations is rather natural. Further, the use of purposeful annotations in programs helps not only increase program correctness and readability [72] but raise its level of abstraction [4].
MDSE with AtOP. Because of the ability to add attributes to the code model, AtOP has been found to help provide a bridge for the abstraction gap (discussed in Section 2.1.1) between OOPL-based PSM and PIM in MDSE. A conventional OOPL-based code model (i.e. a model constructed only from the built-in OOPL meta-concepts) lacks the necessary elements required to express the domain-specific design rules. AtOP can overcome this by allowing domain-specific concepts to be represented directly in the program.
A representative development model for MDSE/AtOP is reported in the development of a model-driven development framework, called mTurnpike [76]. This framework combines AtOP with model-driven development in a top-down fashion, with an aim to define domain- specific concepts at both the modelling and programming levels. More recently, a bottom-up MDSE approach is proposed in [4], which entails a formalism and a general method for defining annotation-based embedded models.
Behaviour Interface Specification Language
BISL [5, 32, 47, 69, 71] is a class of languages for specifying software behaviour. Of particular interest to this dissertation are BISLs that (i) express functional behaviour properties for object oriented source code and (ii) use some form of annotation to structure the specification. These BISLs are concerned with defining a specification structure for the code model elements (e.g. a Class or a Method) that can be used to capture the domain-specific requirements concerning those elements. At the unit level, one specifies the behaviour for either a Class or a Method. A behaviour specification includes two parts: interface definition and behaviour description. The former consists in the information needed by other software units. The latter specifies one or more state transformations that result from executing the behaviour.
The supported behaviour properties are typically concerned with the transformation from the pre-condition state to the post-condition state of a method and the consistency criteria (invariant) of class. There are two popular BISLs supporting these properties that are associated with the two OOPLs Java and C# (resp.): Java Modelling Language (JML) [47]
34
and Spec# [5]. Both JML and Spec# use annotation to structure the specification. However, these BISLs are general-purpose languages and, as such, do not define rules specifically for constructing domain models in a target OOPL.
Annotation-Based DSL
An important problem in DSL engineering is to enable the domain experts and the technical team to focus on building the domain model, not having to worry about the technical details of the language design itself. A type of internal DSL, called annotation-based DSL, presents a solution to this problem. Annotation-Based DSL (aDSL) [54] is an application of the annotation feature of modern OOPLs in DSL engineering. The name “annotation-based DSL” has been coined and studied only recently by Nosal et al. [54]. A few years earlier, however, Fowler and White [25] had classified this type of language as “fragmentary, internal DSL”. Nosal et al. defined annotation-based DSL based on three types of its composition. The first type is language unification, in which annotation in the host language is used to define the domain concepts. The annotation attachments help ‘unify’ the domain with the host language. The second type is language referencing by extension, in which annotation in the host language defines references to the concepts in another language. These references effectively extend the host language with new concepts. The third type is language extension, in which annotation in the host language defines new concepts, but these concepts do not exist independently from the host.
However, Nosal et al. only provide a general framework and do not provide technical insights for how to construct aDSL. In particular, they do not discuss how meta-modelling (such as using UML/OCL) is used to define the language syntax. Further, questions can be raised about the extent to which the aDSL’s syntax matches with the abstraction level required by the domain that it expresses. If the aDSL’s syntax is of the host OOPL then it inherits the abstraction gap problem, which was identified earlier by Schmidt [67] (see Section 2.1.1). Thus, more research is needed to determine the suitable abstraction levels for aDSL.
2.2 Domain-Driven Software Development with aDSL
The core idea of DDD is domain modelling for software development. Recently, we observe, based on our detailed analysis of the foundational works [22, 62] and the state-of-the-art
35
DDD frameworks [17, 60], that a current trend in DDD is to utilise the domain model for software construction. Given a domain model, other parts of software, including graphical user interface (GUI), are constructed directly from it. Further, this construction is automated to a certain extent.
2.2.1 DDD with aDSL
In DDD, a form of annotation-based language extension of OOPL, has been used to develop the software frameworks (ApacheIsis [17, 62] and OpenXava [60]). The design rules in a domain model are expressed by a set of annotations. These frameworks support the development of a software from its domain model. We observe that aDSL is suited for DDD because it is a type of internal DSL that has the characteristics described earlier in Section 2.1.4 of a DSL for DDD. Another reason is because the practice of using annotations has been around for quite some time, especially in AtOP, and proved useful.
However, the exiting DDD works mentioned above have several limitations. First, they do not formalise their extensions into a language. Second, their extensions, though include many annotations, do not identify those that express the minimal (absolutely essential) annotations. Third, they do not investigate what DSLs are needed to build a complete software model and how to engineer such DSLs.
2.2.2 Behavioural Modelling with UML Activity Diagram
In his book [22], Evans does not explicitly consider behavioural modelling as part of DDD. This shortcoming remains, inspite of the fact that the method considers object behaviour as an essential part of the domain model and that UML interaction diagrams would be used to model this behaviour. For example, in Chapter 2 of the book, when discussing the use of documents and diagrams (i.e. models) in the ubiquitous language, Evans states the followings:
– “the attributes and relationships are only half the story of an object model. But the behavior of those objects and the constraints on them are not so easily illustrated. Object interaction diagrams can illustrate some tricky hotspots in the design...”
– “Behavioral responsibilities of an object can be hinted at through operations names,
and implicitly demonstrated with object interaction (or sequence) diagrams.”
36
In UML [57] (§13.2.1), interaction diagrams (such as sequence diagram) are only one of three main diagram types that are used to model the system behaviour. The other two types are state machine (§14) and activity diagram (§15, 16). Although in the book, Evans only uses sequence diagram as an example, in the ApacheIsIs framework [17] that directly implements the DDD’s philosophy, a simple action language is used to model the object behaviour. This language is arguably a specific implementation of the action sub-language (§16) of UML activity diagram. It leverages the annotation construct of OOPL (see Section 2.1.7) to specify a class operation with a pre-defined behaviour type.
More generally in practice, UML activity diagram has been argued to be suitable for domain experts to use [20]. Further, we observe that it is tightly linked to the other two UML behavioural diagrams. In principle, UML activity diagram and state machine represent two sides of the same coin, while the UML activity’s action language [57] forms a basis in interaction diagram.
For these reasons, we will focus in this dissertation on the use of UML activity diagram for behavioural modelling. To standardise the language terminology used throughout the dissertation, we will call this the (UML) activity modelling language. In the remainder of this section, we will present a brief technical review of this language. We apply the meta- modelling approach with UML/OCL (see Section 2.1.3) to define an essential ASM of the activity modelling language. The ASM, shown in Figure 2.5, is essential in the sense that it contains the core meta-concepts of the language.
As shown in the figure, Activity itself is a sub-type of Behaviour, which, according to §13.2.2 of the UML specification, is a sub-type of Class. These mean two things: (i) activity is a type of behaviour (and thus can be used to model system behaviour) and (ii) we can model activities directly as classes in the domain model. Structurally, an Activity consists of an activity graph that is made up of ActivityNodes and ActivityEdges. These compositions are displayed in the shaded rectangle that lies at the heart of the ASM. ActivityEdge is a binary directed edge, that consists of a source and a target ActivityNode. ActivityNode and ActivityEdge are specialised into various subtypes and descendant types that together give a complete meaning to the activity graph.
Meta-concept ActivityEdge defines either data or control flows and, thus, consists of two sub-types: ObjectFlow and ControlFlow (resp.). ObjectFlow (ControlFlow) models the flow of data (control resp.) tokens that pass through an edge as the result of the execution of the nodes connected to the edge. The tokens are not explicitly modelled. To regulate the
37
Figure 2.5: The meta-model of UML activity modelling language (Adapted from §15.2.2 of the UML specification [57]).
token flow, an ActivityEdge can be associated with one guard and one weight condition. Both conditions are modelled by the meta-concept named ValueSpecification. A guard condition is used to filter tokens that are offered to an ActivityEdge (by the source node), while a weight condition sets the minimum number of tokens that can pass through an ActivityEdge at a time.
The ActivityNode’s type hierarchy defines various node types that are connected to the above two activity flow types. A sub-type of ActivityNode called ObjectNode is exclusively connected to ObjectFlow. Connected to ControlFlow and ObjectFlow are ExecutableNode, ControlNode and six sub-types of ControlNode. These sub-types are: InitialNode, FinalNode, ForkNode, JoinNode, MergeNode and DecisionNode. As of this writing, Action (§16 [57]) is the only concrete sub-type of ExecutableNode.
Example 2.5. In order to illustrate the activity modelling language and to understand its graphical notation (defined in the UML specification), let us consider an example in which we use this language to model the enrolment management activity of CourseMan. We deliberately left out the details of this activity from the description in Section 1.1.1, so that we can discuss different modelling scenarios for it here.
Figure 2.6 shows the activity models of five basic variants of the enrolment management activity. These models demonstrate five fundamental activity flows of the activity modelling
38
Figure 2.6: The UML activity models of five basic variants of the CourseMan’s enrolment management activity.
language. Navigating from left to right and top to bottom, the first scenario results in what we term a sequential activity model, which demonstrates the sequential activity flow. This model consists in two Actions that are performed in sequence. The first action is “Register a student” and the second is “Register student into classes”. There is an ObjectFlow (represented in the figure as an arrowed line) that connects the first to the second action. This flow carries a Student object, which is created as the result of the first action, through to the second action. The second scenario results in a decisional activity model, which demonstrates the activity flow of the DecisionNode. This node is represented by a diamond and has one incoming edge and two or more outgoing edges. The outgoing edges represent the alternative decision outcomes. The decision input, if any, is represented by a note box connected to the decision node by a dashed, gray line. Compared to the sequential model example, the decisional activity model consists of an additional Action, named “Handle help request”, which together with the action “Register student into classes” are two alternative outcome actions. The
39
decision input is attribute Student.helpRequested, whose value is used by the decision node to determine if the registering Student is requesting help from the enrolment officer. If help was requested then control flows through the left outgoing edge to “Handle help request”; otherwise it flows through the right edge to “Register student into classes”.
The third scenario results in a forked activity model, which demonstrates the activity flow of the ForkNode. This node is represented in the model by a line segment with parallel, orthogonal branches, representing the incoming and outgoing edges from and to the surrounding nodes. A fork node has one incoming edge and two or more outgoing edges. In the example model, after performing “Register a student”, control flows into the fork node and exits out below this node, branching into two other Actions: (i) “Make payment” and (ii) “Authorise registration”. The first action involves requesting the registering Student to make Payment, the second action involves an enrolment officer performing Authorisation’s routine against the Student’s registration.
The fourth scenario results in a joined activity model, which demonstrates the activity flow of the JoinNode. In the model, this node has a similar representation to the fork node, but an opposite arrangement of the incoming and outgoing edges. Specifically, it has one outgoing edge and one or more incoming edges. In the example model, the join node joins two Actions (“Make payment” and “Authorise registration”) before passing control to action “Approve enrolment”. This action decides whether to accept or reject the enrolment.
The fifth and final scenario results in a merged activity model, which demonstrates the activity flow of the MergeNode. In the model, this node has a similar diamond-representation to the decision node, but an opposite arrangement of the incoming and outgoing edges from and to the surrounding nodes. Specifically, it has two or more incoming edges and one outgoing edge. In the example model, the merge node merges the action “Register student into classes” with the action “Attend orientation” such that they both end in an action named “Conclude enrolment”. Here, “Attend orientation” means to attend an orientation program for new students.
2.2.3 Software Module Design
Traditionally, in object oriented software design [48, 49, 51], it is well understood that large and complex software requires a modular structure. According to Meyer [51], software module is a self-contained decomposition unit of a software. Meyer suggested that, in an
40
OOPL, module be represented by class.
For large and complex software that is developed using the DDD method, the domain model needs to be designed in such a way that can easily cope with the growth in size and complexity. After all, tackling domain modelling complexity is the main objective of DDD. As discussed in Section 2.1.4, Evans [22] proposed using the pattern modules to In this section, we use the term “domain module” group closely-related domain classes. instead of Evan’s module in order to make a distinction with “software module”. In object oriented design language terminology [57], a domain module is a package. According to the general software design wisdom [48, 49], a domain model should have the quality of high cohesion and low coupling. To the best of our knowledge, although the existing works in DDD [17, 22, 60, 62, 75] support domain module, they do not address how to use it to form software module. Further, they do not consider modules as first-class objects and, thus, lack a method for their development. Not only that, they do not precisely characterise the software that is developed from the domain model. These shortcomings would surely hinder DDD adopters in their efforts to apply the method in practice.
From the OOPL’s perspective, a recent development in Java 9 [29] introduces a module- based design for Java software. A Java software module is more than a class or a package. It is a named, configurable group of one or more related packages. The primary aim is to provide stronger code encapsulation [37, 61] that would help ease the construction of large software. More specifically, instead of the usual keyword class that is used to define data types, Java module configuration is defined with the keyword module and is written in a special Java file. Each configurable element is written in a code statement of the module’s body. However, Java software module has a number of limitations. First, it only supports module configuration and not the module concept. Second, it does not provide a mechanism for defining a domain-specific module structure. Third, module configuration requires a different syntax from the one used to write standard Java programs. This increases learning and requires additional tool support. Fourth, the module syntax is not easily extendable.
2.2.4 Module-Based Software Architecture
In this dissertation, we adopted a module-based software architecture (MOSA), which we developed in a previous work [45], for software development in DDD. We chose MOSA because it was developed based on the MVC architecture and specifically for domain-driven
41
software development. MOSA is inherently module-based. In this section, we will review the key concepts of MOSA and illustrate them using CourseMan.
MOSA realises the DDD’s layered architecture (discussed in Section 2.1.5). It positions the domain model at the core and (currently) incorporates the UI concern into a layer around this core. A software module in MOSA forms a micro, functional software. The modules can be combined to form a complete software. MOSA is built upon two key concepts: MVC-based module class and module containment tree.
Definition 2.6. Module class is a structured class [57] that describes the structure of modules in terms of three MVC components: model (a domain class), a view class and a controller class. Given a domain class C, the view and controller classes are the parameterised classes ViewhT → C i and ControllerhT → C i (resp.); where ViewhT i and ControllerhT i are two library template classes, T is the template parameter.
To ease discussion, we name a module class after its domain class, using the prefix “Module”; e.g. ModuleStudent is a module class created from Student. Further, we use the notation ViewhC i to denote the view of a ModuleC.
Now, every module class has a state scope, which is a sub-set of the attributes of the domain class that are relevant to the module. Relevancy is determined based on the module’s specification. Module classes in a MOSA model are associated by virtue of the fact that their domain classes are associated in the domain model. These associations form the basis for module containment and containment tree. Module containment is a relation on the set of modules. Containment tree is a rooted tree that results from combining the module containments of a composite module.
Definition 2.7. Given two domain classes C and D, a module M = ModuleC (called com- posite module) contains another module N = ModuleD (called child module), if
– C participates in a binary association (denoted by A) with D.
– C is at the one end (if A is one-many), at the mandatory one end (if A is one-one) or
at either end (if otherwise).
– Exists a subset of N ’s state scope, called containment scope, that satisfies M ’s
specification.
42
Definition 2.8. Containment tree is a rooted tree that has the following structure:
– Root node is a composite module (called the root module). Other nodes are descendant
modules that are contained directly or indirectly in the root module.
– Tree edge from a parent node to a child node represents a module containment.
Example 2.6. The bottom part of Figure 2.7 shows a more detailed sub-model of the Course- Man’s domain model presented in Figure 1.1. This sub-model, which is created in the package courseman.model, consists of five classes and three new associations. For brevity, we ex- clude attributes and operations from the class boxes. The first two associations associate EnrolmentMgmt to Student and SClass, the third associates Student to HelpRequest.
Figure 2.7: The MOSA model of CourseMan.
The entire Figure 2.7 is a MOSA model of CourseMan. It is drawn using the graphical notation described in [45]. A binding is depicted by a dashed line, whose Controller’s end is drawn with the symbol ‘(cid:13)’. The model consists of four module classes. Among these, ModuleEnrolmentMgmt is a composite module, whose containment tree first contains a child module ModuleStudent (because of the one-many association from EnrolmentMgmt to Student). This child module would in turn be the parent of a ModuleCourseModule if Student is preferred to CourseModule over the many-many association between them.
The state scope of ModuleStudent includes two attributes Student.id, name and another attribute, named modules, that realises the Student’s role in the many-many association to CourseModule. The containment scope of ModuleStudent in the containment tree of
43
ModuleEnrolmentMgmt is the same as its state scope. In the containment trees of other modules (e.g. ModuleClass’s), however, ModuleStudent’s state scope may contain only a proper subset of the state scope.
Module Configuration Method
We view module configuration at two levels [45]. At the module level, a configuration specifies the model, view and controller components of the module class. If the module is composite then the configuration also specifies the containment tree. At the component level, the configuration specifies properties of each of the three components.
First, the model configuration specifies properties of the domain class (the model). Second, the view configuration specifies such properties as the view’s layout and the label, style and dimension of view fields. There are two types of view field: subview and data field. A subview is a container containing other view fields. A subview presents the view of a descendant module. A data field, on the other hand, is a non-composite component, which does not contain other view fields. Third, the controller configuration specifies behavioural properties of the controller through a set of basic actions that are performed in response to the user commands. In particular, the controller configuration specifies the default action that is executed when the view is first displayed. Further, it specifies the policy for an open action, which is executed when the user performs the data openning command. This action connects to the object store of the domain class and prepares the view ready for user to start manipulating the stored objects. Other controller actions are also supported.
Example 2.7.
To configure ModuleEnrolmentMgmt of CourseMan, whose view is shown in Fig- ure 2.8, we first need to specify three com- ponents: model := EnrolmentMgmt, view := ViewhEnrolmentMgmti and controller := ControllerhEnrolmentMgmti. In addi- tion, since this module is composite we need to specify a containment tree which details the containment scopes of the modules of the following three domain classes that are Figure 2.8: A ModuleEnrolmentMgmt’s view containing a child ModuleStudent’s view.
44
associated to EnrolmentMgmt: SClass, Student and HelpRequest. As for the three component configurations, the model configuration contains the model property specified above. The view configuration specifies that the overall layout is a tab layout. In addition, it contains labels for the three view fields that render three associative fields that realise EnrolmentMgmt’s ends of the associations to the other three domain classes. The labels are used to name the three tabs shown in the figure. Each view field is a subview that displays the view of one child module. For instance, the subview shown in the figure displays the view of a child module that is typed ModuleStudent. This subview contains four view fields that render four attributes of Student (id, name, helpRequested and modules) that are listed in ModuleStudent’s containment scope. These four view fields are data fields.
The controller configuration in this case does not require any specific customisation.
2.3 Summary
In this chapter, we reviewed the concepts, methods, techniques and tools that are relevant to the research problem of this dissertation. Our exposition helps paint a knowledge map of the relevant and connected works in three main areas of related work: MDSE, DDD and OOPL. We identified aDSL to be the underlying research thread that connects these areas. To understand aDSL, we reviewed it in a broader context of annotation usage in MBSD.
A key observation that we can draw from our review is that there is a need to extend existing OOPLs with more expressive power, with an aim to bridge the conceptual gap with the high-level modelling languages (such as UML/OCL) that are commonly used to express the domain model. Intuitively, this extension makes sense and is necessary if OOPL is to become the preferred executable language of choice for the domain model. A general approach that the state-of-the-art approaches in aDSL takes to address this need is to leverage the annotation meta-concept to define a set of domain-specific annotations and combine these with other non-annotation meta-concepts.
However, we argued that there are still significant open issues in two main problem areas. The first area concerns what an ‘essential’ aDSL is and how it can be used to express both the structural and behavioural aspects of the domain model. The second concerns how to modularly construct the software from the domain model. In particular, how we can also leverage aDSL for this construction. The rest of the dissertation will present our contributions for these two problem areas.
45
Chapter 3
Unified Domain Modelling with aDSL
In this chapter, we describe our first two contributions concerning unified domain (UD) mod- elling. Taking the view that domain class design is the basis for unified domain model (UDM) construction, we first specify a horizontal aDSL, called DCSL, for expressing the essential structural and behavioural features of the domain class. We discuss how DCSL enables an automatic technique for constructing the domain class design specification. We then use DCSL to define UDM. In this, we present a set of generic UD modelling patterns that can be used to construct UDMs for real-world problem domains.
3.1
Introduction
In principle, UDM extends the traditional domain model (proposed by Evans [22]) with elements that capture the state-specific structure of the activity modelling language. It is clear that an aDSL for expressing the UDMs of different real-world domains needs to be a horizontal DSL. Ideally, the underlying modelling patterns that are expressed in this language would cover both structural and behavioural modelling aspects. This is achievable if we learnt from Chapter 2 how UML/OCL was used as a horizontal, high-level meta-modelling language to define the abstract syntaxes of both structural and behavioural modelling languages.
We argue that, at the lowest level of abstraction, the desired aDSL’s scope would reuse all the OOPL’s meta-concepts (see Section 2.1.7) and focus on defining the commonly-used constraints and behaviour types that are often imposed on instances of these meta-concepts in a domain model. For example, a common constraint that is often imposed on a class
46
(e.g. Student) is whether or not it is (i.e. all objects of the class are) mutable. A similar con- straint that is often imposed on a field (e.g. Student.name) is whether or not it is mutable. An example of a behaviour type is setter, which is assigned to a method (e.g. Student.setName) that updates the value of a mutable field using some input argument(s).
There are three main questions facing the design of such aDSL. The first question concerns the constraints and behaviour types that are accepted as being essential. The second concerns the represention of these constraints and behaviour types as meta-concepts in an aDSL. The third question concerns the meta-modelling language used to specify the aDSL.
Existing works in DDD [17, 22, 60] have addressed the second question by using anno- tations to represent constraints and behaviour types. However, they have so far not tackled the first and third questions. In this chapter, we will define a horizontal aDSL, named Do- main Class Specification Language (DCSL), to address all three questions. An added benefit of DCSL is that it enables a techique to automatically generate the complete domain class specification from just the state space specification.
The rest of the chapter is structured as follows. Section 3.2 defines the domain of DCSL. Section 3.3 specifies the abstract syntax of DCSL using UML/OCL. Section 3.4 presents the static semantics of DCSL. Section 3.5 discusses the dynamic semantics of DCSL. Section 3.6 uses DCSL to define UDM and a set of generic UD modelling patterns. Section 3.7 concludes the chapter.
3.2 DCSL Domain
The DCSL’s domain is a horizontal (technical) domain that is described in terms of the OOPL meta-concepts and a number of essential state space constraints and essential behaviours that operate under these constraints.
3.2.1 Essential State Space Constraints
The structural constraint examples listed in Section 1.1.2 are examples of 11 types of con- straints that, in our view, are essential to the conception of domain class. Together, they help practically shape the state space of domain class and, thus, make it suitable for domain modelling real-world software. In the remainder of this dissertation, we will use the term
47
state space constraints to refer to the constraints, and the term domain state space1 (or state space for short) to refer to the state space restricted by them. The state space defines the valid object states at any given point in time.
Table 3.1: The essential state space constraints
Type
Descriptions
Boolean
Whether or not the objects of a class are mutable [48, 49]
OM
its value can be
Boolean
FM
its value needs not be
Boolean
FO
Constraints Object mutability Field mutability Field optionality
the field’s
Field length
Non-Boolean
FL
Whether or not a field is mutable (i.e. changed) [34] Whether or not a field is optional (i.e. initialised when an object is created) [34] The maximum length (if applicable) of a field (i.e. values must not exceed this length) [34]
Boolean
Whether or not the values of a field are unique [34]
FU
Boolean
IF
the field’s values
Non-Boolean
YV
the field’s
Non-Boolean
XV
Field uniqueness Id field Min value of a field Max value of a field
Auto field
Boolean
TF
Whether or not a field is an object id field [34] The min value (if applicable) of a field (i.e. must not be lower than it) [34] The maximum value (if applicable) of a field (i.e. values must not be higher than this) [34] Whether or not the values of a field are automatically generated (by the system) [34]
Non-Boolean
YL
The minimum number of objects to which every object of a class can be linked [57]
Non-Boolean
XL
The maximum number of objects to which every object of a class can be linked [57]
Min number of linked objects Max number of linked objects
Table 3.1 lists the names and natural language descriptions of the constraints, together with reference(s) to the works in which they are discussed or used. For the sake of exposition, we group the constraints into two types: (i) boolean constraint and (ii) non-boolean constraint. The type of each constraint is indicated in the table.
3.2.2 Essential Behaviour Types
1 to differentiate from the term “system state space” used in formal methods.
An essential behaviour type specifies a pattern of behaviour that is essential for each domain class baring the essential state space constraints stated above.
48
Table 3.2: The essential behaviour types
Names
Type names
RequiredConstructor
Required constructor
ObjectFormConstructor
Object form constructor
Descriptions creates a new object whose state is initialised to hold values only for the non-optional fields. This is the absolute minimum constructor behaviour. creates a new object whose state is initialised to hold values for both optional and non-optional fields. This behaviour is needed to handle object-creation requests from the user.
generates a new value for an auto-field.
AutoAttributeValueGen
LinkCountGetter
LinkCountSetter
LinkAdder
LinkAdderNew
Auto-attribute value generator Link count getter Link count setter Link adder Link adder new Link remover
LinkRemover
LinkUpdater
LinkUpdater
Getter Setter
observes the current number of object links that an object has with objects of another class. sets the current number of object links that an object has with objects of another class. adds an object link to an object of another class. adds an object link to a newly-created object of another class. removes an object link to an object of another class. update an object based on changes to a linked object of another class. observes the value of a field. sets the value of a field.
Getter Setter
In order to identify the behaviour types, we analysed the state space constraints in Table 3.1 in the context of these three core operation types [49]: creator, mutator and observer. We then specialised these operation types for the constraints to yield the 11 essential behaviour types listed in Table 3.2. Each behavioural type is characterised by a type name and two essential attributes that are used to specify the pre- and post-conditions of the behaviour.
We say that the behaviour types form the behaviour space of a domain class. This space
concerns with the allowable changes in the object state that occur over time.
3.3 DCSL Syntax
In this section, we specify the syntax of Domain Class Specification Language (DCSL). In our specification, we will focus on the ASM. This ASM includes the core OOPL meta- concepts described in Section 2.1.7 and a number of annotations (called meta-attributes) that express the essential state space constraints and the essential behaviour types that were
49
Figure 3.1: The abstract syntax model of DCSL.
described previously in Section 3.2. The concrete syntax is a subset of that of the host OOPL, which is applied to the meta-concepts in the ASM.
Definition 3.1. A meta-attribute AT is an annotation whose properties structurally describe the non-annotation meta-concepts T to which it is attached.
Figure 3.1 shows an UML/OCL model for the ASM. It consists of five core meta-attributes, one auxiliary annotation and three enums. The five meta-attributes are DClass{Class}, DAttr{Field}, DAssoc{Field}, DOpt{Method} and AttrRef{Method, Parameter}. The auxiliary anno- tation is Associate. The two enums AssocType and AssocEndType specify the association type and end type (resp.). The enum OptType captures the type names of the 11 essential behaviour types.
Graphically, an annotation is represented in the figure by a 2-compartment class box; a property is represented by a class field. The default value of a property (if any) is written within brackets and appears after the property type.
50
The two meta-attributes DClass and DAttr together possess properties that directly model the first nine state space constraints listed in Table 3.1. The other two constraints (YL and XL) are modelled by the third meta-attribute named DAssoc. The remaining two meta-attributes (DOpt and AttrRef) model the essential behaviour of Method.
To model YL and XL, we design DAssoc to capture the association link context within which these two constraints are applied. The base property is DAssoc.associate (type: Associate), which captures the associated class (property Associate.type), together with the range of the number of linked objects of this class. This range is specified by the two properties Associate.cardMin (for YL) and cardMax (for XL).
In addition to these, we also introduce a number of other contextual properties that are required to identify the different associations realised by the same class. These include property DAssoc.ascName, which specifies the association name, property ascType (type: AssocType, specifying three association types: OneOne, OneMany and ManyMany), property role (specifies the role of the link end) and property endType (type: AssocEndType, specifying two link end types: One and Many).
Meta-attribute DOpt in Figure 3.1 is used to specify the method behaviour, while meta- attribute AttrRef is used to specify the reference to a field whose value is manipulated by a method. Property DOpt.type defines the behaviour type, which is taken from the values captured by the enum OptType. Two properties requires and effects express the pre- and post-conditions of a method. The expression language used for these two conditions is OCL and we will explain more about these in Section 3.3.1.
Example 3.1. (CourseMan specification) Listing 3.1 shows a complete DCSL specifi- cation of the class Student of CourseMan, written in Java. Listing 3.2 shows a partial DCSL specification for the domain class Enrolment. This specification omits the behavioural specification. We will use both listings to illustrate DCSL and to explain a graphical notation that we use for its specifications in the remainder of this dissertation.
As shown in Listing 3.1, class Student is specified with DClass.mutable = true, because at least one of its domain fields (name) is mutable. The domain field name is mutable (DAttr.mutable = true), not optional (DAttr.optional = false) and has max length (DAttr.length) = 30. The domain field id is an identifier field (DAttr.id = true), whose value is automatically generated (auto = true). The former also means that id is not optional, while the latter means that this field is immutable. Finally, the domain field enrolments is an associative field. Its DAssoc assignment specifies that the field realises
51
1 @ DClass ( mutable = true ) public class Student {
2
3
/* ** STATE SPACE * */ @ DAttr ( name = " id " , type = Type . Integer , id = true , auto = true , mutable = false ,
optional = false )
4
5
private int id ; @ DAttr ( name = " name " , type = Type . String , mutable = true , optional = false ,
6
length =30)
7
private String name ;
8
9
10
@ DAttr ( name = " enrolments " , type = Type . Collection ) @ DAssoc ( ascName = " std - has - enrols " , role = " std " ,
11
12
ascType = AssocType . One2Many , endType = AssocEndType . One , associate = @Associate ( type = Enrolment . class , cardMin =0 , cardMax =30) )
13
14
15
private Collection < Enrolment > enrolments ; private int enrolmentCount ; private static int idCounter ;
16
17
18
19
20
/* ** BEHAVIOUR SPACE ( partial ) * */ @ DOpt ( type = DOpt . Type . ObjectFormConstructor , requires = " n <> null and n . size () <= 30 " , effects = " self . id = genId ( null ) and self . name = n " )
21
public Student ( @ AttrRef ( " name " ) String n ) ;
22
23
24
// automatically generate the next student id ( if required ) @ DOpt ( type = DOpt . Type . AutoAttributeValueGen ,
25
effects = " if id = null then idCounter = idCounter +1 and result = idCounter " +
26
27
" else if id > idCounter then idCounter = id and result = id " + " else result = id endif endif " )
28
@ AttrRef ( " id " ) private static int genId ( Integer id ) ;
29
30
31
// add links ( this , e ) for all e in enrols @ DOpt ( type = DOpt . Type . LinkAdder ,
32
requires = " enrolmentCount + " +
33
" enrols - > select ( o | enrolments - > excludes ( o ) ) -> size () <= 30 " ,
34
35
effects = " enrolments = enrolments@pre - > asSet () -> union ( enrols - > asSet () ) " + " and enrolmentCount = enr olm entCount @pre + ( enrolments - > size () - " +
36
" enrolments@pre - > size () ) " )
37
38
@ AttrRef ( " enrolments " ) public boolean addEnrol ( Collection < Enrolment > enrols ) ;
39
the one end of a one-many association to the associate class Enrolment (Associate.type = Enrolment). The min and max cardinalities of the Enrolment’s end are 0 and 30 (resp.). Listing 3.1: Specification for the domain class Student in Java
52
40
41
// add link ( this , e ) @ DOpt ( type = DOpt . Type . LinkAdder ,
42
requires = " if enrolments - > excludes ( e ) then enrolmentCount + 1 <= 30 else
true endif " ,
43
effects = " enrolments = enrolments@pre - > asSet () -> union ( Set { e }) and " +
44
" enrolmentCount = enrolmentC ount@pre + ( enrolments - > size () -
enrolment@pre - > size () ) " )
45
46
@ AttrRef ( " enrolments " ) public boolean addEnrol ( Enrolment e ) ;
47
48
49
50
// remove link ( this , e ) for all e in enrols @ DOpt ( type = DOpt . Type . LinkRemover , requires = " enrolmentCount - " +
51
" enrols - > select ( o | enrolments - > includes ( o ) ) -> size () >= 0 " ,
52
53
effects = " enrolments = enrolments@pre - > asSet () - enrols - > asSet () and " + " enrolmentCount = e nrolmentC ount@pre - ( enrolments@pre - > size () - " +
54
" enrolments - > size () ) " )
55
56
@ AttrRef ( " enrolments " ) public boolean removeEnrol ( Collection < Enrolment > enrols )
57
throws C o n s t r a i n t V i o l a t i o n E x c e p t i o n ;
58
59
60
// remove link ( this , e ) @ DOpt ( type = DOpt . Type . LinkRemover ,
61
requires = " if enrolments - > includes ( e ) then enrolmentsCount - 1 >= 0 else
true endif " ,
62
effects = " enrolments = enrolments@pre - > asSet () - Set { e } and " +
63
" enrolmentCount = e nrolm entCount @pre - ( enrolments@pre - > size () - " +
64
" enrolments - > size () ) " )
65
66
@ AttrRef ( " enrolments " ) public boolean removeEnrol ( Enrolment e ) throws
C o n s t r a i n t V i o l a t i o n E x c e p t i o n ;
67
68
69
70
// getter for name @ DOpt ( type = DOpt . Type . Observer , effects = " result = name " ) @ AttrRef ( " name " ) public String getName () ;
71
72
73
74
75
// setter for name @ DOpt ( type = DOpt . Type . Mutator , requires = " n <> null and n . size () <= 30 " , effects = " self . name = n " ) public void setName ( @ AttrRef ( " name " ) String n ) ;
76 }
The required constructor of class Student has DOpt.type = RequiredConstructor and one parameter n, which is assigned with an AttrRef that references the domain field name. This
53
is the only non-collection typed, non-optional domain field of class Student. AttrRef is also assigned to the getter method getName, which has DOpt.type = Getter. This AttrRef specifies that this method is the getter for the field name.
Note that, Listings 3.1 and 3.2 include an extra property DAttr.name, which is added in our implementation of DCSL to specify domain field name. This property adds nothing to DAttr and is merely used as a syntactic convenience for mapping DAttr to an attached field. This helps ease reading and processing the specification.
1 @ DClass ( mutable = true ) 2 public class Enrolment {
3
4
5
/* ** STATE SPACE ( partial ) : other attributes ( omitted ) */ @ DAttr ( name = " student " , type = Type . Domain , optional = false ) @ DAssoc ( ascName = " std - has - enrols " , role = " enrolments " ,
6
7
ascType = AssocType . One2Many , endType = AssocEndType . Many , associate = @Associate ( type = Student . class , cardMin =1 , cardMax =1) )
8
private Student student ;
9
10
11
@ DAttr ( name = " module " , type = Type . Domain , optional = false ) @ DAssoc ( ascName = " mod - has - enrols " , role = " enrolments " ,
12
ascType = AssocType . One2Many , endType = AssocEndType . Many ,
13
associate = @Associate ( type = CourseModule . class , cardMin =1 , cardMax =1) )
14
private CourseModule module ;
15 }
Listing 3.2: A partial state space specification of Enrolment in Java
To ease discussion, we use the graphical notation shown in Figure 3.2 to present a DCSL model. This notation extends the UML’s class diagram notation with a structured text notation. This notation is applicable to DCSL models because there exists a meta-mapping between UML/OCL and OOPL (see Section 2.1.7) and DCSL is derived from OOPL.
Let us briefly describe the notation. First, a non-annotation element is drawn using standard UML class diagram notation. Second, a meta-attribute element is drawn using UML note box. Third, a meta-attribute assignment is represented by a dashed grey line, whose target element end is marked with the attachment symbol ( ). Fourth, the note box content of a meta-attribute element is a structured text segment that has the form: A {props}, where A is the meta-attribute name and props is a property listing. A text entry specifies the initialisation of a property to a value. If this value is another annotation element then this element is written using a nested, borderless note box. The entries are separated by either a next line or a comma (‘,’) character.
54
Figure 3.2: A DCSL model for a part of the CourseMan domain model.
Another feature of the notation is the use of a virtual (dashed) association line to represent a pair of DAssoc elements that help realise the association ends of an association. This association line is more compact and thus helps significantly ease drawing and improves readability of the model. In the text, we will use the term “association” to refer to this association line and the DCSL model elements that realise it.
The DCSL model in Figure 3.2 realises the DCSL specification segment of Course- Man shown in Listings 3.1 and 3.2. This model focuses on two domain classes Student and Enrolment and the association between them (class Enrolment realises the associa- tion class between Student and CourseModule). The association named “std-has-enrols” between Student and Enrolment is represented in the figure by the association line that connects the two classes. The two association ends are realised by two associative fields: Student.enrolments (explained above) and Enrolment.student. The two thick arc arrows
55
in the figure illustrate how the two DAssoc elements of these fields are intuitively “folded into” the association line. The association name is used to label the line and the properties DAssoc.ascName of the two elements. The role label of an association end is used to set the value for the property role of the Associate element of the DAssoc element of the same end. The role label is also used to name the field at the opposite end of the association. The cardinality constraint of an association end is used to determine the suitable values for the two properties ascType and endType of the DAssoc element of the same end. In addition, the constraint is used to set the values of the properties cardMin and cardMax of the Associate element of the DAssoc element of the opposite end.
3.3.1 Expressing the Pre- and Post-conditions of Method
As discussed earlier, we use two properties DOpt.requires and effects to specify the pre- and post-condition of method. The values of these properties are string-representations of OCL expressions. What we are interested in is not the use of general purpose OCL expression but a specific set of essential OCL expressions that are suitable for expressing the behaviour of the different OptTypes.
For example, Listing 3.1 shows how the pre-condition of the required constructor is the OCL expression n <> null and n.size()<= 30, which states that the value for pa- It is required because rameter n is required and does not exceed 30 characters in length. DAttr(Student.name).optional = false. The max length is taken from the value of DAttr(Student.name).length. Recall that field Student.name is mapped to n via the specification of AttrRef. The post-condition of the constructor has the OCL expression self.id = genId(null) and self.name = n, which basically states that Student.name is set to n and Student.id is set to the next value, automatically generated by the helper method genId.
As another example, method genId is typed AutoAttributeValueGen and is linked to id via the specification of AttrRef. The OCL expression in the post-condition of this method states two main cases of the result. The first case is applied when id = null, which occurs when the next value is to be determined automatically. For the genId method, this means automatically incrementing the identifier value by one. This is maintained by the static field Student.idCount.
The second case is applied when id <> null, which occurs when the next value is
56
already determined (e.g. because the object comes from another source, such as an object store), and, thus, we instead need to synchronise the relevant static field(s) to the input value if needs to. For the genId method, this means updating Student.idCount to id if its value is smaller.
3.3.2 Domain Terms
The meta-attributes and their associations to the non-annotation meta-concepts provide basis for the definitions of four domain terms. We propose that these terms be added to the ubiquitous language’s vocabulary. The following definition uses the function def that we defined as part of Definition 2.5.
Definition 3.2. Given a DCSL model M . An element c : Class ∈ M is a domain class if def(DClass(c)). An element f : Field ∈ M is a domain field if def(DAttr(f )). A domain field f ∈ M is an associative field if def(DAssoc(f )). An element m : Method ∈ M is called a domain method if def(DOpt(m)).
Note that the definition of domain method only requires the assignment of DOpt, not AttrRef. We make this annotation optional to help ease the specifications of domain methods, especially when it can be inferred from the class structure which domain field is manipulated by a domain method. For example, one can easily infer the domain field of a setter/getter method.
3.4 Static Semantics of DCSL
In this section, we define a set of rules that precisely describe the state space constraints and the behaviour types that are captured by the DCSL’s meta-attributes. These rules form the core static semantics of DCSL and can be applied at compile-time to identify instances of the domain terms that are present in a DCSL model. For the sake of exposition, we divide the static semantic rules into two groups: state space semantics and behaviour space semantics. The first group defines the static semantics of the state space constraints, the second defines the static semantics of the behaviour types. As will be explained in detail, the behaviour space semantics is defined based on a structural mapping with the state space.
57
3.4.1 State Space Semantics
The state space semantic rules are constraints on the ASM and, thus, we use OCL invariant to precisely define these rules. The benefit of using invariant is that it allows us to specify exactly the structural violation of the constraint, which occurs if and only if the invariant is evaluated to false. The OCL invariant is defined on an OOPL meta-concept and has the following general form:
φ implies E
where:
– E: an OCL expression on the ASM structure that must conditionally be true in order
for the constraint to be satisfied,
– φ: the condition upon which E is evaluated. It is defined based on some characteristic
C of the meta-concept:
if C is in effect true, φ = if C is not in effect. false,
Note that when φ = true then E is evaluated and the result equates the constraint’s
satisfaction. Otherwise, E does not need to be evaluated (can be either true or false).
For the sake of exposition, we divide the OCL constraints into two groups: (i) well- formedness constraints and (ii) state space constraints. State space constraints are themselves divided into boolean and non-boolean constraints, as described earlier in Table 3.1. These constraints are identified with the same name labels as shown in this table. For these constraints, φ = true when the corresponding property of the constraint is given a definite value. The well-formedness constraints are other OCL constraints needed to ensure the overall well-formedness of DCSL models. These constraints are identified with the name label prefix ‘WF’.
The following subsections will explain the OCL definitions of these three types of con- straints. Each constraint includes a header comment that describes, in a semi-structured format, what the constraint means. The helper OCL functions that are used in the constraint statements are defined in Appendix A.
58
Well-formedness Rules
An important well-formedness rule among those listed in Table 3.3 is WF4, which we call generalisation constraint. This constraint, when combined with the relevant generalisation rules enforced by OOPL, help ensure that the state space constraints are preserved through inheritance. More specifically, rule WF4 is applied to all the overridden methods that reference a domain field of an ancestor class in the inheritance hierarchy. Informally, this rule states that each overridden method must be assigned with an DAttr that preserves the DAttr of the referenced domain field. In rule WF4, the condition φ = not(Tk::ancestors (c).oclIsUndefined()) means that the class c is a subclass of some superclass.
Table 3.3: Well-formedness constraints of DCSL
Names
Constraints
1 -- Parameter . ref . value ( if specified ) refers to name of a Field in same
class
2 context p : Parameter inv :
WF1
3
not ( p . ref . oclIsUndefined () ) implies
4
p . owner . owner . fields - > exists ( f | f . name = p . ref . value )
1 -- Method . ref . value ( if specified ) refers to name of a Field in same class 2 context m : Method inv :
3
WF2
not ( m . ref . oclIsUndefined () ) implies
4
m . owner . fields - > exists ( f | f . name = m . ref . name )
1 -- Method . atr is only specified for overridden methods that also have
Method . ref
2 context m : Method inv :
WF3
3
not ( m . atr . oclIsUndefined () ) implies
4
m . isOverriden () and not ( m . ref . oclIsU ndefined () )
1 -- all overridden methods of a subtype that reference a domain field must 2 -- preserve the DAttr of that field 3 context c : Class inv :
4
not ( Tk :: ancestors ( c ) . oclIsU ndefined () ) implies
5
WF4
c . overridenMethods () -> forAll ( p | not ( p . atr . oclIsUndefined () ) implies
6
Tk :: ancestors ( c ) -> exists ( c1 |
7
c1 . fields - > exists ( a | p . isAttrRef ( a ) and p . atr . preserves ( a . atr ) ) )
8
)
59
public class ElectiveModule extends CourseModule {
@ DOpt ( type = DOpt . Type . Getter ) @ AttrRef ( " semester " ) @ DAttr ( type = Type . Integer , optional = false , min =3) @Override public int getSemester () ;
}
For example, the above listing shows how the subclass ElectiveModule is specified with an overridden method named getSemester. This method has two annotations: (i) an AttrRef element that references the domain field semester of the superclass CourseModule and (ii) a DAttr element that preserves the DAttr element of CourseModule.semester. The preservation is guaranteed by the fact that all properties except min have the same values, while the value of property min is 3, which is greater than semester.min = 1.
Boolean State Space Constraints
The boolean state space constraints shown in Table 3.1 include OM, FM, FO, FU, IF and TF. These constraints are expressed by the following Boolean-typed annotation properties in DCSL: DClass.mutable and DAttr.mutable, optional, unique, id, auto. Table 3.4 lists the definitions of the constraints.
Table 3.4: The boolean state space constraints of DCSL
Names
Constraints
1 -- exists a mutable field a of c 2 context c : Class inv Mutable :
OM
3
c . dcl . mutable implies c . fields - > exists ( a | a . atr . mutable )
a V a r A s si g n E x p r e ss i o n for a
1 -- exists a method p of a . owner s . t p ’ s result expression is 2 -- 3 context a : Field inv Mutable :
4
a . atr . mutable implies a . owner . methods - > exists ( p | p . isMutatorRef ( a ) and
FM
5
6
7
let e : OclExpression = p . resultExp in not ( e . oclIsTypeOf ( OclVoid ) ) and e . oclIsTypeOf ( V a r A s s i gn E x p r e s s i on ) and e . oclAsType ( V a r A s s i gn E x p r e s s io n ) . lhs . ref e rre d Var i able = a )
60
1 -- exists a constructor u of a . owner s . t . none of the body expressions of u contains a in the LHS 2 -- 3 context a : Field inv Optional :
4
FO
a . atr . optional implies a . owner . methods - > exists ( u | u . isCreator () and
5
6
u . postExps () -> forAll ( e | e . oclIsTypeOf ( V a r A s s i g n Ex p r e s s i o n ) implies e . oclAsType ( V a r A s s i gn E x p r e s s io n ) . lhs . ref e rre d Var i able <> a ) )
1 -- a has unique values among all objects of the class 2 context a : Field inv Unique :
3
a . atr . unique implies
FU
4
a . owner . allInstances () -> forAll (o , o ’ | o <> o ’ implies
5
a . value ( o ) <> a . value (o ’) )
1 -- id means both not ( Optional ) and Unique 2 context a : Field inv Id :
IF
3
a . atr . id implies not ( a . Optional ) and a . Unique
a private method p ( both of a . owner ) s . t u contains a body expression e of the form ’a = p (...) ’ ( i . e . u invokes p and assigns the result obtained to a )
1 -- a is not mutable and is not optional and exists a constructor u and 2 -- 3 -- 4 -- 5 context a : Field inv Auto :
6
a . atr . auto implies
7
8
let c : Class = a . owner in if not ( a . Mutable ) then
9
-- c is the owner class of a -- not Mutable ( a ) -- not Optional ( a )
10
11
12
13
if not ( a . Optional ) then -- there exists constructor u and a private operation p of c and a -- body expression e of u s . t . e is a O pe r a t i o n C a l lEx pr of the form -- a = p (...) c . methods - > exists (u , p |
TF
14
u . isCreator () and p . visibility = VisibilityKind :: private and
15
16
17
18
u . postExps () -> exists ( e1 | e1 . oclIsTypeOf ( V a r As s i g n E x p r es s i o n ) and let e = e1 . oclAsType ( V a r A s s i g nE x p r e s s i o n ) in e . rhs . oclIsTypeOf ( O perat ionC a llE x p ) and e . rhs . oclAsType ( Ope rat ionCa l lEx p ) . r e fer red Ope rat ion = p and
19
e . lhs . referred Varia ble . asProperty () = a ) )
20
else
21
false
22
endif
23
else
24
false
25
endif
61
Each constraint in Table 3.4 has the following (more specialised) form:
X.P implies E
where:
– φ = X.P denotes value of the boolean property P of some model element X (X can be a navigation sequence through the association links between model elements e1.e2. . . e n),
– E is defined as before.
For example, let us consider the constraint FM. In this constraint, the condition φ = a.atr. mutable, in which X = a.atr refers to the element AttrRef(a) of some Field a and P = mutable refers to the property AttrRef.mutable. The expression E is the OCL expression that immediately follows the keyword implies. This expression states the existence of a method p as described in the header comment.
Non-Boolean State Space Constraints
The non-boolean constraints shown in Table 3.1 include FL, YV, XV, YL and XL. These are expressed by the following annotation properties in DCSL: DAttr.length, min, max and Associate.cardMin, cardMax. Table 3.5 lists the definitions of the constraints. Each constraint in Table 3.5 has the following (more specialised) form:
X.P op v implies E
where:
– φ = X.P op v denotes an OCL expression that compares, using operator op, the value
of some property X.P to some value v,
– E is defined as before.
For example, let us consider the constraint FL. In this constraint, the condition φ = a.atr .length >= 1 (X.P = a.atr.length, op = ‘>=’ and v = 1). E is the OCL expression that immediately follows the keyword implies. This expression states the universal truth about the operations p that is described in the header comment. Note that E is actually a disjunction of two expressions. The first expression, which is evaluated only when a is typed
62
String, captures the meaning of E stated in the header comment. The second expression is true and is evaluated when otherwise. In this case we do not care about E and thus must specify true to make the invariant hold.
Table 3.5: The non-boolean state space constraints of DCSL
Names
Constraints
1 -- for all opt p of a . owner that mutates a via a parameter m , exists an 2 -- expression e in p ’ s pre that restricts ( m . size () <= a . atr . length )
3
context a : Field inv MaxLength :
4
5
6
FL
let l : Integer = a . atr . length in l >= 1 implies if a . type . name = ’ String ’ then
7
8
a . owner . methods - > forAll ( p | p . i s C r e a t o r O r M u t a t o r R e f ( a ) implies p . params - > exists ( m | m . isAttrRef ( a ) and
9
p . preExps () . exists ( e | e . equals ( m . name + ’. size () <= ’ + l ) ) ) )
10
else true endif
exists an expression e in p ’ s pre that restricts m >= y
4
5
6
YV
1 -- for all operation p of a . owner that mutates a via a parameter m , 2 -- 3 context a : Field inv MinValue : let y : Double = a . atr . min in y <> Double :: INFINITY implies if a . isNumericType () then
7
a . owner . methods - > forAll ( p | p . i s C r e a t o r O r M u t a t o r R e f ( a ) implies
8
p . params () -> exists ( m | m . isAttrRef ( a ) and
9
p . preExps () . exists ( e | e . equals ( m . name + ’ >= ’ + y ) ) ) )
10
else true endif
4
5
6
XV
1 -- for all operation p of a . owner that mutates a via a parameter m , 2 -- exists an expression e in p ’ s pre that restricts m <= a . atr . max 3 context a : Field inv MaxValue : let x : Double = a . atr . max in x <> Double :: INFINITY implies if a . isNumericType () then
7
a . owner . methods - > forAll ( p | p . i s C r e a t o r O r M u t a t o r R e f ( a ) implies
8
p . params () -> exists ( m | m . isAttrRef ( a ) and
9
p . preExps () . exists ( e | e . equals ( m . name + ’ <= ’ + x ) ) ) )
10
else true endif
63
1 -- for - all link - remover operation p of c = owner ( a ) that removes a
collection of objects of c2 = a . type , the pre - and post - conditions of p must be set accordingly
2 -- 3 -- 4 context a : Field inv CardMin :
5
6
7
8
YL
let y : Integer = a . asc . associate . cardMin in y > -1 implies let ca : Class = elementType ( a . type ) in a . owner . linkRemovers () -> forAll ( p | p . isAttrRef ( a ) implies
9
10
p . params () -> size () = 1 and let m : Parameter = p . params () . any ( true ) in elementType ( m . type ) = ca and
11
p . preExps () . exists ( e |
12
e . equals ( ExprTk :: g e n L i n k R e m o v e r P r e C o n d ( ca , m , y ) ) ) and
13
p . postExps () . exists ( e1 , e2 |
14
e1 . equals ( ExprTk :: g e n L i n k R e m o v e r P o s t C o n d 1 (a , m ) ) and
15
e2 . equals ( ExprTk :: g e n L i n k R e m o v e r P o s t C o n d 2 ( ca , a ) ) )
of objects of c = a . type , the pre - and post - conditions of p must be set accordingly
1 -- for - all link - adder operation p of c = owner ( a ) that adds a collection 2 -- 3 -- 4 context a : Field inv CardMax :
5
6
7
8
let x : Integer = a . asc . associate . cardMax in x >= 1 implies let c2 : Class = elementType ( a . type ) in a . owner . linkAdders () -> forAll ( p |
p . isAttrRef ( a ) implies
XL
9
10
p . params () -> size () = 1 and let m : Parameter = p . params () . any ( true ) in elementType ( m . type ) = c2 and
11
p . preExps () . exists ( e |
12
e . equals ( ExprTk :: g e n L i n k Ad d e r P r e C o n d ( c2 , m , x ) ) ) and
13
p . postExps () . exists ( e1 , e2 |
14
e1 . equals ( ExprTk :: g e n L i n k A d d e r P o s t C o n d 1 (a , m ) ) and
15
e2 . equals ( ExprTk :: g e n L i n k A d d e r P o s t C o n d 2 ( c2 , a ) ) )
3.4.2 Behaviour Space Semantics
The behaviour space semantic rules are designed to make precise the informal static semantics of the behaviour types that we listed in Table 3.2. The formalism that we use is based directly on the OOPL’s meta-concepts and, thus, has an added benefit that it can be implemented easily in a target OOPL. We demonstrate this benefit in Section 3.4.3 with a programmatic technique that uses the formalism to automatically generate the behaviour space specification of a domain class.
64
Because each behaviour type directly manipulates some state space elements, we define the semantic rules based on a structural mapping between the state space and the behaviour space. A structural mapping consists of a set of rules, called structural mapping rules, that map elements of meta-attribute assignments (in the state space) to the behaviour elements of the behavioural types.
Structural Mapping Formalism
Let us first use the meta-attribute assignments to define two design spaces. Denote by cF , cO the sets of domain fields and domain methods (resp.) of a domain class c. Further, denote by cR the set of overridden methods of c (cR may be empty).
Definition 3.3. The state space of a domain class c of a DCSL model M is the tuple hα, µα,c, φci, where α = {DClass, DAttr, DAssoc}, φc = {c} ∪ cF ∪ cR and µα,c = {(a, e) | A ∈ α, e ∈ φc, a = A(e)}.
For example, the state space of the domain class Student shown in Figure 3.2 (which includes the association between Student and Enrolment) is hα, µα,Student, φStudenti, where φStudent = {Student, id, name, enrolments} and µα,Student = {(DClass(Student), Student), (DAttr(id), id), (DAttr(name), name), (DAttr(enrolments), enrolments), (DAssoc(enrolments), enrolments)}.
The complete state space that additionally includes the association between Student and
SClassRegistration is defined similarly.
Definition 3.4. The behaviour space of a domain class c of a DCSL model M is the tuple hβ, µβ,c, λci, where β = {DOpt, AttrRef}, λc = cO and µβ,c = {(b, e) | B ∈ β, e ∈ λc, b = B(e)}.
To illustrate, let us consider a partial behaviour space of the class Student shown in Fig- ure 3.2. We will discuss shortly how the complete behaviour space is identified and generated. The partial behaviour space hβ, µβ,Student, λStudenti has λStudent = {Student[2], getName} and µβ,Student = {(DOpt(Student[2]), Student[2]), (AttrRef(Student[2].0), Student[2].0), (AttrRef(Student[2].1), Student[2].1), (DOpt(getName), getName)}.
In this set example, Student[2] denotes the 2-parameter constructor Student(Integer, String) and Student[2].n (n ∈ {0, 1}) denotes the first and second parameters of the con- structor.
65
A key observation that we make is that we can structurally map element patterns of the
state space to those of the behaviour space.
Definition 3.5. Given a state space hα, µα,c, φci, k meta-attributes A1, . . . , Ak ∈ α, and k stateful functions ui : Ai → {true, false} (i = 1. . .k). A state space element pattern (SSEP) w.r.t (A1, u1) ,. . . , (Ak, uk) is the set {(a, e) | (a, e) ∈ µα,c, a = A1(e), u1(a), . . . , a = Ak(e), uk(a)}. To ease notation, we will write SSEP by listing just the pairs (Ai, ui).
A stateful function is named after the property of the meta-attribute (Ai) and the condition to be applied to that property’s value. We will discuss the set of all the essential stateful functions for DCSL in the next section. For example, function isMutable in the SSEP (DAttr, isMutable) means to check property DAttr.mutable for the condition that its value being set to true. The SSEP itself is thus the set of all the DAttr assignments of a state space in which DAttr.mutable=true. In the context of the Student’s state space given above, this set is {DAttr(name), DAttr(enrolments)}.
For the sake of exposition, we next define a special type of SSEP which involves at least two meta-attributes, at least one of the stateful functions associated to which are the special stateful function named unassign. This function “reverses” the effect of assigning a meta- attribute to an element. That is, for any i: (a = Ai(e) ∧ unassign(a)) ↔ undef(Ai(e)).
Definition 3.6. Given a state space hα, µα,c, φci, k meta-attributes A1, . . . , Ak ∈ α (k > 1), k stateful functions ui : Ai → {true, false} (i = 1. . .k), and ∃i ∈ [1...k].ui = unassign. An SSEP w.r.t (A1, u1),. . . , (Ak, uk) is called an SSEP with negation (SSEPN).
For example, (DAttr, isAuto), (DAssoc, unassign) is an SSEPN. It is the set of all the DAttr assignments of a state space in which DAttr.auto=true and the target elements are not assigned with any DAssocs. In the context of the Student’s state space given above, this set is {DAttr(id)}.
Definition 3.7. Given a behaviour space hβ, µβ,c, λci, k meta-attributes B1, . . . , Bk ∈ β, : Bi → {true, false} (i = 1. . .k). A behaviour space and k stateful functions vi element pattern (BSEP) w.r.t (B1, v1), . . . , (Bk, vk) is the set {(b, e) | (b, e) ∈ µβ,c, b = B1(e), v1(b), . . . , b = Bk(e), vk(b)}. To ease notation, we will write BSEP by listing just the pairs (Bi, vi).
For example, the BSEP (DOpt, isRequiredConstructorType) is the set of all the DOpt assignments of a behaviour space in which DOpt.type = RequiredConstructor. In
66
the context of the Student’s behaviour space in the example of Definition 3.4, this set is {DOpt(Student[2])}.
Now, let us denote by Σ and Π the sets of SSEPs and BSEPs of the state and behaviour
spaces of a domain class (resp.).
Definition 3.8. Structural mapping from the state space hα, µα,c, φci to the behaviour space hβ, µβ,c, λci is an injective function: Σ → P(Π), that maps a SSEP of the state space to a subset of BSEPS of the behaviour space according to a set of rules.
We call a domain class c behaviour essential if c’s structure conforms to this mapping.
Structural Mapping Rules
Table 3.6: The core structural mapping rules
SSEP(N)s
No
DAttr
DAssoc
BSEPs DOpt
Property
Stateful func.
1
type
isObjectFormConstructorType
2
type
isRequiredConstructorType
3 4
Property – – – – – – –
Stateful func. isNotAuto isNotCollectionType isNotAuto isNotCollectionType isNotOptional isMutable isAuto
Property auto type auto type optional mutable auto
Stateful func. – – – – – – unassign
isOneManyAsc
ascType
5
type
isCollectionType
isOneEnd
endType
6
type
isDomainType
isOneOneAsc
ascType
type type type type type type type type type
isSetterType isAutoAttributeValueGenType isLinkAdderNewType isLinkAdderType isLinkUpdaterType isLinkRemoverType isLinkCountGetterType isLinkCountSetterType isLinkAdderNewType
Table 3.6 lists the structural mapping rules for the different OptTypes in DCSL. Each num- bered row of the table defines one structural mapping rule. The column labelled “SSEP(N)s” lists the SSEPs and/or SSEPNs of each rule, and the column labelled “BSEPs” lists sets of BSEPs of the same rule. The SSEPs are related to two meta-attributes DAttr and DAssoc. The stateful functions associated to these meta-attributes in each pattern are listed under the sub-column labelled “Stateful func.”. The sub-column “Property” lists the properties (if any) of each meta-attribute in a pattern, whose values are conditioned by the corresponding stateful function.
67
Except for the stateful function unassign, other stateful functions are primitive stateful functions. Each primitive stateful function is defined for a single property. For patterns that involve more than one property, their stateful functions are straight-forwardly constructed by logical-ANDing the primitive stateful functions of the concerned properties.
A primitive stateful function is named after a property and the condition that is applied to that property’s value. In particular, the name of each BSEP’s stateful function is an OptType value. For example, function isAuto means to check if DAttr.auto=true. Similarly, function isCollectionType (isNotCollectionType) means to check if DAttr.type is (resp. is not) a type of Collection. As another example, function isSetterType means to check if DOpt.type=Setter.
Let us explain how to read the mapping rules using four representative examples. The first two examples are rules 2 and 3. Rule 3 maps SSEP (DAttr, isMutable) to BSEP (DOpt, isSetterType). Rule 2’s SSEP involves three properties and its state- ful function is constructed by logical-ANDing three primitive stateful functions: (DAttr, isNotAuto ∧ isNotCollectionType ∧ isNotOptional). This is mapped to the BSEP (DOpt, isRequiredConstructorType).
The third example is rule 4, which maps SSEPN (DAttr,isAuto), (DAssoc,unassign) to BSEP (DOpt,isAutoAttributeValueGenType). The last example is rule 5, which maps one SSEP to six BSEPs. The SSEP is:
(DAttr,isCollectionType), (DAssoc,isOneManyAsc ∧ isOneEnd). The six BSEPs are: (DOpt, isLinkAdderNewType), (DOpt, isLinkAdderType), (DOpt, isLinkUpdaterType),
(DOpt, isLinkRemoverType), (DOpt, isLinkCountGetterType), and (DOpt, isLinkCountSetterType).
3.4.3 Behaviour Generation for DCSL Model
In this section, we explain a programmatic technique that uses the static semantics described in the previous subsections to automatically generate the behaviour specification of the domain methods. Our technique is captured in Alg. 3.1 by a function named BSpaceGen. This function, which is applied at compile-time, takes as input a domain class (c) in the source code form, whose state space is specified in DCSL and automatically generates in c a set of domain method definitions.
68
// create constructors
create in c object-form-constructor c1(u1, . . . , um) (uj ∈ FU ) // rule 1
1 FU ⇐ {f | f ∈ cF , ¬isAuto(DAttr(f )), ¬isCollectionType(DAttr(f ))} 2 FR ⇐ {f | f ∈ FU , ¬isOptional(DAttr(f ))} 3 if FU 6= ∅ then 4 5 if FR 6= ∅ then 6
create/update in c required-constructor c2(r1, . . . , rp) (rk ∈ FR) // rule 2 // create other methods
Alg.3.1 BSpaceGen Input: c: a domain class whose state space is specified Output: c is updated with domain method specification (of the behaviour space)
create in c getter for f if isMutable(DAttr(f )) then create in c setter for f // rule 3 if def(DAssoc(f )) then if isOneManyAsc(DAssoc(f )) ∧ isOneEnd(DAssoc(f )) then create in c link-related methods for f // rule 5 else if isOneOneAsc(DAssoc(f )) then create in c link-adder-new for f // rule 6
7 for all f ∈ cF do 8 9 10 11 12 13 14 15 16 17
if isAuto(DAttr(f )) ∧ undef(DAssoc(f )) then create in c auto-attribute-value-gen for f // rule 4
We assume that each method type has a header template that is available in the target OOPL. The templates are similar to those of the class Student in Figure 3.2. To ease reading, we name the methods after their types. For example, the required-constructor method at line 6 refers to the method whose type is RequiredConstructor.
Theorem 3.1. Behaviour Generation The input domain class updated by Alg 3.1 is behaviour essential.
Proof. The proof is helped by the marker comments in the algorithm text referencing the mapping rules that are applied. These comments show that the algorithm has implemented all the mapping rules in Table 3.6. A scatch of the proof is as follows.
The two sets FU and FR (created at lines 1-2) are sets of class fields that satisfy the SSEPs of the two constructor rules 1 and 2 (resp.). Each set forms the parameters of a corresponding constructor. The constructors are created at lines 3-4 and 5-6. The create/update statement at line 6 is to allow for the case that these sets are the same. That is, if FU = FR then object-form- constructor (c1) is the same as the required-constructor (c2). In this case, c2 is not created. Instead, c1 is assigned with an additional DOpt, whose type is RequiredConstructor.
The for loop at lines 7-17 realises other structural mapping rules (3–6), which are applied
69
to the individual class fields. Rule 3 is applied at line 10 to create a setter for the domain field f if it is mutable. Rule 4 is applied at line 17 to create an auto-attribute-value-gen method for f if it is an auto, non-associative field. If f is an associative field then rules 5 and 6 are applied (at lines 13 and 15 resp.) to create the required link-related methods for the two cases of one-many and one-one associations (resp.).
Theorem 3.2. Complexity The worst-case time complexity of Alg 3.1 is linear in number of domain fields of the input domain class.
Proof. The dominant parts of Alg. 3.1 are the formations of the sets FU (line 1) and FS (line 2) and the for loop (lines 7-17). All three parts have the same worst-case time complexity O(|cF |), i.e. linear in the number of the domain fields of c. First, the formulation of FU requires a loop over elements of cF . This loop has |cF | as the max number of iterations. Second, the formulation of FR requires a loop over the elements of FU . Thus, this loop also has |cF | as its max number of iterations. Third, the for loop iterates over the elements of cF and, in each iteration, performs some method creation statements. The max number of these statements is a constant which equals the number of the essential operation types that are applicable to the mapping rules 3–6. Hence, the for loop also has the complexity of O(|cF |).
Discussion
It is necessary to give two remarks concerning the relationship between behaviour specifi- cation and the overall software behaviour and that between the behaviour specification of a domain method and its code. First, we contend that if the domain classes of a domain model are fully specified by DCSL as described in this chapter then it can be used as basis to construct the software modules that make up a software. A module’s behaviour is mapped to that of its domain class. We will explain this in detail in Chapter 4.
Second, the behaviour space expressed by DCSL contains only the primitive behaviour types, whose behaviour specifications can precisely be specified using OCL expressions that are translatable directly to OOPL code. This means that a domain method’s code can be automatically generated from its behaviour specification. Indeed, our implementation of the function BSpaceGen in jDomainApp generates also the method code. We will explain the reason behind this through the Student’s specification in Listing 3.1. The OCL expressions
70
of the pre- and post-conditions of the domain methods only invoke either the built-in operators of the built-in OCL types (primitive and collection) or other domain methods of the same class (e.g. genId). These operators and types are readily supported by OOPL.
The OCL expression of the AutoAttributeValueGen method (e.g. genId) has two additional features that are worth explaining. First, it uses an if expression, which is also supported by OOPL. Second, in practice, the domain-specific value pattern associated with AutoAttributeValueGen can be more complex than in the above example. It would typically involve combining a pre-defined text label and a value. This value is automatically generated by a generator formula, which may reference some domain field(s) of the same class. In this case, however, we can still represent the value pattern by an expression that includes the formula as a sub-expression. Parsing this type of expression is within the capability of OOPL.
3.5 Dynamic Semantics of DCSL
In principle, the dynamic semantics of DCSL is derived from the dynamic semantics of the host OOPL, augmented with the semantics of the DCSL’s meta-attributes. More technically, that semantics describes what happens when a DCSL model, written as a program in an OOPL, is executed. We will discuss the dynamic semantics of DCSL under the headings of its three terms (see Definition 3.2). In particular, we will explain whether these terms affect the dynamic semantics of Class, Field and Method (resp.); and, if so, what the effects are.
Domain Class and Method
Regarding to Domain Class, the meta-attribute DClass has one property, DClass.mutable, which only affects the static semantics of Class.
As for Domain Method, the two properties DOpt.requires and effects do not alter the meaning of Method. They only help make explicit the meaning of the pre- and post- conditions. More specifically, an execution of a Domain Method on a domain object results in a state satisfying DOpt.effects if the state before the execution satisfies DOpt.requires. More formally, with regards to Java method specification, DOpt.requires and effects are translatable into the @requires and @effects clauses of JML. These clauses are designed to capture the pre- and post-conditions of Java methods.
71
Domain Field
We observe that a subset of the properties of Domain Field, which are defined in two meta- attributes DAttr and DAssoc, only have the static semantics explained in Section 3.4. Other properties carry dynamic semantics. We explain these properties’ semantics by adapting the translational semantic specification approach (see Section 2.1.3). We translate the properties into equivalent class invariants concerning Field.
Table 3.7: Translating Domain Field properties into JML’s class invariants
Properties
Descriptions
Meta-attributes/ Annotations
optional
length
DAttr
unique
min
max
cardMin
DAssoc.associate
cardMax
class invariant on Field f stating whether or not f is null class invariant on Field f constraining that f ’s values do not exceed a given length class invariant on Field f constraining that f ’s values are unique class invariant on Field f constraining that f ’s values are not lower than a given value class invariant on Field f constraining that f ’s values are not higher than a given value class invariant on Field f constraining that the number of links that each of f ’s value holds is not lower than a given number class invariant on Field f constraining that the number of links that each of f ’s value holds is not higher than a given number
For illustration purpose, we use Java/JML as the language for writing the invariant. We choose JML because, as discussed in Section 2.1.8, it is a design specification for the Java language that also uses annotation to model the language constructs. Further, the semantics of both JML [10, 46] and Java [2, 7] are well established. Table 3.7 lists the properties of DAttr and DAssoc that are translatable into JML invariants. The general semantics of a class invariant in JML is that it holds for all objects of the owner class in all visible states.
3.6 Unified Domain Model
Let us now explain how to use DCSL to construct a unified domain model (UDM). We call the process for constructing a UDM UD modelling. There are two reasons why UDM is feasible. First, we can use UML/OCL as the base language to express the state-specific structure of activity modelling. Second, the resulted UML/OCL model can be expressed in DCSL.
72
3.6.1 Expressing UDM in DCSL
The term ‘unified’ in UDM refers to a unique representation scheme that we propose, which merges the class modelling structure and the state-specific activity modelling structure into a unified class model. The state-specific structure includes activity class and activity node, but excludes activity edge. We first define the unified class model and then explain how this model is expressed as UDM in DCSL.
Definition 3.9. A unified class model is a domain model whose elements belong to the following types:
• activity class: a domain class that represents the activity. • entity class: a domain class that represents the type of an object node. This class
models an entity type (see the Entities pattern of Section 2.1.4).
• control class: captures the domain-specific state of a control node. A control class that represents a control node is named after the node type; e.g. decision class, join class etc. A control class that does not represent a control node is named after the negation of the corresponding control class; e.g. non-decision class, non-join class etc.
• activity-specific association: an association between each of following class pairs:
– activity class and a merge class.
– activity class and a fork class.
– a merge (resp. fork) class and an entity class that represents the object node of an
action node connected to the merge (resp. fork) node.
– activity class and an entity class that does not represent the object node of an
action node connected to either a merge or fork node.
We will collectively refer to the entity and control classes as component classes.
Note the following points about Definition 3.9. First, the representation scheme in the It definition does not cover all the possible associations among the component classes. focuses only on the activity-specific ones. These associations help explicitly model the links between domain-specific states of the activity nodes.
Second, to ease representation we do not model any activity-specific associations between activity class and decision and join classes. Instead, with the fourth class pair of activity- specific association in the definition, we model the associations between the activity class
73
and the entity classes connected to these two node types. The main reason for this design choice is because, unlike the fork and merge nodes, it is not essential to make the logics of the decision and join nodes visible.
Third, the condition imposed on the fourth class pair in the definition stems from the fact that there is no need to explicitly define the association between an activity class and an entity class that represents the object node of an action node connected to either a merge or fork node. Such an entity class is ‘indirectly’ associated to the activity class, via two associations: one is between it and the merge or fork class (the third class pair) and the other is between the activity class and this control class (the first or second class pair).
Definition 3.10. A unified domain model (UDM) is a DCSL model that realises a unified class model as follows:
– a domain class ca (called the activity domain class) to realise the activity class. – the domain classes c1, . . . , cn to realise the component classes. – let ci1, . . . , cik ∈ {c1, . . . , cn} realise the non-decision and non-join component classes, contain associative fields that realise the corresponding association
then ca, ci1, . . . , cik ends of the relevant activity-specific associations.
In the remainder of this dissertation, to ease notation we will use activity class to refer to
the activity domain class ca and component class to refer to the c1, . . . , cn.
Example 3.2.
To illustrate, Figure 3.3(A) shows the UML activity and class models of the Course- Man variant that handles the sequential activity model of enrolment management. We described this activity model in Example 2.5 of Chapter 2. Recall that in this variant, stu- dents are allowed to request help after the making the initial registration. The accompanied class model in Figure 3.3(A) is extracted (as a sub-model of) the CourseMan’s conceptual model shown in Figure 1.1.
Figure 3.3(B) shows the resulted UDM of the activity. This model consists of five domain classes and realisations of five activity-specific associations. To ease reading, we omit the domain-specific associations that are shown in the UML class model in Figure 3.3(A). Class EnrolmentMgmt is the activity class. Class DHelpOrSClass is a decision class, which captures the domain-specific decision logic. The remaining three classes are entity classes that realise the three types of object nodes involved. These entity classes also correspond to
74
Figure 3.3: (A: Left) The UML activity and class models of a CourseMan software variant that handles the enrolment management activity; (B: Right) The UDM that results.
three domain classes in the UML class model. Among the five activity-specific associations, three associate EnrolmentMgmt and the entity classes. The remaining two associations associate decision class DHelpOrSClass to two entity classes (SClassRegistration and HelpRequest), which realise the object nodes connected to the two actions nodes branching of the decision node. These associations are weak dependency associations and only added in this case because the decision logic encapsulated by DHelpOrSClass needs to reference the two entity classes.
Incremental UD Modelling
An important benefit of UDM is that it can be constructed incrementally, whereby domain- specific elements are gradually discovered and added to the model by the development team. For example, the EnrolmentMgmt’s UDM shown previously in Figure 3.3(B) helps identify one new association between Student and HelpRequest. This association is necessary to ensure the object flow between the corresponding pair of activity nodes in the EnrolmentMgmt’s activity. More examples like this will appear in the next section when we discuss the UD modelling patterns in the next section.
75
3.6.2 UD Modelling Patterns
To demonstrate the practicality of UDM and to ease the application of UD modelling in prac- tice, we define five UD modelling patterns. We name these patterns (sequential, decisional, forked, joined and merged) after the five primitive activity flows of the activity modelling language (discussed in Example 2.5).
We focus in particular on the design of the pattern form [27, 65]. To keep the patterns generic, we present for each pattern form the activity model and the template UDM that realises the activity model. The template UDM is a ‘parameterised’ DCSL model, in which elements of the non-annotation meta-concepts are named after the generic roles that they play. We use the DCSL model notation of Figure 3.2 to draw the UDM. For brevity, we will assume that all fields that are listed in a DCSL model diagram are domain fields and, thus, will omit from this diagram the DAttr assignments of these fields. Further, we will omit the base domain methods of each domain class.
Each pattern is illustrated with an example, which is a variant of the CourseMan’s enrolment management activity described in Example 2.5, whose name corresponds with the pattern’s name. A pattern example includes a concrete UDM and one or more software GUIs. The software is automatically generated from the UDM, using the software tool that we have implemented for this dissertation. We will describe this tool later in Chapter 5.
Sequential Pattern Form
We begin in this section with the design of the sequential pattern form. The top-right of Figure 3.4 shows the activity model, the top-left shows the template UDM. The latter consists of three classes Ca, Cs and Cn and three associations. Class Ca is the activity class and has two associations with the two entity classes Cs and Cn. The objects of these classes are manipulated by the action nodes es and en (resp.) of the activity model.
There are two one-many associations between Ca and Cs and Cn, and one one-many association between Cs and Cn. The first two associations are used to connect the activity to the two entity classes. The third association is a weak dependency from Cn to Cs. It is added in order to realise the object flow from action es to action en.
76
Figure 3.4: The sequential pattern form (top left) and an application to the enrolment management activity.
Example 3.3. The remainder of Figure 3.4 shows how the pattern is applied to the sequential activity model of the CourseMan’s enrolment management activity. The activity model is shown at the bottom left. This activity involves performing two actions in sequence. The first action (es) registers a student into course modules, while the second action (en) registers the student into a preferred class.
In this example: Ca = EnrolmentMgmt, Cs = Student, n = 1, C1 = SClassRegistration. Note that the weak dependency association between SClassRegistration and Student is superseded by the existing association (shown in Figure 1.1) between these two classes. The GUI of the UDM is shown in Figure 3.5. It presents how the activity’s GUI (EnrolmentMgmt’s in this example) contains the GUIs of the two actions in separate tabs. This provides the user with an awareness of the activity context, while performing a given action. The LHS GUI shows the tab containing the Student’s GUI, while the RHS GUI shows the tab containing the SClassRegistration’s GUI. Note, in particular, that the data field of the associative field SClassRegistration.student is automatically set to the value Student(name=“Nguyen Van Anh”). This Student object is created on the Student’s GUI.
77
Figure 3.5: The sequential pattern form view of enrolment management activity.
Decisional Pattern Form
The top-left of Figure 3.6 shows the template UDM that realises the activity model shown on the top-right. Apart from the activity class Ca, the template UDM includes five other domain classes, namely Cd, D, C1, Cn and Ck, that are mapped to the five activity nodes. Class Ck is a control class that is referenced by the control node ck of the activity model. Class D is a decision class, which is a domain class that is referenced by the decision node. This class is derived from an interface named Decision. It defines the domain-specific control logic for the decision node. This logic requires knowledge of and may cause new features to be added to the domain classes involved ( namely C1, Cn and Ck). Thus, we add three weak dependency associations to the model to associate class D to these classes.
Class Ca has one-many associations to the other four domain classes. The configurations of these associations are similar to those in the sequential pattern’s form. Note, in particular, that the association to Ck can be used as a bridge in a larger activity model to other activity flow blocks. This association is applied differently if ck is a decision node. In this case, the association to Ck is replaced by (or “unfolded” into) a set of associations that connect Ca directly to the domain classes of the UDM containing Ck.
The two weak dependency associations between C1, Cn and Cd reflect the fact that both C1 and Cn know about Cd, due to the passing of object tokens from ed to e1 and en (via the decision node).
78
Figure 3.6: The decisional pattern form (top left) and an application to the enrolment management activity.
Example 3.4. The remainder of Figure 3.6 shows how the pattern is applied to the decisional activity model of the CourseMan’s enrolment management activity. The activity model of this activity is displayed at the bottom left. In this activity, after performing student registration (ed), a student may either (e1) request help from the help desk or (e2) register into classes. The control node ck is not used.
In this example: Ca = EnrolmentMgmt, Cd = Student, D = DHelpOrSClass, n = 2, C1 = HelpRequest,
C2 = SClassRegistration.
The decision logic captured by DHelpOrSClass requires that a new boolean-typed domain field Student.helpRequested be added. If this field is set to true then the decision outcome is (a), otherwise the decision is (b).
Similar to the sequential pattern, the activity’s GUI in Figure 3.7 contains GUIs of the three actions in separate tabs. Under both cases of the decision, the Student object
79
Figure 3.7: The decisional pattern form view of enrolment management activity.
(e.g. Student(name=“Nguyen Van Anh”)) that is created in the first action is passed on to the next action. This object is then presented in the view field student of the domain class mapped to the action. In Figure 3.7, the first GUI is for student registration, the second and third are for when help is and is not requested (resp.).
Forked Pattern Form
The top-left of Figure 3.8 is the template UDM that realises the activity model shown on the top-right. The activity class Ca has two associations to the entity class Cf (referenced by node ef ) and the fork class Co (representing the forked node). Class Co in turn has associations to the other three domain classes, namely C1, Cn and Ck. In addition to these, class Cf has two weak dependency associations to C1 and Cn, as these classes need to know Cf through object passing.
Note a key difference between this template UDM and the model of the decisional pattern, that class Ca is not directly associated to C1, Cn and Ck. It is instead associated to the control class Co and this class is in turn associated to the other three classes. The rationale behind this design choice is that, compared to the decision node, the fork node arguably involves a separate concurrency control process. This process requires a coordination strategy between the action nodes e1, en and ck.
Similar to the decisional pattern’s model, however, the association from Co to Ck can be
used as a bridge in a larger activity model to connect to other activity flow blocks.
80
Figure 3.8: The forked pattern form (top left) and an application to the enrolment management activity.
Example 3.5. The remainder of Figure 3.8 shows how the pattern is applied to the forked activity model of the CourseMan’s enrolment management activity. The activity model of this activity is shown at the bottom left. This activity involves performing student registration (ef ) and then two support actions concurrently: payment processing (e1) and enrolment authorisation (e2). These actions must be completed in order for any subsequent actions to proceed.
In this example: Ca = EnrolmentMgmt, Cf = Student, Co = FEnrolmentProcessing,
n = 2, C1 = Payment, C2 = Authorisation.
Note that in addition to the newly added associations in the example model, we have DClass(Payment).mutable=false and DClass(Authorisation).mutable=false. This is because both Payment and Authorisation objects are not to be modified after creation. These objects are created by the system after it has executed the payment and authorisation processes.
The two snapshots of the UDM’s GUI concerning the two concurrent actions (making
81
Figure 3.9: The forked pattern form view of enrolment management activity.
payment and enrolment authorisation) are shown in Figure 3.9. The snapshot for the first action (“Student Registration”) is similar to that of Student, which was presented in Fig- ure 3.7. A difference between this GUI and the GUIs of the previous two patterns is that it has a 2-level containment. Basically, this 2-level containment reflects the length-2 association chain from EnrolmentMgmt (the activity class) to Payment and Authorisation. The first- level containment is that between the activity’s GUI and enrolment processing’s GUI. The second-level containment is that between the enrolment processing’s GUI and Payment’s and Authorisation’s GUI.
Joined Pattern Form
The top-left of Figure 3.10 is the template UDM of the pattern. Similar to the decisional pattern’s form, the model consists of an activity class Ca and five other domain classes, namely C1, Cn, Ck, J and Cj. Classes C1, Cn, Ck and Cj are referenced by the activity nodes e1, en, ck and ej (resp.). Class J is a join class, which is a domain class that is referenced by the join node. This class implements an interface named Join. The implementation is domain-specific and involves writing the join logic. This logic requires knowledge of and may cause new features to be added to the three domain classes involved, namely C1, Cn and Ck. Thus, we add three weak dependency associations to the model to associate class J to these three classes.
82
Figure 3.10: The joined pattern form (top left) and an application to the enrolment manage- ment activity.
Class Ca has one-many associations to the other four domain classes. The configurations of these associations are similar to those discussed in the decisional pattern’s form. The two weak dependency associations between Cj and C1, Cn reflect the fact that Cj knows about both C1 and Cn, due to the passing of object tokens from e1 and en to ej (via the join node).
Example 3.6. The remainder of Figure 3.10 shows how the pattern is applied to the joined activity model of the CourseMan’s enrolment management activity. The activity model of this activity is shown at the bottom left. This activity involves joining two actions that concern the same Student, namely making payment (e1) and registration authorisation (e2), before concluding at the enrolment approval action. This last action decides, based on the results of the other two actions, whether or not to approve the student enrolment.
In this example: Ca = EnrolmentMgmt, n = 2, C1 = Payment, C2 = Auhorisation, J = PaymentAuthorise and Cj = EnrolmentApproval. Note that in addition to the newly added associations in the example model, class
83
Figure 3.11: The joined pattern form view of enrolment management activity.
EnrolmentProcessing is added with a domain field student, which is used to ob- tain input from the user for a Student. As discussed in the forked pattern’s example, this Student is needed to initialise the payment and authorisation processes. Note fur- ther that, for the same reason as that described in the forked pattern’s example, we have DClass(Payment).mutable=false and DClass(Authorisation).mutable=false. Three snap- shots of the UDM’s GUI are shown in Figure 3.11: the first snapshot is for making payment, the second is for registration authorisation and the third is for enrolment approval.
Merged Pattern Form
The top-left of Figure 3.12 is the template UDM of the pattern. Similar to the forked pattern’s form, the activity class Ca has two associations to the entity class Cm (referenced by node em) and the merge class Cg. Class Cg in turn has associations to the other three domain classes (C1, Cn and Ck). In addition to these, class Cm has two weak dependency associations to C1 and Cn, as Cm needs to know these classes through object passing. The rationale behind the 2-level association chain is that the merge node represents a logical grouping of flows from the action nodes e1, en and ck.
The association from Cg to Ck can be used as a bridge in a larger activity model to connect
84
Figure 3.12: The merged pattern form (top left) and an application to the enrolment manage- ment activity.
to other activity flow blocks.
Example 3.7. The remainder of Figure 3.12 shows how the pattern is applied to the merged activity model of the CourseMan’s enrolment management activity. The activity model is shown at the bottom left. This activity involves merging two actions, namely student class registration (e1) and attending an orientation (e2), to conclude at the action enrolment closure (em). The assumption here is that students can perform any combination of the two actions e1, e2. The completion of any one action will lead to enrolment closure. The action that has not yet been performed can be performed by the students at some later time.
Action e2 requires adding a new domain class named Orientation to the CourseMan’s UDM. This class is displayed at the bottom right of Figure 3.12.
In this example: Ca = EnrolmentMgmt, n = 2, C1 = SClassRegistration, C2 = Orientation,
85
Figure 3.13: The merged pattern form view of enrolment management activity.
Cg = MgEnrolmentProcessing and Cm = EnrolmentClosure. The UDM’s GUI in Figure 3.13 shows a length-2 association chain from the activity class EnrolmentMgmt to SClassRegistration and Orientation. The first level is realised by the containment between class EnrolmentMgmt and classes MgEnrolmentProcessing and EnrolmentClosure. EnrolmentClosure’s GUI is the snapshot on the far right. The second level is realised by the containment between MgEnrolmentProcessing and SClassRegistration and Orientation. SClassRegistration’s GUI is the snapshot on the far left and Orientation’s GUI is the remaining snapshot.
86
3.7 Summary
In this chapter, we first specified a horizontal aDSL named DCSL, which is used for expressing the essential structural and behavioural features of a domain model. These features include a set of structural constraints and a set of behaviour types. We systematically defined the DCSL’s domain requirements concerning the features, synthesising from our reviews of the authoritative software and system engineering sources. Based on these requirements, we then constructed the DCSL’s abstract syntax using UML/OCL. We also specified the static and dynamic semantics of DCSL.
We next applied DCSL to precisely define the UDM and explained how the UDM can be constructed incrementally. We demonstrated the practicality of UDM and UD modelling by defining a set of UD modelling patterns.
We argue that constructing the UDM in this way is necessary for software development with the DDD method, because the software can only function sufficiently well if its domain model core is adequately expressed with features from both the structural and behavioural aspects. In the next chapter, we will present a method for developing software from the UDM. The content of this chapter is published in the following papers (listed in the Publications
section): one conference paper 1 and one SCIE journal paper 4.
87
Chapter 4
Module-Based Software Construction with aDSL
In this chapter, we explain our contributions concerning module-based software construc- tion. We first set the software construction context by defining a software characterisation scheme. We then specify another horizontal aDSL, called MCCL, for expressing the module configuration classes (MCCs). We also discuss a generator for the MCCs.
4.1
Introduction
Although the existing works in DDD [17, 22, 60] support domain module, they do not address how to use it to form software module. More specifically, they do not consider software modules as first-class objects and, thus, lack a method for their development. Further, they lack a characterisation of the software that is constructed from the domain model. This characterisation provides an essential technical guidance for software construction with DDD. To tackle these problems we propose to use the MOSA architecture (discussed in Section 2.2.4) as the basis to define a 4-property software characterisation. Further, we propose a generative technique for constructing software modules in MOSA. The modules are created directly from the domain classes of the UDM.
Specifically, we first extend MOSA with three enhancements that help make this archi- tecture amenable to generative development. We next consider modules as objects of module class, which is constructed from module configuration. We thus make module configurations objects and capture their design in a module configuration class (MCC). We then propose a horizontal aDSL named Module Configuration Class Language (MCCL) for constructing the MCCs. To help reduce the effort needed to construct the MCC, we define a generator function, named MCCGen, that automatically generates an MCC from a domain class. The automation is based on a structural mapping between the MCC and the domain class.
88
Figure 4.1: A detailed view of DDDAL’s phase 2 with software module construction.
MCCL helps refine the second phase of our overall DDDAL method (presented in Sec- tion 1.3) as shown in Figure 4.1. The figure includes an MCC model that conforms to MCCL and five smaller activities (1–4 and 6) relating to the use of this model. Activities 3–6 are performed repeatedly until both the domain and MCC models satisfy the domain requirements. Our MCC design brings two important benefits. First, each MCC can easily be customised to create a different variant of the same module, without having to change the module’s internal design. Further, the MCCs of different module classes can flexibly be combined to create software configurations for different software variants.
The rest of the chapter is structured as follows. Section 4.2 presents our software charac- terisation. Section 4.3 discusses the enhancements of MOSA and how these help define our module configuration approach. Section 4.4 specifies MCCL. Section 4.5 presents MCCGen. Finally, Section 4.6 summarises and concludes the chapter.
4.2 Software Characterisation
Our study of the software generators of the DDD frameworks [17, 60, 62] (hereafter referred to as “DDD tools”) together with our experience in developing the jDomainApp software
89
framework1 had led us to the identification of four properties that characterise software developed in a DDD method. Two of these properties (instance-based GUI and model reflectivity) arise from the need to construct software from the UDM. The other two properties were derived from well-known design properties.
We first introduce in Subsection 4.2.1 an abstract software model. We then use this model in the remaining subsections to define the four properties. We demonstrate, through the CourseMan example, how the software generated by jDomainApp supports each property. Further, we also highlight the extent to which the existing DDD tools support each of the property. To ease discussion, we will use the term “software” to refer to software prototype and the term “user” to refer to the development team members.
4.2.1 An Abstract Software Model
Figure 4.2 shows an abstract model of the software that is generated using our method. This model presents an abstract view of MOSA. It consists of three lay- ers: domain model layer (core), module layer (middle) and software layer (top). The domain model layer presents an ab- stract model of DCSL, which is expressed in terms of the four domain terms that we listed in Definition 3.2. We will explain further about the three layers of the model in our expositions of the software proper- ties in the subsequent sections.
Figure 4.2: An abstract UML-based software model: (core layer) domain model, (middle layer) module and (top layer) software.
1 paper 5 listed in the Publications section.
Conceptually, given a UDM, we semi- automatically construct a software model instance and use it as input in jDo- mainApp to generate a GUI-based software. For example, Figure 4.3 shows the software generated for the CourseMan’s UDM, that was constructed for the example of the forked modelling pattern in Section 3.6.2.
90
Figure 4.3: The GUI of CourseMan software prototype generated by jDomainApp: (1) main window, (2-4) the UDM’s GUI for EnrolmentMgmt, Student, and Enrolment.
4.2.2 Instance-based GUI
This is the extent to which the software uses a GUI to allow a user to observe and work on instances of the UDM. This property and the next property (model reflectivity) describe the components at two reflective ends that can be mapped through one structure in the module layer of our software model. We will explain this structure in the next subsection. To illustrate the property, let us consider the software GUI in Figure 4.3. This GUI consists of a main window that displays a set of menus, a tool bar, and a workspace. The view of EnrolmentMgmt (view numbered 2) in the figure is the GUI of the CourseMan UDM concerning the enrolment management activity. The menus and tool bar provide user with a set of actions that can be performed on this GUI.
Existing DDD tools only provide object GUIs, not instance-based ones. The former focuses on presenting objects of individual domain classes, while the latter targets objects of different domain classes that are associated (directly or indirectly) in the model.
91
4.2.3 Model reflectivity
This is the extent to which the GUI faithfully presents the UDM and its structure. This property is central to the functionality of the software GUI. The structure in the top part of the module layer in Figure 4.2 defines model reflectivity. This part consists of View, Data Field and two associations: reflectField(Data Field, Domain Field) and reflectCls(View, Domain Class).2 A View is composed of Data Fields, ‘reflectively’ similar to how a Domain Class is composed of Domain Fields. An association chain, which consists of domain classes that are sequentially associated through several associations, is reflected by the reflexive compose-of association on View. This association results from two other associations: references(Associative Field, Domain Class) and reflectCls(View, Domain Class). These together cause the presentation of the domain class that is referenced by an associative field of a domain class as a component View (or subview) of the View of this class.
For example, the EnrolmentMgmt’s view in Figure 4.3 reflects the UDM’s structure. The views of two other domain classes (Student and Enrolment) shown in the figure provide reflective views for sub-models of the UDM. In particular, the EnrolmentManagement’s view consists directly of two subviews: Student Registration and Enrolment Processing. These two subviews are created from the two associative fields EnrolmentMgmt.students and EnrolmentMgmt.enrolProcs. The Enrolment Processing’s subview reflects an association It presents the fork class FEnrolmentProcessing and consists of two subviews: chain. Payment and Authorisation. These are created from the two associative fields (payments and authorisations) of this class.
The GUIs of existing DDD tools are only partially reflective because they only focus on presenting a GUI for each domain class. Their GUIs only support the directly associated domain classes. They do not support association chain.
4.2.4 Modularity
2 we use normal font for these high-level concepts, as they may not be mapped to implementation classes.
In principle, modularity is the extent to which a software development method possesses the following five criteria [51]: decomposability, composability, understandability, continuity and protection. We first adapt these high-level criteria for the software model as follows. Decomposability is the extent to which the model facilitates the decomposition of a software
92
into smaller, sufficiently-independent modules that are connected by a simple structure. Composability is the extent to which the model facilitates construction of modules which may freely be used to produce other software. Understandability is the extent to which the model facilitates a human user in understanding a module, without having to know about other modules. Continuity is the extent to which the model facilitates making changes to a small number of modules, in response to a small change in the domain requirement. Protection is the extent to which the model facilitates localising the effect of abnormal run-time condition that occurs in a module.
Before refining these criteria further, let us first explain the remaining part of the module layer of the software model. This bottom part consists of two concepts: Module and Action. Conceptually, Module represents modules in MOSA. It has three parts: a Domain Class, a View and a set of Actions. Further, a Module may be composed from one or more other Modules. This composition relationship is mapped to the view-subview composition relationship discussed in the previous subsection. That is, the views of the component modules of a module are subviews of this module’s. Concept Action represents the view actions that are performed on a View and its Data Fields. A sub-set of the Actions have their behaviours determined by the Domain Method’s behaviour (defined in Chapter 3). The execution of one of these Actions causes the invocation of the relevant Domain Methods, each of which belongs to one Domain Class.
For example, the views of the three domain classes in Figure 4.3 belong to three modules. Module “Enrolment Management”3, in particular, is composed of two component modules. The first component module is module “Student Registration” and the second is module “Enrolment Processing”. The views of these two modules are subviews of module “Enrolment Management”. Module “Enrolment Processing” is in turn composed of two component modules. The first component module is module “Payment” and the second is module “Authorisation”. The views of these two modules are also subviews of the parent module.
3 here, we refer to the modules by their titles/labels in the figure.
Now, let us define software modularity more precisely in terms of our software model. Decomposability is the extent to which the domain classes of the UDM and the modules are constructed in the incremental, top-down fashion (e.g. by adopting the decomposition by abstraction approach [49]). Composability is the extent to which packaging domain classes into modules helps ease the task of combining them to form a new software. Understand- ability is the extent to which the module structure helps describe what a module is. Since the
93
domain class lies at the core of this structure, to understand a module requires to understand this domain class and how it relates to other parts of the module structure.
Continuity is the extent of separation of concerns supported by the module structure. This separation of concerns provides a basis for mapping the requirement to part(s) of each module structure and the interface between the modules. Using this mapping, a designer can identify which and to what extent(s) part(s) need to be updated in response to a change. As for protection, it is the extent to which the domain class behaviour and the user actions con- cerning the performance of this behaviour are encapsulated in a module. This encapsulation should include a mechanism for handling the abnormal conditions that arise from the module execution.
4.2.5 Generativity
This refers to the extent to which the software is automatically generated from the UDM, leveraging the capabilities of the target OOPL platform. The higher the generativity is, the more productive the model building process becomes.
Using the software model, we define generativity in terms of its three layers as follows. First, view generativity is the extent to which the View of a Domain Class is automatically generated. This generativity is enabled by the model reflectivity property. Second, module generativity is the extent to which a Module is automatically generated from its three components. This generativity is enabled by the structures in the domain model and module layers. Third, software generativity is the extent to which a software is automatically generated from its modules. This is enabled by the software layer’s structure, which shows how a Software is aggregated from a nonempty set of Modules.
For example, the CourseMan software shown in Figure 4.3 is generated from three modules (discussed in the previous subsection). Each module is generated from a module configuration, which specifies the configurations for the three module components. Part of this configuration is a view configuration, that is used to generate each module’s view. We will discuss our module configuration method in the remainder of this chapter.
To the best of our knowledge, the existing DDD tools support view and, to some extent,
software generativity. They do not support module generativity.
94
4.3 Module Configuration Domain
This section begins our discussion of a module configuration method that we propose to realise the module generativity sub-property of our software characterisation scheme. In this section, we focus on describing the module configuration domain, whose main aim is to configure the module class. We consider the domain’s scope to include the module configuration method of the previous work [45] (presented in Section 2.2.4) and three enhancements to this method that we will discuss in detail in this section. These enhancements help make the method more suitable for practical use and amenable to generative development. Specifically, we present in Subsections 4.3.1–4.3.2 two optimisations of and in Subsection 4.3.3 one improvement to the method. To ease discussion, we will treat module as being synonymous to module class and module objects as objects of this class.
4.3.1 One Master Module Configuration
Although it is suggested in [45] that it is possible to create more than one module configura- tions from one domain class, for ease of maintenance we propose that one ‘master’ module configuration be defined from each domain class. This configuration is used as the base for defining the configurations of all the descendant modules of the same class. In the subsequent sections, we will discuss in detail how this can be achieved.
More precisely, we assert that there is a one-one correspondence between a domain class and the master module configuration that uses that class as the model. We call this module configuration (module class) the owner module configuration (owner module class, resp.). This assertion helps simplify the containment tree definition in that a descendant node can simply refer to the domain class of the owner module (as opposed to referring to the next module object id [45]). The descendant module object is implicitly the next module object of the descendant module class.
4.3.2 The ‘Configured’ Containment Tree
An important property of our module configuration method to the designer is that it does not require her to specify the whole containment tree of a composite module. She only needs to focus on the edges, whose associated containments require customisation. Further,
95
the configuration of each of these edges only need to contain the customised values for the concerned containment.
We use the term configured containment tree to refer to the application of the configured edges to the default containment tree (generated using the procedure described in [45]). To ease discussion in the remainder of the dissertation (except for in the next section) and when it is not necessary to make a distinction with the actual containment tree, we will use the term “containment tree” to mean the configured one.
4.3.3 Customising Descendant Module Configuration
The module configuration proposed in [45] supports not only module class but also module objects of this class that are descendants in the containment tree of some composite module. However, the current configuration of these module objects includes only a customised containment scope. To achieve a complete design freedom for the descendant modules, we propose to extend the configuration to cover all three MVC components. In practice, for example, it may be necessary to make the model uneditable, to change the layout of the subview of a module object, or to alter the display type of a particular view field of the subview. We argue that this customised configuration should possess three properties. We derive these properties from those of DSL:
the custom configuration is defined in the same manner as the standard • usability:
configuration (i.e. using annotation).
• modularity: the custom configuration is captured by a separate sub-model, which is
connected to the descendant module’s configuration.
• reusability:
the custom configuration needs to reuse as many as possible the meta- concepts that are being used in other parts of the configuration to specify the same properties.
Usability is necessary to ease learning and using. Modularity is a key property of embedded DSL [36]. Reusability is essential to increasing the user’s productivity. For the sake of exposition in the dissertation, we differentiate between the descendant module objects and stand-alone module objects. The latter are those that may be executed as an independent process (typically invoked through a menu item or a tool bar button).
96
4.4 MCCL Language Specification
For the module configuration domain, we propose a horizontal aDSL named module con- figuration class language (MCCL). We present in this section the specification of this language. We first give an overview of our language specification approach. Next, we specify the language syntax using UML/OCL. After that, we briefly discuss MCCL’s semantics. We illustrate MCCL using the CourseMan modules and Java as the target OOPL.
4.4.1 Specification Approach
We adopt meta-modelling with UML/OCL (defined in Section 2.1.3) to specify both the ASM and CSM of MCCL. Because both ASM and CSM are represented as UML class models, we use the standard OOPL’s class term to refer to the meta-concepts in both models. Our aim is to construct the ASM in the annotation-based form, expressed in the OOPL’s meta-model. This allows us to take for granted the OOPL’s CSM for the MCCL’s CSM.
To construct the ASM requires three steps. In the first step, we construct a conceptual model (CM) of the domain as a UML/OCL class model. This model helps understand the overall structure, without being constrained by the target OOPL’s meta-model. The next two steps gradually transform CM into the ASM. In the second step, we transform CM into an equivalent, annotation-friendly form, called CMT . In order to produce a compact ASM, we try, in this step, to construct a compact CMT . In the third step, we then transform CMT into the actual ASM, which takes an annotation-based form specified in the OOPL’s meta- model. In this form, the configuration-related meta-concepts are represented by annotations. Further, with the model-reflectivity property in mind, we use Class and Field as the basis to structure the annotations. The module-related annotations are attached to Class, while the view field annotations are attached to Field. We call the resulted Class-based structure module configuration class (MCC).
Intuitively, each view field reflects a domain field and the MCC’s structure reflects a domain class. MCC enables us to treat module configurations as first-class objects, which helps ease development and maintenance. Further, the MCCs can easily be reused to create different software variants. To ease discussion in the remainder of this chapter, we will (unless explicitly stated otherwise) consider MCC as being synonymous with module class. In particular, we will say that module objects are objects of MCC.
97
4.4.2 Conceptual Model
Figure 4.4 shows the UML class diagram of the conceptual model (CM) of the MCCL’s domain. Class ModuleConfig represents module configuration, while classes ModelConfig, ViewConfig and ControllerConfig represent the three component configurations (resp.). The module containment tree is represented by the association from ModuleConfig to Tree. The structure consisting of Tree and three other classes, namely Node, RootNode and Edge, define a labelled, binary and rooted tree. Class Node has one attribute, named dclass, which specifies the domain class of the corresponding module. RootNode is a subtype of Node which contains an additional attribute named stateScope. This is used to specify the state scope of the corresponding module. Class Edge has two associations to Node, which clearly specify that its two Nodes play the roles of parent and child.
Figure 4.4: The CM of MCCL.
Class ViewConfig, in particular, is composed from one or more ViewFieldConfigs and, if it is the view of a composite module, then also from one or more SubviewConfigs. DataFieldConfig and SubviewConfig are sub-types of ViewFieldConfig, which repre- sent the configurations of data field and subview, respectively.
98
Class RegionConfig is a generalisation of both ViewConfig and ViewFieldConfig. Conceptually, RegionConfig represents any GUI region that forms part of a view. This can be a view field, a subview, or an entire view.
The CM contains a sub-model for customising the configuration of descendant module. This sub-model is designed with an aim to satisfy the three design properties discussed in Section 4.3.3. More specifically, the sub-model consists of four classes (ScopeConfig, ModelConfig, ControllerConfig and SubviewConfig) and four associations. The latter three classes are re-used from other parts of the CM. The first three associations are be- tween these classes and ScopeConfig. These associations are used to customise the three component configurations. The fourth association is the composition association between SubviewConfig and ViewFieldConfig. This association is used to customise the configu- rations of the view fields of the descendant module’s view. The entire sub-model is connected to class Edge via the association between this class and ScopeConfig. This associates every customised configuration to a containment edge.
To ease the introduction of other configuration properties in the future, we use PropertySet and Property. The former is composed of the latter and is referenced by ModelConfig, ControllerConfig and RegionConfig.
Well-formedness Rules
We use OCL invariant to precisely express the well-formedness rules of the CM. We group the rules by the meta-concepts of the CM to which they are applied. Each rule includes a header comment that describes, in natural language, what the rule means. The rule definitions use a number of shared (library) rules, which we provide in Appendix B.1.
Syntactically, some rules use DCSL to express constraints on certain meta-concepts’ attributes. There are two reasons for this. First, it is possible to apply DCSL to the CM in Figure 4.4, because this model contains only the elements that are mappable directly to those expressible by DCSL. Specifically, it includes only class, field, one-one and one-many associations, and generalisation. Second, it is more compact and intuitive to write rules in DCSL, where applicable. For instance, the OCL expression name.Unique in rule R1 (discussed shortly below) is shorter and easier to grasp than the equivalent, but lengthy, OCL rule describing the fact that attribute ModuleConfig.name is unique (i.e. its values are distinct among all the ModuleConfig objects).
99
Module Configuration
Rules R1–R4 define the structural constraints concerning ModuleConfig. The first two rules are written using these two DCSL constraints: Optional and Unique. The third rule states that the containment tree must not be specified for non-composite modules. The last rule ensures that a containment tree’s nodes refer to the domain classes of the referenced descendant modules.
1 -- ModuleConfig . name is mandatory and unique 2 context ModuleConfig inv :
3
not ( name . Optional ) and name . Unique
R1
1 -- ModuleConfig . view may not be specified ( e . g . for non - view modules ) 2 context ModuleConfig inv : view . Optional
R2
1 -- ModuleConfig . contTree of non - composite module is not defined 2 context ModuleConfig inv :
3
not ( isComposite () ) implies contTree . oclIsUndefined ()
R3
1 -- If ModuleConfigure . contTree is defined then its nodes must 2 -- refer to the domain classes of the descendant modules 3 context ModuleConfig inv :
4
not ( contTree . oclIsUndefined () ) implies descMods () -> notEmpty () and
5
contTree . nodes - > forall ( n |
6
descMods () -> exists ( model . domainClass = n . dclass ) )
R4
Containment Tree
1 -- Tree has at least one node 2 context Tree inv : nodes - > notEmpty ()
Rules R5–R10 define a valid containment Tree. In particular, rules R8 and R9 enforce that Tree really is a connected and acyclic graph. On the other hand, rule R6 ensures that Tree is rooted. Rule R7 states that every Edge of a Tree connect two Nodes of that tree. Rule R10 states that Nodes reference only domain classes and do so via the attribute Node.dclass. R5
100
1 -- The root Node is among the nodes 2 context Tree inv : nodes - > select ( n | n = root ) -> size () =1
R6
1 -- Every Edge connects some two nodes of the Tree 2 context Tree inv :
3
edges - > forAll ( e | nodes - > includes ( e . parent ) and nodes - > includes ( e . child ) )
R7
1 -- ( Acyclicity ) No two edges have the same child 2 context Tree inv : edges - > forAll ( e1 , e2 | e1 . child <> e2 . child )
R8
1 -- ( Connectedness ) There exists a path connecting any pair of two nodes 2 context Tree inv : nodes - > forAll ( n1 , n2 | hasPath ( n1 , n2 ) )
R9
1 -- Node . dclass is a domain class ( if specified ) 2 context Node inv :
3
not ( domainClass . oclIsUndefined () ) implies dclass . isDomainClass ()
R10
Model Configuration
A primary constraint for ModelConfig states that it must refer to an actual domain class (as per the DCSL’s definition).
1 -- ModelConfig . domainClass must be a domain class 2 context ModelConfig inv :
3
not ( domainClass . oclIsUndefined () ) and domainClass . isDomainClass ()
R11
Controller Configuration
1 -- ControllerConfig . ctrlClass must be assignment compatible to Controller 2 context ControllerConfig inv :
3
not ( ctrlClass . oclIsUndefined () ) and ctrlClass . oclIsKindOf ( Controller )
As for ControllerConfig, it must specify either Controller or a subtype as the controller. R12
101
View Configuration
Rules R13– R15 state three primary constraints concerning view configuration. Rules R13 and R14 regulate the ViewConfig’s structure. Rule R15 ensures the structural consistency between the containment scope specifications of a containment tree and the view configu- rations of the descendant modules. We will use rules R14 and R15 later in Section 4.5.1 to define the structural consistency property that holds between MCC and domain class.
1 -- ViewConfig . displayClass must be assignment compatible to View 2 context ViewConfig inv :
3
not ( displayClass . oclIsUndefined () )
4
and displayClass . oclIsKindOf ( View )
R13
1 -- Every ViewFieldConfig in ViewConfig . fldCfg must have its name set to 2 -- either ‘ title ’ or name of a domain field of the module ’ s domain class 3 -- that it reflects AND there is exactly one field named ‘ title ’ 4 context ViewConfig inv :
5
fldCfg - > forAll ( f | f . name = ‘ title ’ or
6
module . model . domainClass . domFields () -> exists ( d | d . name = f . name ) )
7
8
and fldCfg - > forAll ( name = ‘ title ’) -> size () = 1
R14
1 -- all containment scope values in a ModuleConfig . contTree contain valid 2 -- view field names in ViewConfigs of the corresp . descendant modules 3 context ModuleConfig inv :
4
not ( contTree . oclIsUndefined () ) implies
5
contTree . getContScopes () -> forAll ( Tuple (n , s ) |
6
Tk :: parseContScope ( s ) -> forAll ( t |
7
getDescModuleOf ( n ) . view . fldCfg - > exists ( name = t ) )
8
)
R15
Subview Configuration
Rules R16– R19 make explicitly clear the two usages of SubviewConfig in the overall ViewConfig’s structure. Rule R16 states these two usages. The subsequent rules give specific details for each usage. Rule R17 enforces that the SubviewConfig that is not used in customising a descendant module must not contain any ViewFieldConfigs.
102
Rules R18 and R19 together express the constraints for the second usage.
In this, a SubviewConfig does contain some ViewFieldConfigs and these configurations must be structurally valid.
4
1 -- A SubviewConfig must either be part of a ViewConfig or 2 -- have its scope specified but not both 3 context SubviewConfig inv : view . oclIsUndefined ()
5
xor scope . oclIsUndefined ()
R16
4
1 -- A SubviewConfig that is part of ViewConfig must 2 -- have its custFldCfg unspecified . 3 context SubviewConfig inv : not ( view . oclIsUndefined )
5
implies custFldCfg - > isEmpty ()
R17
1 -- A SubviewConfig that has its scope specified must 2 -- have its custFldCfg specified . 3 context SubviewConfig inv :
4
not ( scope . oclIsUndefined )
5
implies custFldCfg - > notEmpty ()
R18
1 -- In every SubviewConfig u that has its scope specified , every 2 -- ViewFieldConfig f in u . custFieldCfg must have f . name set to the name of 3 -- a domain field of the domain class specified by scope . edge . child . dclass 4 context SubviewConfig inv :
5
6
not ( scope . oclIsUndefined () ) implies
7
custFldCfg - > forAll ( f |
8
scope . edge . child . dclass . domFields () -> exists ( name = f . name ) )
R19
Data Field Configuration
1 -- clazz is compatible to the referenced domain class of the 2 -- corresponding domain field of the module ’ s domain class . 3 context DataFieldConfig inv :
4
clazz . oclIsTypeOf ( view . module . model . domainClass . getDomField ( name ) . type )
R20
103
1 -- boundAttrs is a comma - separated string of domain field names of the 2 -- referenced domain class of the bounded domain field . 3 context DataFieldConfig inv :
4
5
let b : String = boundAttrs in b . size () > 0 implies
6
7
8
9
b . indexOf ( ‘ , ’) > 0 and let attrs : Set ( String ) = Tk :: splitStr (b , ‘ , ’) in attrs . size () > 0 and attrs - > forAll ( s | view . module . model . domainClass . getDomField ( name ) . type .
domFields () -> exists ( name = s ) )
R21
Scope Configuration
1 -- stateScope is a comma - separated string of domain field names of this 2 -- referenced domain class : edge . child . dclass 3 context ScopeConfig inv :
4
not ( stateScope . oclIsUndefined ) and stateScope . size () > 0 implies
5
6
7
8
stateScope . indexOf ( ‘ , ’) > 0 and let attrs : Set ( String ) = Tk :: splitStr ( stateScope , ‘ , ’) in attrs . size () > 0 and attrs - > forAll ( s | edge . child . dclass . domFields () -> exists ( name = s ) )
R22
4.4.3 Abstract Syntax
Our main objective is to construct an ASM from the CM by transformation, so that the ASM takes the annotation-based form, suitable for being embedded into a host OOPL. Furthermore, we will strive for a compact ASM that uses a small set of annotations. From the practical standpoint, such a model is desirable since it will result in a compact concrete syntax, which requires less effort from the language user to construct an MCC. To achieve this requires two steps. First, we transform CM into another model, called CMT , that is compact and suitable for annotation-based representation. Second, we transform CMT into the actual annotation-based ASM. We first explain CMT and the transformation CM → CMT . After that, we explain the ASM.
104
Figure 4.5: (A-shaded area) The transformed CM (CMT ); (B-remainder) Detailed design of the key classes of CMT .
CMT : A Compact and Annotation-Friendly Model
Figure 4.5 (A) shows the UML class model of CMT . The detailed design of the key classes are shown in Figure 4.5 (B). To ease our discussion later about the annotation-based ASM, we add to the figure the default value notation of the optional domain field (i.e. field with DAttr.optional = true). The default value is written within a pair of brackets that imme- diately follow the field’s data type.
As shown in Figure 4.5 (A), class ModuleDesc represents the overall module configura- tion, while class AttributeDesc represents the view field configuration. Class ModuleDesc has associations to the following three classes that specify the three component configura- tions: ModelDesc, ViewDesc and ControllerDesc. In addition, class ModuleDesc has an association to CTree, which specifies the containment tree configuration.
The structure Tree-Node-RootNode-Edge of the CM is replaced by CTree-CEdge in CMT . This structure is more compact and fits naturally with the idea of the configured containment tree (see Section 4.3.2). That is, instead of specifying the whole tree the designer only configures the customised edges. Class CEdge has two attributes, parent and child, that specify the dclasses of the parent and child Nodes of an Edge in the CM. CEdge is also associated to the ScopeDesc class, which is mapped to CM’s ScopeConfig class.
105
Well-formedness Rules of CTree
1 -- no edge can have root as its child
2
context CTree inv :
3
edges - > forAll ( child <> root )
We present below the OCL invariants on CTree that form the well-formedness rules of the new CTree representation. Rule R23 ensures that CTree has a distinguished root. Rules R24– R25 state the acyclicity and connectedness properties of CTree. These rules make use of two library functions named nodeClasses and hasPath. These functions are defined in rules R26 and R27 (resp.). R23
1 -- Acyclicity : no two edges have the same child
2
context CTree inv :
3
edges - > forAll ( e1 , e2 | e1 . child <> e2 . child )
R24
3
1 -- Connectedness : there exists at least one path from root to 2 -- every ’ node - class ’ context CTree inv :
4
nodeClasses ( edges ) -> forAll ( c1 , c2 | hasPath ( c1 , c2 ) )
R25
1
2
3
4
context CTree -- returns node classes ( i . e . domain classes of the nodes ) of the edges def : nodeClasses () : Set ( Class ) = edges - > collect ( parent ) . asSet ()
5
-> union ( edges - > collect ( child ) . asSet () )
R26
1
2
3
4
5
context CTree -- determines if there is a path ( i . e . a sequence of CEdges ) that -- connect two node - classes c1 to c2 ( in either direction ) def : hasPath ( c1 : Class , c2 : Class ) : Boolean = edges - > exists (( parent = c1 and child = c2 ) or
6
( parent = c2 and child = c1 ) )
7
8
or edges - > exists ( e | hasPath ( c1 , e . parent ) and hasPath ( e . parent , c2 ) )
R27
106
Mapping from CM to CMT
Table 4.1: Mapping from CM to CMT
Map#
M1
CMT (ModuleDesc, ModelDesc, ViewDesc, ControllerDesc)
ScopeDesc
M2
Select, (ViewFieldConfig, Select)
M3
(ViewDesc, AttributeDesc)
M4
Property
M5
(ModelDesc, PropertyDesc)
M6
(ControllerDesc, PropertyDesc)
M7
M8
(ViewDesc, PropertyDesc), (AttributeDesc, PropertyDesc) CTree CEdge (ModuleDesc, CTree) (CTree,CEdge)
M9 M10 M11 M12
-
M13
CM (ModuleConfig, ModelConfig, ViewConfig, ControllerConfig) (RegionConfig, ViewFieldConfig, SubviewConfig, ScopeConfig) DataFieldConfig.clazz, boundAttrs (RegionConfig, ViewConfig, ViewFieldConfig, DataFieldConfig) PropertyDesc (ModelConfig, PropertySet, Property) (ControllerConfig, PropertySet, Property) (RegionConfig, PropertySet, Property) (Tree, RootNode) Edge, (Edge, Node) (ModuleConfig, Tree) (Tree, Edge) RegionConfig, SubviewConfig, DataFieldConfig, PropertySet, Node, RootNode
Table 4.1 defines the precise mapping CM 7→ CMT , which consists of a set of thirteen labelled mapping rules. One or a combination of mapping rules map a (source) sub-model of the CM to a corresponding (target) sub-model of CMT . To reduce the size of CMT , we make sure that no target sub-model is larger than the source and, more importantly, that each target sub-model is optimised for size. Fortunately, we could achieve this for each sub-model mapping using only a few basic class model transformations. We explain these directly in the text below.
Specifically, mapping rule M1 maps the sub-model concerning the overall module config- uration structure. This includes the correspondences between two sets of classes: X Configs (X ∈ {Module, Model, View, Controller}) and X Descs, and the relevant associations that associate these classes. The correspondences are primarily to do with renaming the meta-concepts.
107
Three mapping rules M2-M4 map the view-related sub-model. This sub-model consists of the following five classes and the relevant associations among them: RegionConfig, ViewConfig, ViewFieldConfig, DataFieldConfig and SubviewConfig. Conceptually, these rules break the type hierarchy in the sub-model (which is not going to be supported by annotation) and condense it to a sub-model consisting of four classes: ViewDesc, AttributeDesc, Select and ScopeDesc. First, we systematically push all attributes of each supertype down to its subtypes. Second, we remove the top-most supertype (RegionConfig), which is no longer needed. Third, we remove the two leaf subtypes by performing two merges. The first is to merge SubviewConfig into ScopeConfig (due to the one-one association be- tween the two classes). The second is to merge DataFieldConfig into ViewFieldConfig, while separating its two attributes into a new class, named Select. As can be seen in M3, this adds a new one-one association between ViewFieldConfig and Select. Finally, we rename ScopeConfig and ViewFieldConfig to ScopeDesc and AttributeDesc (resp.). The next four rules, M5-M8, handle the sub-model consisting of two classes: Property and PropertySet. The main idea is to remove PropertySet and instead use Property to perform the roles of PropertySet in the model. Rule M5 maps Property directly to PropertyDesc, while the other three rules effectively replace PropertySet by suit- able associations between PropertyDesc and the relevant Y Desc classes (Y ∈ {Model, Controller, Region}), whose corresponding Y Config classes in the CM have associa- tions to PropertySet.
The subsequent four mapping rules, M9–M12, handle the containment tree sub-model. As explained earlier, the objectives here are twofold: to make the sub-model more compact and fit better with the idea of the configured containment tree. Rule M9 takes advantage of the one-one association between Tree and RootNode to combine them into CTree. This involves removing RootNode and adding its two attributes to CTree. Then, for clarity, we rename attribute CTree.dclass to CTree.root. Similarly, rule M10 takes advantage of the two one-one associations between Edge and Node to combine them into CEdge. The other two rules, M11-M12, straight-forwardly take care of the two associations that associate Tree with ModuleConfig and Edge.
The last rule M13 makes explicit the six classes in the CM that have been replaced (as
part of the aforementioned mappings) and are no longer in CMT .
108
The Annotation-Based ASM
Although CMT is suitable for OOPL’s rep- resentation, it is still not yet natively in that form. Our next step, therefore, is to trans- form it into the actual ASM of the language that is “embedded” in OOPL. This ASM is constructed from the following four OOPL meta-concepts that were discussed in Sec- tion 2.1.7: Class, Field, Annotation and Property.
Figure 4.6: The annotation-based ASM.
Figure 4.6 shows the UML class model of the ASM. In this, the classes in CMT are transformed into annotations of the same name. Each domain field is transformed into an annotation property. The annotations are depicted in the figure as grey-coloured boxes. The grey, dashed association lines between the annotations are used merely as a visual aid to relate the overall ASM’s structure to the corresponding associations in CMT .
A key structural difference between ASM and CMT is the addition of two annotation attachments: ModuleDesc to Class and AttributeDesc to Field. These are represented in Figure 4.6 by solid lines connecting the corresponding class boxes. A ModuleDesc attachment defines an MCC because it describes the instantiation of a ModuleDesc object together with objects of the annotations that are referenced directly and indirectly by ModuleDesc. The association between Class and Field in the figure helps realise the composite association between ViewDesc and AttributeDesc. The reason is that there is a one-one association between ModuleDesc and ViewDesc and, thus, associating ModuleDesc to Class leads to ViewDesc being associated to it. The Fields that make up a Class together with the AttributeDescs of these fields constitute the view field configurations of the ViewDesc attached to that Class.
109
Together, the above features lead us to the following definition of MCC and view field.
Definition 4.1. An MCC is a class assigned with a suitable ModuleDesc, that defines the configuration of a module class owning a domain class in the UDM. Further, the MCC’s body consists of a set of fields that are assigned with suitable AttributeDescs. These fields realise the view fields. Exactly one of these fields, called the title data field, has its AttributeDesc defines the configuration of the title of the module’s view. Other fields have the same declarations as the domain fields of the domain class and have their AttributeDescs define the view-specific configuration of these domain fields.
We say that a view field reflects the corresponding domain field. To ease discussion, we
will say that the MCC of a module class owns its domain class.
If an MCC defines a module class configuration for the owner module of a domain class, then we need a set of MCCs to define the configurations for all the owner modules of the domain classes in a UDM. This set of MCCs forms what we term an MCC model.
Definition 4.2. An MCC model w.r.t a UDM is an MCCL model that consists in a set of MCCs, each of which configures the owner module of a domain class in the UDM.
4.4.4 Concrete Syntax
Because MCCL is embedded into OOPL, it is natural to consider the OOPL’s textual syntax as the concrete syntax of MCCL. From the perspective of concrete syntax meta-modelling approach [39], the CSM of such textual syntax is derived from that of OOPL. Further, the core structure of the CSM model is mapped to the ASM. In addition to this core structure, the CSM contains meta-concepts that describe the structure of the BNF grammar rules. The textual syntaxes of Java and C# are both described using this grammar.
In this dissertation, we will adopt the Java textual syntax as the concrete syntax of MCCL. The following example will illustrate this syntax using the MCCs of two CourseMan software modules that we discussed in the example of Section 2.2.4.
Example 4.1. (ModuleStudent) Let us consider the MCC of ModuleStudent shown in Listing 4.1. The resulted module’s view is presented in Figure 4.7.
110
is header The MCC’s
It specifies that
The view of a (stand-alone)
Figure 4.7: ModuleStudent object.
assigned with a ModuleDesc element, which defines the overall module configura- the module’s tion. name is “ModuleStudent”, the refer- enced ModelDesc specifies the domain class Student, the referenced ViewDesc the view (e.g. with the ti- specifies tle “Manage Students”), the referenced ControllerDesc specifies the controller class to Controller and that the object opening policy is the one named I_C.
4
1 @ ModuleDesc ( name = " ModuleStudent " , 2 modelDesc = @ ModelDesc ( model = Student . class ) , 3 viewDesc = @ ViewDesc ( formTitle = " Manage Students " , imageIcon = " student . jpg " , view = View . class , parentMenu = RegionName . Tools , topX =0.5 , topY =0.0) ,
5 controllerDesc = @ ControllerDesc ( controller = Controller . class ,
6
openPolicy = OpenPolicy . I_C ) ,
8
7 containmentTree = @CTree ( root = Student . class , stateScope ={ " id " ," name " ," modules " }) )
9 public class ModuleStudent {
10
11
@ AttributeDesc ( label = " Student " ) private String title ;
12
13
14
@ AttributeDesc ( label = " Id " , type = JTextField . class , alignX = AlignmentX . Center ) private int id ;
15
16
17
@ AttributeDesc ( label = " Full name " , type = JTextField . class ) private String name ;
18
19
20
@ AttributeDesc ( label = " Needs help ? " , type = JBooleanField . class ) private boolean helpRequested ;
21
22
23
24
25
@ AttributeDesc ( label = " Enrols Into " , type = JListField . class , ref = @Select ( clazz = CourseModule . class , attributes ={ " name " }) , width =100 , height =5) private Set < CourseModule > modules ;
26 }
Listing 4.1: The MCC of ModuleStudent
111
Note that the ViewDesc element in Listing 4.1 is specified with a property named parentMenu. This property is supported by jDomainApp, which, if configured, will create in the specified menu of the software GUI a menu item for executing the module. This menu item is the primary means through which the user accesses a module. Since this property is not intrinsic to MCCL, it will be omitted from discussion in the remainder of this dissertation. The referenced CTree of ModuleDesc specifies that the descendent module owning Student has the containment scope containing just three attributes (namely id, name and modules). It excludes the domain field Student.helpRequested. In the next example, we will explain how ModuleStudent is reused to create another ModuleStudent object that is a descendant of ModuleEnrolmentMgmt. The subview of this object is customised to contain data fields for all four Student’s domain fields.
The MCC’s body contains five view fields, each of which is assigned with an AttributeDesc
element. All five view fields are data fields. The first configuration specifies the data field that presents the view’s title text. The remaining four configurations specify the data fields that are labelled (via property AttributeDesc.label) “Id”, “Full Name”, “Needs help?” and “Enrols Into”. These reflect the following four domain fields of Student: id, name, helpRequested and modules (resp.). The data fields are configured (using prop- erty AttributeDesc.type) with a specific display class type. Specifically, the display class types of the four data fields are JTextField, JTextField, JBooleanField and JListField (resp.). If omitted, the display class type of a data field will be derived automatically from the domain field’s data type. For instance, property AttributeDesc.type can be omitted from the configuration of the first three data fields.
The data field modules is configured with AttributeDesc.ref.attributes = { “name” }. This means that this data field is to display values of the domain field CourseModule.name. Indeed, Figure 4.7 shows how the data field (which is labelled “Enrols Into”) displays the names of three CourseModules (“IPG”, “PPL” and “SEG”) that are currently in the system. These values are easier for the user to comprehend than those of the identifier attribute CourseModule.code.
Example 4.2. (ModuleEnrolmentMgmt)
1
2
3
@ ModuleDesc ( name = " M oduleEnro lmentMg mt " , // other configuration elements ( omitted ) containmentTree = @CTree ( root = EnrolmentMgmt . class ,
Listing 4.2: The containment tree of ModuleEnrolmentMgmt
112
4
edges ={
5
6
7
// enrolmentmgmt -> student @CEdge ( parent = EnrolmentMgmt . class , child = Student . class , scopeDesc = @ ScopeDesc (
8
9
10
stateScope ={ " id " , " name " , " helpRequested " , " modules " } , // custom configuration for ModuleStudent attribDescs ={ // Student . id , name are both presented by JLabelField
11
12
@ AttributeDesc ( id = " id " , type = JLabelField . class ) @ AttributeDesc ( id = " name " , type = JLabelField . class , editable = false )
13
}) ) }
14
) )
15
public class Mod uleEnr olmentMgmt {
16
// view field configurations ( omitted )
17
}
Listing 4.2 shows a partial MCC of ModuleEnrolmentMgmt that contains just the containment tree (the complete MCC is given in Listing B.2 of Appendix B.2). The ModuleEnrolmentMgmt’s view is shown in Figure 4.8. We will focus on explain- ing the customisation of descendant mod- ule configuration.
4.8: The customised
Figure view of ModuleEnrolmentMgmt (as configured in List- ing 4.2).
Specifically, the containment tree spec- ifies the customisation of a descendant module object of ModuleEnrolmentMgmt. This object (typed ModuleStudent) is a child module and its customised configu- ration is specified in the CEdge listed at lines 6–15. The containment scope (line 8) specifies all four domain fields of Student. The attribDescs property (lines 10–15) specifies a customised configuration for two data fields of ModuleStudent that reflect Student.name and id. This configuration states that both data fields are presented by a view field class called JLabelField. In addition, we add, only for illustration purpose, the configuration editable = false in the data field for Student.name. This means that this data field is to be displayed as read-only, although technically in this case this configuration is redundant due to the use of JLabelField.
113
4.4.5 Semantics
Although in principle the well-formedness rules presented earlier in Sections 4.4.2 and 4.4.3 form part of the static semantics of MCCL, we have not discussed what this semantics is. Con- ceptually, we observe that the overall semantic structure of MCCL can be described relatively with ease by adapting the translational semantic specification approach (see Section 2.1.3). We take advantage of the fact that DCSL’s semantics has been defined (see Chapter 3) and use this as the target language for the translation. We translate the MCCL’s ASM into a DCSL model using the mapping rules that were defined in Table 2.1. These mappings are applicable because, similar to the CourseMan domain model (see Section 3.3), the ASM is an UML/OCL model that contains only the elements that are expressible in DCSL.
4.5 MCC Generation
Because an MCC has a structurally close relationship to its domain class, it needs to be managed effectively in order to ensure that this structural relationship is preserved when the domain class as well as the MCC evolve. Further, in order to reduce the effort needed to construct the MCCs for a particular software, the MCC management mechanism should incorporate some form of automation. In this section, we discuss a key MCC management function, named MCCGen, that is responsible for automatically generating an MCC from the domain class. This function forms part of the MCCL’s toolkit that is provided for the language users.
It is worth mentioning that, for completeness, we have defined other MCC management In the interest of
functions in another paper (paper 6 listed in the Publications section.). space, however, we will not discuss these functions in this dissertation.
4.5.1 Structural Consistency between MCC and Domain Class
Before discussing MCCGen, let us state a property about the validity of MCC. Because MCC reflects its domain class, the validity of an MCC is described by a structural consistency between it and the domain class. The following definition makes clear what this means for MCCs and, more generally, for the overall MCC model of a software.
114
Definition 4.3 (Structural Consistency). The owner MCC of a domain class is structurally consistent with that class if it satisfies the following conditions:
(i) (Rule R14 of MCCL’s CM) the MCC’s body consists of only the title data field and the view fields that reflect the domain fields of the domain class
(ii) (Rule R15 of MCCL’s CM) every reference to a domain field name in the containment tree specified by ModuleDesc.containmentTree of the MCC is a valid field name either of the domain class or of one of the domain classes of a descendant module in the actual containment tree
A non-owner MCC is structurally consistent with a domain class if it satisfies condition (ii). An MCC model is structurally consistent with a domain class if all of its MCCs are structurally consistent with that class.
It follows rather immediately from Definition 4.3 that our module class design satisfies the model reflectivity property (discussed in Section 4.2.3) of the software characterisation scheme.
Proposition 4.1. The module class induced by an MCC satisfies the model reflectivity property defined in Section 4.2.3. That is, the module’s view reflects the structure of the domain class that is owned by the module.
Let us illustrate Proposition 4.1 using the software GUI shown in Figure 4.3. As can be seen from the figure, each module’s view directly reflects the structure of its domain class. We explain this using two examples of non-associative and associative fields. The view field ViewhStudent.idi, which is the field labelled Id of ViewhStudenti, is a data field that reflects the non-associative domain field Student.id.
As for associative field, the view structure reflects association chains of any length through the multi-level view-subview containment. An association chain is realised by the associative fields of the participating domain classes. For example, the view field ViewhEnrolmentMgmt.enrolProcsi is a subview (of ViewhEnrolmentMgmti) that reflects the associative field EnrolmentMgmt.enrolProcs. This subview itself contains two smaller subviews, which reflect two associative fields between EnrolmentProcessing and Payment and Authorisation. If any of these two classes were to contain associative fields, then we could observe further subviews being created to realise them.
115
4.5.2 MCCGEN Algorithm
We present in Alg. 4.1 the algorithm for the MCC generation function, named MCCGen. This function takes as input a domain class (c) and generates as output the ‘default’ owner MCC (m) of that class. By ‘default’ we mean the generated MCC contains the default values for all the essential annotation properties. To ease comprehension, we insert comments at the key locations to help explain the algorithm. Specifically, Alg. 4.1 consists of three main
// STEP 1: create m’s header
1 nc ⇐ c.name, nm = “Module" + nc 2 m ⇐ Class(visibility=“public",name=nm)
// STEP 2: create m’s ModuleDesc
3 do ⇐ ModelDesc(model=c) 4 dv ⇐ ViewDesc(formTitle=“Form: "+nc,domainClassLabel=nc, imageIcon=nc+“.png",view=View) // (cid:182) 5 dc ⇐ ControllerDesc() 6 dm ⇐ ModuleDesc(m):modelDesc=do, viewDesc=dv, controllerDesc=dc // (cid:183)
// STEP 3: create m’s view fields (i.e. view field configs)
// c’s domain fields
7 fd ⇐ Field(class=m, visibility=“private",name=“title", type=String) // title 8 create AttributeDesc(fd):label=nc // (cid:184) 9 cF ⇐ {f | f : Domain Field, f ∈ c.fields} 10 AddViewFields(m, cF ) // create a view field to reflect each c’s domain field 11 return m
12 Function AddViewFields(Class m, SethFieldi F ): 13 for all f in F do 14 nf ⇐ f .name, tf ⇐ f .type 15 16
fd ⇐ Field(class=m,visibility=“private", name=nf ,type=tf ) create AttributeDesc(fd):label=nf // (cid:185)
Alg.4.1 MCCGen Input: c: Domain Class Output: m: MCC
steps, which are labelled “STEP 1”–“STEP 3” in three comments. In step 1, the MCC header In particular, the class name includes the prefix ‘Module’ combined with the is created. domain class’s name. In step 2, three configuration component elements of the MCC (do, dv, dc) are created first, then the ModuleDesc element (dm) is created from them.
In step 3, the view fields are created in the MCC’s body. The first view field (fd) is the title field. Other view fields are created for the domain fields (set cF ) of c. Since this is a shared procedure, we define it as a function named AddViewFields. This function, which is displayed at the bottom of Alg. 4.1, basically consists in a for loop that iterates over the input domain field set (F ) to extract the name and data type of each field (f ) and use these to create a corresponding view field (fd) in the output class (MCC m). The AttributeDesc of each view field has its label property set to name of the corresponding data field (label=nf ). Note in Alg. 4.1 that the parts labelled (cid:182)–(cid:185) contain properties which may need to be
116
customised to suite the domain requirements. This customisation concerns module-specific changes. More specifically, part (cid:182) includes changes to view-related properties, such as title, label and icon, and other properties discussed in Section 4.4.2. For example, if the module is not supposed to have a view then property ViewDesc.view needs to be changed from View to Null. Part (cid:183) includes changes to the overall module configuration. For instance, if the module is composite then property ModuleDesc.containmentTree would be set to a suitable CTree. Parts (cid:184) and (cid:185) entail changes (via annotation AttributeDesc) to view configuration of the data fields representing the title and domain fields of the domain class.
Example 4.3. (Generating ModuleEnrolmentMgmt) Listing 4.3 shows the owner MCC ModuleEnrolmentMgmt of EnrolmentMgmt, which is generated by MCCGen. The model In the view configura- configuration specifies that the domain class is EnrolmentMgmt. tion, the values of the ViewDesc’s properties are set to the default values. For instance, formTitle and imageIcon are constructed directly from the domain class’s name. The de- signer would customise these values to suite the domain. In particular, formTitle would be changed to a more user-friendly label, such as “Manage Enrolments”. The default controller configuration requires no property value specification. The containment tree is the (actual) automatically-generated tree. The designer would customise this tree for some descendant modules of interest. An example of such customisation was described in Example 4.2.
The MCC’s body contains the declarations of five view fields. The labels of these fields take the default values, which are the same as the field names. These labels would be customised to contain user-friendly texts. An example configuration of these fields is shown in Listing B.1 of Appendix B.2.
1
2
3
@ ModuleDesc ( name = " M odul eE nrolmen tMgmt " , modelDesc = @ ModelDesc ( model = EnrolmentMgmt . class ) , viewDesc = @ ViewDesc ( formTitle = " Form : EnrolmentMgmt " ,
4
5
imageIcon = " EnrolmentMgmt . png " , domainClassLabel = " EnrolmentMgmt " , view = View . class ) ,
6
7
8
9
controllerDesc = @ ControllerDesc () ) public class Mod uleEnr olmentM gmt { @ AttributeDesc ( label = " title " ) private String title ;
10
11
12
@ AttributeDesc ( label = " id " ) private int id ;
13
Listing 4.3: The ‘default’ ModuleEnrolmentMgmt produced by MCCGen
117
14
15
@ AttributeDesc ( label = " students " ) private Set < Student > students ;
16
17
18
@ AttributeDesc ( label = " helpDesks " ) private List < HelpRequest > helpDesks ;
19
20
21
@ AttributeDesc ( label = " sclassRegists " ) private Collection < SClassRegistration > sclassRegists ;
22
}
4.6 Summary
In this chapter, we presented a module-based approach for constructing software from the UDM. We first characterised the software in terms of four essential properties. Two of these properties (instance-based GUI and model reflectivity) arised specifically from the need to construct software from the UDM. The other two properties (modularity and generativity) were derived from well-known design properties. After that, we focused on a key step in software development, which concerns creating software modules from the UDM. Taking the view that a module is an object of a module class and that this class is constructed from three component classes (model, view and controller) and a module configuration, we defined an aDSL named MCCL for defining the module configuration classes (MCCs). We specified the ASM and CSM of MCCL using UML/OCL class diagrams and discussed the language semantics. Futhermore, to ease the construction of MCC, we presented an algorithm (MCCGen) for automatically generating the owner MCC of a domain class.
We argue that MCCL helps treat module configurations as first-class objects, making their development and maintenance easier. Further, the MCCs are reusable to create different software variants. But to what extent does MCCL and MCCGen help to achieve the aim of module-based software construction? The answer will come in the next chapter when we evaluate the technical contributions of the dissertation.
The content of this chapter is published in the following papers (listed in the Publications section). The software characterisation scheme is published in the SCIE journal paper 4. MCCL and the associated generator are published in two conference papers 3 and 5 and in the SCIE journal paper 6.
118
Chapter 5
Evaluation
In this chapter, we present our evaluation of the contributions made in this dissertation. We first describe an implementation of the research contributions as components in the jDomainApp framework. We then describe a real-world software development case study which we have developed using the implemented components. After that, we present two separate evaluations: one is for DCSL and the other is for module-based software construction with MCCL. We conclude each evaluation with a number of discussion points.
5.1
Implementation
In order to evaluate our claims about UD modelling and module-based software construction and to ease the adoption of our contributions in developing real-world software projects, we implemented DCSL, MCCL and the generators and tools associated with these aDSLs as components of the jDomainApp framework. The implementation language is Java version 8. In addition, we use a number of third-party libraries to handle basic language manipulation tasks. To ease discussion, we will refer to the UDM generally as “domain model”.
5.1.1 UD Modelling
Because DCSL plays the central role in our method, we implemented this language as part of the modelling component of jDomainApp. As for the BSpaceGen function, we implemented it as an add-on component of jDomainApp. Developers who wish to use this component would import it into their projects as a library.
119
Our implementation uses the following core third-party libraries:
– JavaParser [73]: to parse the Java code model of the domain model into a syntax tree
for manipulation
– Eclipse’s libraries for OCL [30] and EMF [21]: to generate and validate the OCL pre-
and post-conditions of the domain methods
A documentation of our implementation together with its demonstration with the Course- Man example is available online1. In this document, we also describe how to generate and execute the CourseMan software examples of the UDM patterns discussed in Section 3.6.2. Further, we implemented a software tool, named DomainAppTool, whose aims are two- fold: (i) to enable the use of DCSL in developing the domain model and (ii) to provide a basic level of support for the three phases of the DDDAL method. In principle, the tool takes as input a (possibly incomplete) domain model and automatically generates a set of software modules and a GUI-based software composing of these modules. For this reason, the tool can be used in early development runs of the DDDAL method to construct the domain model.
Specifically, DomainAppTool enables the three key stakeholders of the DDDAL process to collaboratively and iteratively build a domain model. The designer uses the tool to iteratively work with the domain expert to capture the domain requirements in the model. The programmer participates in the iterations by initially coding the domain model in DCSL and subsequently updating it, based on changes to the requirements that she has received from the domain expert. The model is processed automatically by the tool to generate the software.
In each iteration, the tool automatically generates an interactive software prototype directly from the domain model. This software’s GUI shows an object form that realises a module’s view and a desktop for organising these forms. The object form provides an interface for the user to view and to manipulate the domain objects of a domain class. For example, Figure 5.1 shows a partial software GUI of CourseMan, which is generated by the tool. It includes object forms for three domain classes: Student, SClass and SClassRegistration.
1 https://github.com/vnu-dse/dcsl 2 http://fit.hanu.vn
We have been using DCSL and DomainAppTool to teach in a software engineering course module at the Faculty of IT2, Hanoi University. In teaching, students and teachers play the stakeholders’ roles.
120
Figure 5.1: A partial CourseMan’s GUI that is generated by DomainAppTool.
5.1.2 Module-Based Software Construction
3 https://github.com/vnu-dse/mccl
We implemented MCCL as part of the module modelling component of jDomainApp. We implemented MCCGen as an add-on component of jDomainApp. This implementation also uses JavaParser to parse an MCC into a syntax tree for manipulation. A documentation of our implementation and a demonstration with the CourseMan example is available online 3. In addition to MCCGen, we also implemented a software generator in jDomainApp. This generator generalises the functionality provided by DomainAppTool. It basically takes as input a set of MCCs that are defined from a domain model and generates as output a software. We use this software generator to generate all the software examples that are used this dissertation.
121
5.2 Case Study: ProcessMan
In this section, we present a relatively complex case study, named ProcessMan (process management). The aim is to investigate how our proposed DDDAL method would help a university faculty to effectively manage its organisational processes. A key objective is to construct a process model and an MCC model that are sufficiently expressive for the faculty’s purpose.
5.2.1 Method
According to Runeson and Höst [66], case study research (CSR) is “an empirical method aimed at investigating contemporary phenomena in their context”. CSR is applicable to software engineering because software development activities are performed by human stake- holders under different conditions, especially where the boundaries between the phenomena and contexts are unclear. The type of case study that we conduct is explanatory. In particular, we seek a confirmation for the applicability of DDDAL to relatively complex, real world environments. The subsequent subsections will report the method’s steps and findings.
5.2.2 Case and Subject Selection
We chose the Faculty of IT (FIT) at Hanoi University4 as the case for investigation. FIT is a relatively young faculty that has been undergoing significant organisational changes. One of these changes involves standardising the organisational processes in accordance with the ISO’s quality management standard5. We thus chose organisational process management as the particular subject of our investigation.
4 http://fit.hanu.vn/course/index.php 5 https://www.iso.org/iso-9001-quality-management.html
As an educational institution, the core processes that FIT performs are teaching subjects (a.k.a course modules) to students every semester and formally assessing the students’ per- formances. Conceptually, a process is a sequence of tasks, each of which is a sequence of actions. A process is created once, by an organisation unit, and is periodically applied to the same unit and possibly to other organisational units that have similar needs. For certain processes, task and action would need to be specialised in order to specify more details. For example, in the assessment process, a subject is created only once but is taught in the same
122
semester every year. This periodic delivery of a subject is called subject-by-semester. The type of tasks that is applied specifically to subject-by-semester is called task-for-subject. Each task-for-subject consists of a sequence of action-for-subject, which is a specialisation of action.
5.2.3 Data Collection and Analysis
Because of the nature of DDDAL, data collection and analysis for the case study naturally coincide with software requirement capturing and analysis (resp.). We collected qualitative data, which include technical documents that describe and expert opinions about the pro- cesses. For these two data types, we applied two requirement capturing techniques: document review and semi-structured interview (resp.). We obtained the process documents directly from their authors, which are also members of the teaching staff. To obtain further informa- tion about the documents, we conducted informal interviews with the document authors and, in some cases, with the faculty’s dean.
We analysed the requirements using DDDAL, with the help of the software tool described in Section 5.1. In the CSR’s terminology, our analysis follows the template approach [66], whereby the collected data are coded using pre-defined domain- and module-specific terms. The coded data is used to construct the domain and MCC models. Further, the analysis is performed iteratively until both models are satisfactory (as explained in Section 1.3).
5.2.4 Results
Our analysis results in a domain model and an MCC model, which we will describe in this section. In addition, we will discuss threats to the validity of our approach.
Process Domain Model
Figure 5.2 shows the domain model that expresses the ProcessMan’s requirements. The model consists of four domain modules, which are represented in the figure as four packages. These domain modules are all named model, each of which is placed inside the directory structure of a software module. To ease discussion, we will refer to the domain module by the software module’s name. The software module’s name is written in the figure in brackets, that appear below the domain module. For example, the domain module processstructure
123
Figure 5.2: ProcessMan’s domain model.
(shown at the top-right of the figure) is placed in the package processstructure.model of the software module named processstructure.
As shown in the figure, the domain module processstructure consists of three domain classes (Process, Task, Action) that together describe the general structure of a process, and two other domain classes (Task4Subject, Action4Subject) that describe a specialised structure for the teaching and assessment processes. Task4Subject specialises Task, while Action4Subject specialises Action. The reason that we only specialise Task and Action and not Process is because class Process suffices for use as a common abstraction for all types of processes. At the process level, there is no real distinction between the processes. The domain module processapplication consists of four domain classes:
two of which (OrgUnit and ProcessApplication) represent the periodic application of a Process, while the other two (SubjectTask and SubjectAction) serve as intermediate classes that resolve the two many-many associations between Task4Subject and Action4Subject and SubjectBySemester (resp.). Note that class OrgUnit plays another role, which is the creator
124
of a Process.
The two classes SubjectBySemester and Subject belong to the domain module teaching. The former represents the periodic delivery of the latter in a semester of each academic year.
Last but not least, the domain module hr (which stands for “human resource”) contains a class named Teacher, which is one of numerous types of domain users that are managed by the system. Teacher has a many-many association to SubjectBySemester, which models the ownership of each subject delivery by a teacher.
MCC Model
Figure 5.3: A partial MCC Model for process structure.
In ProcessMan, MCCs are created and managed within each domain module’s bound- ary. Each domain class in a domain module is used to create one MCC. The MCCs are placed in the software module’s package (which is at the same level as the module’s model package). The owner MCC of a domain subclass is modelled as a subclass of the owner MCC of the domain superclass. This helps not only promote configuration reuse but ease configuration extensibility. To illustrate, the left hand side of Figure 5.3 shows five MCCs of the domain module processstructure. Among these, two pairs are the subject of
125
subclass-superclass association: ModuleTask4Subject is a subclass of ModuleTask and ModuleAction4Subject is a subclass of ModuleAction.
Using the DDDAL’s software tool and iterative analysis, we were able to incrementally construct and verify the domain and MCC models with the domain experts. Thus, we conclude, with a high degree of confidence, that DDDAL is applicable to ProcessMan.
Threats to Validity
We organise threats according to the following four categories of validity that were suggested by Runeson and Höst [66]: construct validity, internal validity, external validity and reliability.
Construct validity. This is the extent to which “. . . the operational measures that are studied really represent what the researcher have in mind and what is investigated according to the research questions”. In our case study, we have assumed that there are no misinterpretations of the process requirements that would lead to unsatisfactory representations in the models. Our DDDAL (see Section 1.3) helped mitigate the threat of misinterpretation by allowing software protototypes to be constructed quickly and incrementally from the models. Using these prototypes, the domain experts can intuitively work with the technical team to verify the models against the process requirements.
Internal validity. This refers to the extent to which causal relations between the investigated factors are carefully examined. DDDAL, being a DDD method, assumes that a software’s core is its domain model. However, there may be other aspects of the software (e.g. concerning such non-functional requirements as security, distributed processing, usability and the like) that also need to be taken into consideration. Indeed, the stake-holders involved have suggested that security and usability are two aspects that are particularly relevant to ProcessMan. We argue that DDDAL can potentially mitigate this threat because the base MOSA architecture is extensible with new layers that express the new requirement types. Further, MCCL is easily extensible to support new annotations that realise the configuration concerning these types.
External validity. This is the extent to which the findings can be generalised and be of interest to other cases that have similar characteristics. This is a threat to our case study because it was carried out over just one case. We would argue, however, that our choice of the generic process model within this case would help mitigate the threat. To the best of
126
our knowledge, the process document was developed in accordance with the ISO standard, making it possible to generalise the resulted models for other cases that adopt the same standard.
Reliability. This refers to the reliability of the data collection and analysis that were per- formed. Ideally, these should be reliable to the extent that if replicated (typically by another researcher) then the same result would be obtained. A threat to the reliability in our approach arises from the fact that the process document that we collected had not formally been cer- tified by an ISO-certification agency. As such, it may not completely conform to the ISO standard. We would thus argue that an application of our approach to an ISO-certified process environment may require some adjustments to the data collection and/or analysis (e.g. more data would need to be collected and a combination of analysis techniques may need to be applied).
5.3 DCSL Evaluation
As far as UD modelling is concerned, within the scope of this dissertation, we focus on evaluating DCSL. We first discuss the overall evaluation approach that we adopt for DCSL. After that, we present the evaluation results. We conclude with a number of discussion points concerning the language and its use in software design.
5.3.1 Evaluation Approach
We evaluate DCSL from two main perspectives: language and generative capability.
Language Evaluation
We consider DCSL as a specification language and adapt from [42] the following three criteria for evaluating it: expressiveness, required coding level and constructibility. Constructibility is evaluated separately from the other two criteria.
We use DCSL’s terms as the base for evaluation because, as will be explained shortly below, they correspond to the essential terms that are used in the relevant modelling and OOPL literatures and there has been no other annotation-based DSL that supports a similar set of terms. We discuss how the DCSL’s concepts and terms are mapped to the DDD patterns.
127
Table 5.1: The expressiveness aspects and domain properties of interest
Aspects
Structural modelling
Domain properties four DCSL’s terms (see Definition 3.2): domain class, domain field, associative field and domain method activity domain class (see Definition 3.9) constraint, structural mapping
Behavioural modelling Language definition
Further, we compare DCSL to the annotation-based extensions of two DDD frameworks and to the commonly-used third-party annotation sets. To ease notation, we label the annotation- based extensions of the frameworks as follow: ApacheIsis [17] is labelled AL and OpenXAVA [60] is labelled XL.
Our approach is to analyse the relevant technical documentations of AL, XL and DDD patterns to identify the language constructs that are either the same as or equivalent to the primitives or combinations thereof that make up each DCSL’s term. We also made an effort to quantify the correspondences.
Expressiveness
This is the extent to which a language is able to express the properties of interest of its domain [42]. Within the scope of this dissertation, we are interested in the essential properties of the domain. We first argue for the minimality (a.k.a essentiality) of DCSL. We then use this as the basis to structure the expressiveness evaluation around DCSL. More specifically, we consider three modelling aspects and within each identify the domain properties of interest. Table 5.1 lists the aspects and properties. A single expressiveness criteria that we use to judge each property is coverage.
Required Coding Level
Required coding level (RCL) is the extent to which the language allows “...the properties of interest to be expressed without too much hard coding” [42]. Based on the expressiveness evaluation result, we judge RCL based on three domain properties, which coincide with following three domain terms that are supported by DCSL, AL and XL: domain class, domain field and associative field.
In addition, we use two criteria to measure the RCL for each domain property: max-locs (max number of lines of code) and typical-locs (typical number of locs). The lower the values of these the better. Because DCSL, AL and XL are all internal to a base OOPL, we
128
consider annotation property as a loc. Thus, max-locs (resp. typical-locs) is the maximum (resp. typical) number of properties needed to express a typical domain term. The typical number of properties include only properties that either do not have a default value or are typically assigned to a value different from the default. For example, to specify in DCSL a typical domain field (say Student.name) maximally (resp. typically) requires these (resp. one of these) three DAttr’s properties: length, min, max.
Constructibility
This is the extent to which the language provides “...facilities for building complex specifications in a piecewise, incremental way”[42]. For DCSL, we define constructibility as generative capability for domain modelling and discuss this separately in the next section.
Generative Capability
The objective of this evaluation is to measure the extent to which DCSL supports UDM generation. We emphasise that this is generativity of the domain model, which is different from the software generativity property discussed in Section 4.2.5. Specifically, we evaluate function BSpaceGen (defined in Section 3.4.3) with respect to two properties: behaviour generation and performance. The performance criteria that we use is time complexity, which was established for BSpaceGen in Theorem 3.2.
For behaviour generation, we emphasise that the objective is about behaviour specification generation of domain method. We do not evaluate code generation for the method body. We use two criteria: number of domain methods and quality. The latter is measured in terms of the conformance to a de facto naming convention of the target OOPL (e.g. JavaBean). To measure these criteria, we use Java as the target host OOPL and, for comparison, a compact CourseMan solution model that we had manually and independently developed for teaching. This solution model consists of three classes (Student, Enrolment and CourseModule), which capture all the essential features of DCSL.
5.3.2 Expressiveness
We present in this section the evaluation of the expressiveness criterion.
129
Table 5.2: (A-left) Comparing DCSL to DDD patterns; (B-right) Comparing DCSL to AL and XL
DCSL concepts
DDD patterns
Aspects
Aspects
DCSL
AL
XL
Entity, Domain Event, Aggregate
Structural modelling
Structural modelling
Value Object
Service
Behavioural modelling
Behavioural modelling Language definition
1/1 8/8 7/7 (cid:51) (cid:51) (cid:51) (cid:51)
1/1 4/8 0/7 (cid:56) (cid:56) (cid:56) (cid:56)
0/1 5/8 1/7 (cid:56) (cid:56) (cid:56) (cid:56)
Expressiveness criteria Domain Class Domain Field Associative Field Domain Method Activity Domain Class Constraint Structural mapping
& terms Domain Class Domain Field Associative Field Domain Method Immutable Domain Class Activity Domain Class (cid:51)
(cid:56)
Language definition
On the Minimality of DCSL
We reason that DCSL, as defined in this dissertation, is minimal with regards to the set of state space constraints and the essential behaviour that operate on them. First, the state space constraints are identified, based on the authoritative system and software engineering sources [34, 48, 49, 57], as being the most fundamental. Second, we have two arguments for why our proposed OptTypes constitute a minimum behaviour specification for domain class. The first argument is that these OptTypes are a specialisation of three essential behavioural types defined in [48, 49], namely, creator, mutator and observer. Clearly, we need at least these three types of operations in order to create and use objects at run-time. The second argument is that these OptTypes are needed to accommondate the structural mapping to the aforementioned state space.
Comparing to the DDD Patterns
The first three rows of Table 5.2(A) show a mapping between DCSL’s concepts and terms and the DDD patterns discussed in Section 2.1.4. The DCSL terms form a technical design language, which realises the high-level design structures described in the DDD patterns. Specifically, the four DCSL’s terms are able to express three DDD patterns: Entity, Domain Event and Aggregate. Regarding Domain Event, in particular, DCSL is able to express elements of the event management model. However, DCSL does not (yet) address how the domain classes use these elements via the publish/subscribe interface operations. We will investigate this as part of future work.
130
Concept Immutable Domain Class in Table 5.2(A) is a special case of Domain Class in which DClass.mutable = false. It is mapped to the Value Object pattern. Concept Activity Domain Class is mapped to the Service pattern.
The last row of the table, however, shows a key difference: while we define DCSL as a
design language, the DDD patterns do not by themselves constitute a language.
Comparing to DDD Frameworks
DCSL >essentially AL, XL
Table 5.2(B) presents the evaluation table between DCSL and AL and XL. The fractions in the table are ratios of the number of essential properties of the meta-attribute involved in a DCSL’s term/concept that are supported by AL or XL. The denominator of a ratio is the total number of essential properties. A detailed comparison data table is given in Appendix C.1. For example, the ratio 4/8 for AL w.r.t the term Domain Field means that AL only supports 4 out of the total of 8 properties of the meta-attribute DAttr (used in Domain Field). The four AL’s properties are: Column.allowsNull, Property.editing, PrimaryKey.value and Column.length
Table 5.2(B) shows that DCSL is more expressive than AL and XL in both structural and behavioural modelling aspects. These two languages only partially support structural modelling and they do not support behavioural modelling using the activity domain class. In particular, AL’s and XL’s support for Associative Field is very poor compared to DCSL.
Comparing to Third-Party Annotation Sets
DCSL >essentially BV
AL and XL support the use of third-party annotation sets, which between them include Java Persistence API (JPA) [59], Java Data Objects (JDO) [18], Hibernate Validator (HV) [64] and Bean Validation (BV) [63]. BV is defined as a standard, of which HV is a reference implementation. In the comparison in Table 5.2(B), we compared and contrasted DCSL with the comparable subset of the combined annotation set of the above annotation sets that are supported by AL and XL. For the sake of completeness of the current comparison, we will compare DCSL to the full BV’s built-in annotation set. We choose BV because it subsumes
131
HV and, similar to DCSL, it is storage-indendendent (JPA and JDO are technologies for mapping domain objects to a data source).
Similar to DCSL, BV’s annotations specify constraints on class, field and method. A number of built-in BV’s annotations are similar or comparable to DCSL. For example, Null is expressible by DAttr.optional; Min, Max, Negative, NegativeOrZero, Positive and PositiveOrZero are expressible by DAttr.min, max; and Size (for String data type) is similar to DAttr.length. The Size constraint for collection-typed field is subsumed by the property pair Associate.cardMin, cardMax of DCSL.
However, BV does not specify any annotations that are equivalent to the following prop- erties of DCSL: DAttr.mutable, unique, id and auto. On the other hand, BV specifies the following annotations that are not currently included in DCSL: Pattern and Email (for string type), AssertTrue and AssertFalse (for boolean type), Future and Past (for date type), and DecimalMin, DecimalMax and Digits (for numerical type). Since these annotations describe constraints that concern specific value subsets of the built-in data types, we argue that they would form an extension annotation set and be added when the need arises. What we currently focus on in DCSL is the essential annotation set.
Apart from these, we observe three underlying limitations of BV compared to DCSL. First, BV is not defined as a language. As such, it is not clear what the underlying constraints mean in terms of the class structure. Second, BV does not identify which constraints are essential and which are not. Third, it does not modularise the annotations in terms of the state and behaviour spaces and thus lacks the identification of the structural mapping between the annotations in these two spaces. This also means that, unlike DCSL, BV does not specify a technique for automatically generating the behaviour specification.
5.3.3 Required Coding Level
Table 5.3: (A-left) Summary of max-locs for DCSL, AL and XL; (B-right) Summary of typical-locs for DCSL, AL and XL
Max-locs criteria
Typical-locs criteria
Total
Total
Domain Class 1 2 2
Domain Field 3 4 6
Associative Field 7 0 1
11 6 9
DCSL AL XL
Domain Class 1 2 2
Domain Field 1 1 1
Associative Field 7 0 1
9 3 4
DCSL AL XL
132
Tables 5.3(A) and 5.3(B) respectively show the values of max-locs and typical-locs for the three underlying DCSL’s terms that are supported by AL and XL. The last columns of the tables show the total values. The detailed comparison data are presented in Appendix C.2.
DCSL >essentially AL, XL
It can be observed from both tables that, compared to AL and XL, DCSL has the highest total max-locs (11) and typical-locs (9). However, a closer inspection shows that the DCSL’s subtotals for Domain Class and Domain Field (4 and 2 resp.) are actually lower than the corresponding subtotals for AL (6 and 3) and XL (8 and 3). Hence, the single contributing factor to DCSL having the two highest totals is the set of 7 mandatory properties needed to express Associative Field. Since all 7 properties are essential for representing this type of field, we conclude that the increase in DCSL’s required coding level is a reasonable price to pay for the extra expressiveness that the language enjoys over AL and XL.
5.3.4 Behaviour Generation
Table 5.4: BSpaceGen for CourseMan
Number of methods
Domain classes
Generated
Manual
20
22
CourseModule
17
18
Enrolment
19
20
Student
Table 5.4 presents the evaluation result of function BSpaceGen. The two columns “Manual” and “Generated” show the numbers of domain methods in the CourseMan solu- tion and generated models (resp.). We exclude AL and XL from this evaluation because they do not support behavioural generation.
The table shows that BSpaceGen is able to generate the behaviour specification of 100% of the domain methods in the solution model. Qualitywise, the generated method headers follow the JavaBean convention. Interestingly, compared to the solution model, the generated specification contains a few extra in all three domain classes of CourseMan. These methods do not have any domain-specific requirements. Thus, the fact that the manual solution model does not contain these methods does not affect the completeness of the model. For example, both CourseModule and Student are generated with a LinkUpdater-typed method named onUpdateEnrolments. However, these methods do not have any domain-specific logic defined for them, because neither CourseModule nor Student object state needs to be updated when a linked Enrolment is changed.
133
The generative capability of DCSL is amplified by the fact that BSpaceGen is also
applicable to generating the behavioural specification of the activity domain class.
5.3.5 Performance Analysis
Since AL and XL do not support code generation, we focus our performance analysis on function BSpaceGen. Based on the linear complexity result of Alg. 3.1 (presented in Section 3.4.3), we conclude that BSpaceGen is practically capable of handling domain classes with large state spaces.
5.3.6 Discussion
Let us conclude the current evaluation with a number of remarks about the design and implementation of DCSL and its use in software design.
The granularity of domain method in DCSL is currently at the lowest, most basic level. At this level, the domain methods are structurally mapped to a set of essential state space constraints. The question then arises as to how to model more coarse-grain methods, such as those discussed in [22, 75] that realise the domain behaviours. The UD modelling patterns that were discussed in Section 3.6.2 are a first important step towards addressing this question. However, more research should be carried out in this direction.
The minimality, behaviour-essentiality and evolution of DCSL are tightly connected. We judged minimality based on a set of fundamental constraint requirements and essential be- haviours that are taken from a set of authoritative academic and practical resources. However, we would not claim that these resources are universal to every researcher and practitioner in the field. It is thus our hope that our proposed ‘minimality’ property would attract interests and feedbacks from those concerned, with an aim to come to an improved understanding.
Regarding to the behaviour-essentiality of DCSL. We basically took the “behaviourally- complete” property proposed in [62] for domain models in general, extracted a set of essential underlying features (called “behaviour essential”) and then used this as the starting point for DCSL. This way, DCSL can be used to define many different behaviourally complete domain models. As a language, DCSL starts out with only a set of essential features. We expect that DCSL, as it is put into use, will evolve to incorporate more features. Some of these features would surface as we investigate how to address other types of requirement.
134
Domain model evolution is inevitable in real-world software development. This happens specifically when the software is put into use and needs to undergo maintenance at some point. Given that the software is developed using our proposed software model, software evolution can basically be handled as part of our overall DDDAL method as follows. First, we identify the necessary software changes through interaction via the software GUI. Then, we map out these changes (via the module layer structure of the software model) to the corresponding changes that need to be applied to the UDM. However, more research need to be conducted concerning how to automate this procedure in our method.
5.4 Evaluation of Module-Based Software Construction
As stated in Section 4.1, existing works in DDD lack a method for software module construc- tion. Thus, we will not compare our our module-based software construction method with these works. Our main objective here is to evaluate the extent to which MCCL helps automat- ically generate software modules. To achieve this, we define a framework for developer-users of MCCL to precisely quantify module generativity for the application domains. In the framework, we will identify the general module patterns and discuss how module generativ- ity can be measured for each of them. Further, we evaluate the correctness and performance of function MCCGen.
5.4.1 Module Generativity Framework
Table 5.5: Module pattern classification
View
Controller
MPs
Configuration Code Configuration Code
Cust
Cust
Cust
Cust Def (cid:51)
((cid:51))
(cid:51)
(cid:51)
((cid:51)) ((cid:51))
((cid:51))
Def M P1 (cid:51) M P2 (cid:51) M P3 M P4
(cid:51) (cid:51) (cid:51)
We first observe that the module gen- erativity procedure consists of two steps: (i) generate the MCC of the module and (ii) generate the module from the MCC. The first step is per- formed semi-automatically by func- tion MCCGen. The second step is performed semi-automatically by the module interpreter of jDomainApp. We measure module generativity by taking a weighted average of the generativity values of these steps.
135
Another observation is that the parts that need to be manually written by the developers in both steps can be identified through the module configuration in MCC. This means that we can measure the generativity value of each step by the efforts taken to compose those parts. We will call the parts generally by the name customised elements. The customised elements in the first step are called customised configuration elements, while those in the second step are called customised components. To facilitate the measurement, we further classify each type of elements by the component type: view elements and controller elements. We omit the model component (the domain class) of each module from measurement because it is developed before hand.
Table 5.5 describes a classification of module patterns (MPs), which is based on valid customisation scenarios. A valid customisation scenario correctly describes a combination of element types that need or need not be customised. In the table, the former case is abbreviated as “Cust” (customised), while the latter case is abbreviated as “Def ” (default). Conceptually, an MP represents a set of module objects of one or more module classes that result from applying a particular customisation pattern on these classes. The four MPs listed in the table cover the set of module objects of the module classes constructible by our method.
Note the followings about the MP classification. First, the module objects that make up a containment tree can belong to different MPs. For instance, a composite module may belong to M P1, while its descendant modules belong to other MPs. Second, we do not need to consider the Def case for code because this is implied if no code customisation is performed. Third, a customised configuration (of either view or controller) may require creating customised component(s). In the table, we show this causal relationship by writing ((cid:51)) in the Cust-Code column whenever we use a (cid:51)in the Cust-Configuration column. Fourth, we systematically define customised components around design patterns that extend the MOSA’s functionality. This promotes code reuse and, hence, improves module generativity for new modules. For controller, a customised component is a pattern-specific module action, which is an action whose behaviour is customised to satisfy a new design requirement. Evans [23] proposed high-level patterns, while we defined in a recent work6 a number of concrete patterns. For view, a customised component is a new view component that improves the usability of the module view. This includes a view field class, a new view layout component and so on.
6 paper 2 listed in the Publications section.
The last observation is that we can construct a shared formula for the generativity factors of both steps of the module generativity procedure. The basis for this formula is that both
136
steps involve writing some form of code for view and/or controller (MCC is also code). Denote by V and C the amounts of code created for the view and controller components (resp.) and by V 0 and C0 the amounts of customised code manually written for these same two components (resp.). That is, V 0 + C0 is the amount of developer’s code input. Further, let W = V + C be the total amount of code created for the view and controller. Denote by m the generativity factor, then we measure m in (0,1] by the following formula:
(5.1) = 1 − m = (V − V 0) + (C − C0) W V 0 + C0 W
Denote by m1, m2 the generativity factors of steps 1 and 2 (resp.). We use subscripts 1 and 2 to denote the components of m1 and m2, resp.; e.g. W1, W2, etc. We measure the module generativity M (also in (0,1]) by taking a weighted average of m1 and m2. We compute two weights α and 1 − α based on the relative extent of W1 and W2:
(5.2) , 1 − α = ) M = αm1 + (1 − α)m2 (where: α = W1 W1 + W2 W2 W1 + W2
In Formula 5.2, the higher the value of M , the higher the module generativity. Our choice of weights means to give higher emphasis to the component (m1 or m2) that dominates in the impact on M . In practice, the dominating factor is typically m2, because W1 (configu- ration) is typically much smaller than W2 (actual code). This reflects a fact that the module generativity’s extent depends mostly on how many customised components to extend the MOSA’s core functionality that need to be created. We will use Formula 5.2 as the basis to develop more specific formulas of M for the MPs. We illustrate each formula and the MP(s) in question by a CourseMan software variant, that is constructed by our software tool.
5.4.2 M P1: Total Generativity
1 = V 0
2 = 0 and C0
1 = C0
In this special MP, we achieve 100% generativity, because V 0 2 = 0, which leads to M = m1 = m2 = 1. A reference software that is constructed only by modules belonging to this MP is implemented by the DomainAppTool (see Section 5.1.1). The soft- ware generated by this tool has the same GUI as those described in the CourseMan examples in the earlier chapters of this dissertation, except that every view field (of a module’s view) is generated with a default configuration.
137
Example 5.1. Figures 5.1 and 5.4 together show an example CourseMan software that is generated by DomainAppTool. Figure 5.1 includes three views: ViewhStudenti, ViewhSClassRegistrationi and ViewhSClassi. Note, in particular, how the view field ViewhEnrolmentMgmti.students in Figure 5.4 is a subview reflecting the associative field EnrolmentMgmt.students.
Figure 5.4: The view of ModuleEnrolmentMgmt of the software in Figure 5.1.
This subview has exactly the same content as ViewhStudenti in Figure 5.1. This view has two list-typed view fields: sclasses and modules. These fields reflect the two many-many associations between Student and SClass, CourseModule (resp.). The ac- tual handling of user actions on these fields require customising some module actions. This cus- tomisation will be discussed later as part of the fourth MP. For this MP, these view fields are used by the development team to visually review the domain class design.
5.4.3 M P2–M P4
These three MPs involve customising view and/or controller at various extents. We thus first develop a shared formula for all three MPs. After that, we discuss how it is applied to each MP. Denote by W and w the numbers of customised configuration elements of a module and of a view field (resp.).
i=1 wi)
Definition 5.1. The configuration customisation factor of a module, whose view contains s number of view fields, is: C = (W + Ps
Given that the module’s containment tree has n descendant modules, whose configurations are customised. Let Ck be the configuration customisation factor of the kth descendant module. We derive from Formula 5.1 the following formula for m1:
138
k=1 Ck
(5.3) m1 = 1 − C + Pn W1
Denote by P and p the numbers of lines of code (LOCs) for the customised components
of a module and of a view field (resp.).
Pti
Definition 5.2. Given that a module has T number of customised components at the module level, s number of view fields and ti number of customised components for the ith view field of the module view. The code customisation factor of the module is:
j=1 pij
i=1
i=1 Pi + Ps
D = PT
k=1 Dk
We derive from Formula 5.1 the following formula for m2 (n is the number of customised descendant modules, as in Formular 5.3):
(5.4) m2 = 1 − D + Pn W2
M P2. It can be observed in Table 5.5 that, for this MP, m1 is measured based only on counting the number of customised controller configuration elements. If there exists a non- empty sub-set of these elements that require customising module actions, then m2 is measured based on counting the LOCs of the customised components of these actions.
M P3. It can be observed in Table 5.5 that, for this MP, m1 is measured based only on counting the number of customised view configuration elements. If there exists a non-empty sub-set of these elements that require creating new view components, then m2 is measured based on counting the LOCs of these components.
It can be observed in Table 5.5 that, for this MP, m1 is measured based on counting M P4. the numbers of customised view and controller configuration elements. If there exists a non-empty sub-set of these elements that require creating new components (view or module action), then m2 is measured based on counting the LOCs of these components.
An important insight that we draw from our evaluation framework is that module genera- tivity is high (which is desirable) if m2 is high and dominates m1. This occurs if (i) existing MOSA’s capability (which includes the set of design patterns that have been constructed over time) is sufficient for constructing software modules in the domain and (ii) α is small. As explained in Section 5.4.1, condition (ii) typically holds in practice. Although condition
139
(i) can not be guaranteed to hold for a software module whose design requirements do not match exactly with the existing MOSA’s capability, it can be made to hold for other software modules that have similar design requirements. This is achieved through the design patterns.
Example 5.2. Table 5.6 shows the module generativity values of two CourseMan’s modules (ModuleStudent and ModuleEnrolmentMgmt) that were configured for each of the three MPs discussed in this section. The last column (“M ”) lists the module generativity value.
Table 5.6: Module generativity values of two CourseMan’s modules in M P2–M P4
Code (Step 2)
MPs
Modules
α
M
M P2
M P3
M P4
Configuration (Step 1) C C1, . . . , Cn W1 m1 0.98 1 0.94 0 0.82 11 0.89 5 0.75 18 0.72 17
– 1, 1, 1 – 1 – –
51 49 61 54 72 61
D D1, . . . , Dn W2 7500 – 0 7500 – 0 7572 – 72 7500 – 0 7791 – 291 7644 – 144
m2 1 1 0.99 1 0.96 0.98
0.01 0.01 0.01 0.01 0.01 0.01
0.99 0.99 0.99 0.99 0.96 0.98
ModuleStudent ModuleEnrolmentMgmt ModuleStudent ModuleEnrolmentMgmt ModuleStudent ModuleEnrolmentMgmt
The two master columns (“Configuration” and “Code”) show statistics for step 1 and step 2 of the generativity procedure. The sub-columns of these master columns show values of each component of Formula 5.3 (step 1) and of Formula 5.4 (step 2), respectively. The two columns “C1, . . . , Cn” and “D1, . . . , Dn” list sequences of numbers for the configuration In the current elements and LOCs (resp.) of the descendant modules of each module. example, column “D1, . . . , Dn” does not contain any values, because none of the customisa- tion that was made necessarily leads to code customisation in any descendant module. For instance, we initially had D1 = 72 for ModuleEnrolmentMgmt of M P3, but then discarded because the customisation could reuse the view component that was implemented as part of ModuleStudent. The numbers of LOCs listed in column W1 are counted directly from each generated MCC. The numbers in the column W2, however, are calculated by adding the LOCS of the customised code to the base LOCs of 7500. This is the total LOCs of the View and Controller classes that are implemented in jDomainApp.
As can be seen from the table, M is very high for both modules in all three MPs. This is because in all of these cases m2 is very high and dominates m1 (α is very small). Figure 5.5 shows the CourseMan software of M P4, which contains the customised views and configurations of the modules. We will use this view to illustrate both types of customisations. We will make explicit for each customisation the MPs under which it is allowed.
First, regarding to view configuration customisation (M P3, M P4), the figure shows
140
Figure 5.5: An example CourseMan software that has substantially been customised.
that all three views have been configured with custom view field labels and with more complex layout. In particular, ViewhStudenti is similar to the one presented in Figure 4.7 in that it excludes the view field helpRequested. ViewhEnrolmentMgmti has an overall tab layout. In this layout, all the subviews reflecting the associative fields (e.g. the subview for EnrolmentMgmt.students) are rendered within the tabs of a tab group. Further, the label and content of every view field has been configured to contain user-friendly strings. For instance, the view field ViewhStudenti.modules is now labelled “Enrols Into”. Its content now lists values (“IPG”, “PPL”, “SEG”) of the ‘bounded’ domain field (CourseModule.name), as opposed to the CourseModule.ids as shown in Figure 5.1.
As for controller configuration customisation (M P2, M P4), we customise the open action of each module with a suitable policy. We also customise this action for two descendant modules of ModuleEnrolmentMgmt of M P2. These explain the three one values (1, 1, 1) written in the column labelled C1, . . . , Cn in Table 5.6 of the module. A useful policy that we use is to automatically load all the objects from the object store. This policy is applicable when there are only a small number of objects of the concerned domain class or that these objects are required in order for the software to function. We showed in the MCC
141
of ModuleStudent in Listing 4.1 how to configure the open policy of the open action.
Regarding to controller code customisation (M P2, M P4), we customise the module actions in order to realise a pattern named many-many association normaliser7. This pattern involves specifying the many-many association type directly in the domain class, despite the fact that the underlying object store of this class only supports one-many association. Given that the CourseMan software uses a relational database to store objects. The domain model (shown in Figure 1.1) directly supports a many-many association between Student and CourseModule. This requires the module action which handles the many-many association to conform to the pattern behaviour. This behaviour basically involves transforming the many- many association (exposed on the module’s view) between the two participating domain classes into two one-many associations that are actually defined in the two classes.
Listing 5.1 shows a partial MCC of ModuleStudent (presented in Listing 4.1) that has been reconfigured with two customised module actions. The customised view of this module was presented as part of Figure 5.5. In this, the actions allow the user to choose for each Student several CourseModules on the list. The two module actions are specified in the two PropertyDescs that form the value of the property ModuleDesc.controllerDesc.props. These specify the customised Create and Update actions to be the following classes (resp.):
CreateObjectAndManyAssociatesDataControllerCommand and UpdateObjectAndManyAssociatesDataControllerCommand.
1
2
3
4
@ ModuleDesc ( name = " ModuleStudent " , modelDesc = @ ModelDesc ( model = Student . class ) , viewDesc = @ ViewDesc ( ... omitted ...) , controllerDesc = @ ControllerDesc (
5
controller = Controller . class , i s D a ta F i e l d S t a t eL i s t en e r = true
6
, props ={
7
8
9
10
11
12
// many - many assoc commands @ PropertyDesc ( name = PropertyName . controller_dataController_create , valueIsClass = C r e a t e O b j e c t A n d M a n y A s s o c i a t e s D a t a C o n t r o l l e r C o m m a n d . class , valueAsString = MetaConstants . NullValue , valueType = Class . class ) , @ PropertyDesc ( name = PropertyName . controller_dataController_update , valueIsClass = U p d a t e O b j e c t A n d M a n y A s s o c i a t e s D a t a C o n t r o l l e r C o m m a n d . class ,
valueAsString = MetaConstants . NullValue , valueType = Class . class )
13
}) ... omitted ...
)
14
public class ModuleStudent { ... omitted ... }
7 paper 2 listed in the Publications section.
Listing 5.1: ModuleStudent’s MCC with customised actions for many-many associations.
142
5.4.4 Analysis of MCCGen
In this section, we summarise the correctness and performance evaluation of function MCC- Gen. We state two theorems and provide a proof for each.
Theorem 5.1 (Correctness). MCCGen correctly generates the owner MCC of the input domain class. This MCC is structurally consistent with the domain class, as per Definition 4.3.
Proof. The proof consists of two parts. First, the output MCC (m) is the owner MCC of the input domain class (c). This follows from the fact that ModuleDesc(m).modelDesc (do) is initialised with model=c.
Second, m is structurally consistent (as per Definition 4.3) with c. Condition (ii) is clearly satisfied because m has an empty containment tree (Alg. 4.1 does not generate this tree). Condition (i) is satisfied due to the fact that the title field (fd) is created as a field of m and that the for loop in function AddViewFields create other view fields (fd) of m that reflect the domain fields f of c. Each view field has the same visibility (“private”), name (nf ) and data type (tf ) as those of the corresponding domain field.
Performancewise, the main concern is worst-case time complexity. In the theorem that fol- lows, we will state the worst-case time complexity of function MCCGen. To ease discussion, we will refer to this generally as complexity.
Theorem 5.2 (Complexity). MCCGen has a linear worst-case time complexity of O(F ), where F is the number of domain fields of the input domain class.
Proof. The dominating part of Alg. 4.1 is the invocation of function AddViewFields which occurs at the end of step 3. The for loop of this function iterates over the set F of the domain fields of c. The loop body consists of three primitive operations. Thus, the time complexity of the algorithm is big-O of |F |, which is O(F ).
Therefore, MCCGen is scalable to handle domain classes with large state spaces.
143
5.4.5 Discussion
We conclude the current evaluation with a brief remark about the usability of software GUI. From the domain expert’s view-point, this usability plays a role in the usability of our method. We would argue in favour of two aspects of the software GUI, namely simplicity and consistency, which contribute towards its learnability [24]. First, the GUI design is simple because, as discussed in Proposition 4.1, the module view reflects the domain class structure. Clearly, model reflectivity is the most basic representation of the domain model. Second, the GUI is consistent in its presentation of the module view and in handling the user actions performed on it. Consistent presentation is due to the application of the reflective layout to all module views. Consistent handling is due to the fact that a common set of module actions (see Section 4.2.1) are made available on the module view.
5.5 Summary
In this chapter, we conducted an evaluation of our contributions with an aim to measure the extent to which they achieve the objectives that were set in Chapter 1. We briefly described an implementation of DCSL and MCCL as part of a software framework. This implementation was used to conduct the experiments needed for the evaluation. We first evaluated DCSL from the perspective of a specification language. The evaluation shows that DCSL is essentially more expressive and, thus, necessarily requires (a little) more coding compared to two other similar languages. Further, behaviour specifications of all the domain methods can be automatically generated and the generation can scale to support domain classes with large state spaces. We then evaluated the extent to which MCCL helps automatically generate the software modules that are configured by it. We first defined a module generativity framework and four generic module patterns that classify the all the modules generatable using MCCL. We also analysed the correctness and performance of function MCCGen. This showed that the function is scalable with the domain class’s state space.
The content of this chapter is published in the following papers (listed in the Publications section). The DCSL’s evaluation is published in the SCIE journal paper 4. The evaluation for module-based software construction is published in the SCIE journal paper 6. The DDD patterns used in this evaluation are published in the conference paper 2. The implemented jDomainApp framework is published in the conference paper 5.
144
Chapter 6
Conclusion
The advent of model-based software development has, over the past twenty years, drastically changed the way software is engineered. Two closely-related MBSD methods that arguably have firmly cemented their place in the industry are MDSE and DDD. The DDD method aims to address the problem of how to effectively use models to tackle the domain’s complexity which it considers to be at the heart of software. The domain models should not only express the domain requirements well but be technically feasible for implementation.
Despite the fact that a substantial body of work has been written and a number of software frameworks have been developed for DDD, there are still significant open issues to be addressed. These issues became clear to us when we analysed DDD from the perspectives of a number of closely-related software engineering paradigms and methods (which include not only MDSE but OOPL, AtOP, BISL and aDSL). They motivated us to conduct this research, whose aim is to develop solutions for tackling the identified issues. The underlying theme of our approach is to use aDSL in DDD to design the core domain model and the modules that make up software constructed from the model.
The solutions that we have presented in this dissertation form an enhanced DDD method, which we believe makes the original method not only more concrete but more complete for software development purposes. After summarising the key contributions of this dissertation, we will discuss a number of directions for future development.
145
6.1 Key Contributions
This dissertation makes five key contributions towards enhancing the DDD method. The first contribution is an aDSL, named DCSL, which consists in a set of annotations that express the essential structural constraints and the essential behaviour of domain class. We have carefully selected the design features from a number of authoritative software and system engineering resources and have shown that they form a minimum design space of the domain class. We have applied the meta-modelling approach with UML/OCL to systematically define the abstract syntax of DCSL. We have also specified the semantics of the language. The second contribution is a unified domain modelling approach, which consists in using DCSL to express a unified domain model. We have chosen UML activity diagram language for behavioural modelling and discussed how the state-specific features of this language are expressed in DCSL. We have demonstrated our approach with a set of five fundamental UD modelling patterns. The third contribution is a 4-property software characterisation that provides technical guidelines for the software that are constructed directly from the domain model. The four properties are instance-based GUI, model reflectivity, modularity and generativity. These properties are defined based on a layered software model that includes the domain model at the core, an intermediate module layer surrounding this core and an outer software layer. Conceptually, this software model shows that a software is structured in terms of a set of modules and these modules are constructed directly from the domain model. The fourth contribution is another aDSL, named MCCL, that is used for designing the software modules in the module-based software architecture. More precisely, MCCL is used to express the module configuration classes (MCCs). An MCC provides an explicit class-based definition of a set of module configurations of a given module class. These configurations are treated as first-class objects and, thus, can easily be reused to create different variants of the same module class, without having to change the module class design. Again, we have adapted the meta-modelling approach with UML/OCL to systematically define the abstract and concrete syntaxes of MCCL. We have also leveraged DCSL to define the base semantics for MCCL. The fifth contribution is an implementation of DCSL, MCCL and the generators associated with these aDSLs as components in the jDomainApp software framework. Our implementation results in various software tools that can be used by developers to effectively apply our method in their software development processes.
146
6.2 Future Work
We argue that our research lays a foundation for further works to be conducted towards enhancing the DDD method. We highlight below a number of directions for these works.
MOSA and Software Construction
It is clear that the MOSA architecture needs to be improved if we are to enhance the software construction capabilities of our method. We gather in this section a number of research ideas concerning both MOSA and software construction.
Formalising the Software Properties. It would be beneficial for software design verification purposes to formalise the four software properties that were defined somewhat informally in this dissertation. The formalism should focus on the UML software model that was used as the basis to define the properties.
Improved Spport for Behavioural Modelling. Two areas of improvement would be con- sidered. The first area of improvement concerns extending the UDM to support other UML activity diagram constructs, e.g. activity group. The second area of improvement concerns constructing an aDSL for the UML activity graph. This graph was assumed to exist in this dissertation (see Section 3.6.2). A closer look at the graph description in the UML specification [57] would reveal that it too can be expressed by an aDSL.
Supporting Other Types of Requirement. To better support real-world software, the MOSA architecture would be extended to support web-based and mobile software development. Other important requirement types that should be studied with MOSA include security and those that are included in the current software module design of the Java language.
An aDSL for Software Construction. We discussed in Section 1.3 how software construc- tion is supported by the jDomainApp framework. However, this framework currently lacks a language that enables the designer to configure the software as a whole and the modules that make up a software. We would argue that the lessons learnt from developing MCCL for software modules would be applied to develop a similar aDSL for software configuration. In particular, this aDSL would allow the definition of software configuration classes. Each class defines a set of software configurations for constructing a software class from a set of software modules.
147
Integration into Software Development Processes
This integration is essential for the dissemination of our method in practice and, thus, we would recommend future research be conducted to investigate this. We argue that our method would particularly be suited for integration into iterative [43] and agile [6] development pro- cesses. Conceptually, the development team (which includes domain experts and developers) would use our tool to work together on developing the UDM in an incremental fashion: the developers use DCSL to create/update the UDM and then use MCCL to construct the software modules from this model. The software prototypes generated from these modules are used as the intermediate releases for the final software. The domain experts give feedbacks for the model via the software GUI and the update cycle continues.
Further, for both iterative and agile processes, tools and techniques from MDSE would be applied to enhance productivity and tackle platform variability. In particular, PIM-to-PSM model transformation would be applied to automatically generate the UDM from a high-level one that is constructed from a combination of UML class and activity diagrams.
Industrial-Scale Applications
It would be useful to apply our method to develop industrial-scale applications and report the results. To prepare for this, in addition to carrying out the future works described in the previous subsections, we would recommend investigating the integration of the overall method in well-known IDE, e.g. Eclipse. Further, an automated mechanism for handling domain model evolution would also be desirable.
Software Engineering Education
Because of the strong connection of our method to OOPL, it would be interesting to investigate how our method is applied in teaching software engineering course modules. Applying our method in education would also help increase the awareness of the method and its adoption in practice. To achieve this, further work should be conducted to integrate our method into university’s software engineering curriculumns. For instance, the practical experience that has been gained through applying our method (especially in connection with DomainApp- Tool) to teaching software engineering at Hanoi Univeristy should be documented, analysed and published. In addition, other works should be conducted to integrate the method into teaching at the entry level, which includes object-oriented programming course modules.
148
Publications
During the development of this dissertation, the author has published in the following inter- national conferences and journals:
1. D. M. Le, D.-H. Dang, V.-H. Nguyen, “Domain-Driven Design Using Meta-Attributes: A DSL-Based Approach”, in: Proc. 8th Int. Conf. Knowledge and Systems Engineer- ing (KSE), IEEE, 2016, pp. 67–72.
2. D. M. Le, D.-H. Dang, V.-H. Nguyen, “Domain-Driven Design Patterns: A Metadata- Based Approach”, in: Proc. 12th Int. Conf. on Computing and Communication Technologies (RIVF), IEEE, 2016, pp. 247–252.
3. D. M. Le, D. H. Dang, V. H. Nguyen, “Generative Software Module Development: A Domain-Driven Design Perspective”, in: Proc. 9th Int. Conf. on Knowledge and Systems Engineering (KSE), 2017, pp. 77–82.
4. D. M. Le, D.-H. Dang, and V.-H. Nguyen, “On Domain Driven Design Using Annotation- Based Domain Specific Language,” Journal of Computer Languages, Systems & Struc- tures (SCIE), vol. 54, pp. 199–235, 2018.
5. D. M. Le, D.-H. Dang, H. T. Vu, “jDomainApp: A Module-Based Domain-Driven Software Framework”, in: Proc. 10th Int. Symp. on Information and Communication Technology (SOICT), ACM, 2019.
6. D. M. Le, D.-H. Dang, V.-H. Nguyen, “Generative Software Module Development for Domain-Driven Design with Annotation-Based Domain Specific Language”, Journal of Information and Software Technology (SCIE), vol. 120, pp. 106–239, 2020.
149
Bibliography
[1] D. Akehurst et al., “Implementing Associations: UML 2.0 to Java 5,” Softw Syst Model,
vol. 6, no. 1, pp. 3–35, Mar. 2007.
[2] J. Alves-Foss and F. S. Lam, “Dynamic Denotational Semantics of Java,” in Formal Springer,
Syntax and Semantics of Java, ser. Lecture Notes in Computer Science. Berlin, Heidelberg, 1999, pp. 201–240.
[3] K. Arnold et al., The Java Programming Language, 4th ed. Addison-wesley Reading,
2005, vol. 2.
[4] M. Balz, “Embedding Model Specifications in Object-Oriented Program Code: A Bottom-up Approach for Model-Based Software Development,” Ph.D. dissertation, Universität Duisburg-Essen, Jan. 2012.
[5] M. Barnett et al., “The Spec# Programming System: An Overview,” in Construction and Analysis of Safe, Secure, and Interoperable Smart Devices, ser. Lecture Notes in Computer Science. Springer, Berlin, Heidelberg, Mar. 2004, pp. 49–69.
[6] K. Beck et al., “Manifesto for Agile Software Development,” 2017.
[7] D. Bogdanas and G. Roşu, “K-Java: a complete semantics of Java,” in ACM SIGPLAN
Notices, vol. 50. ACM, 2015, pp. 445–456.
[8] G. Booch, “Object-Oriented Development,” IEEE Transactions on Software Engineer-
ing, vol. SE-12, no. 2, pp. 211–221, Feb. 1986.
[9] M. Brambilla et al., Model-Driven Software Engineering in Practice, 2nd ed. Morgan
& Claypool Publishers, Apr. 2017.
150
[10] D. Bruns, “Formal Semantics for the Java Modeling Language,” Ph.D. dissertation,
2009.
[11] G. Calvary et al., “From Single-user Architectural Design to PAC*: A Generic Software Architecture Model for CSCW,” in ACM SIGCHI Conf. on Human Factors in Computing Systems, ser. CHI ’97. New York, NY, USA: ACM, 1997, pp. 242–249.
[12] V. Cepa, Attribute Enabled Software Development. Saarbrücken, Germany, Germany:
VDM Verlag, 2007.
[13] V. Cepa and S. Kloppenburg, “Representing Explicit Attributes in UML,” in 7th Int.
Workshop on Aspect-Oriented Modeling (AOM), 2005.
[14] C. W. Churchman, The Systems Approach, revised, updated ed. New York, NY: Dell
Publising Company, Nov. 1984.
[15] J. Coutaz, “PAC: An Object Oriented Model for Dialog Design,” in Interact’87, vol. 87.
Elsevier, 1987, pp. 431–436.
[16] K. Czarnecki, “Overview of Generative Software Development,” in Unconventional Programming Paradigms, ser. Lecture Notes in Computer Science, J.-P. Banâtre et al., Eds. Springer Berlin Heidelberg, 2005, no. 3566, pp. 326–341.
[17] Dan Haywood, “Apache Isis - Developing Domain-Driven Java Apps,” Methods & Tools: Practical knowledge source for software development professionals, vol. 21, no. 2, pp. 40–59, 2013.
[18] DataNucleus, “JDO Annotations Reference (v5.1),” 2018.
[19] R. Dekkers, Applied Systems Theory, 2nd ed. Springer International Publishing, 2017.
[20] M. Dumas and A. H. M. t. Hofstede, “UML Activity Diagrams as a Workflow Specifica- tion Language,” in UML 2001, ser. LNCS, M. Gogolla and C. Kobryn, Eds. Springer, Oct. 2001, pp. 76–90.
[21] Eclipse Foundation, “Eclipse Modeling Project,” 2019. URL: https://www.eclipse.org/
modeling/emf/
151
[22] E. Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software.
Addison-Wesley Professional, 2004.
[23] E. Evans, Domain-Driven Design Reference: Definitions and Pattern Summaries. Dog
Ear Publishing, LLC, Sep. 2014.
[24] E. Folmer and J. Bosch, “Architecting for Usability: A Survey,” Journal of Systems and
Software, vol. 70, no. 1–2, pp. 61–78, Feb. 2004.
[25] M. Fowler and T. White, Domain-Specific Languages. Addison-Wesley Professional,
Sep. 2010.
[26] A. Fuggetta and E. Di Nitto, “Software Process,” in Proceedings of the on Future of Software Engineering, ser. FOSE 2014. New York, NY, USA: ACM, 2014, pp. 1–12.
[27] E. Gamma et al., Design Patterns: Elements of Reusable Object-Oriented Software,
1st ed. Reading, Mass: Addison-Wesley Professional, Nov. 1994.
[28] J. Gosling et al., The Java Language Specification, Java SE 8 Edition, 1st ed. Upper
Saddle River, NJ: Addison-Wesley Professional, May 2014.
[29] J. Gosling et al., The Java Language Specification: Java SE 9 Edition. California,
USA: Oracle America, Inc., Aug. 2017.
[30] C. Guindon, “Eclipse OCL (Object Constraint Language),” Jan. 2013.
[31] W. Harrison et al., “Mapping UML Designs to Java,” in Proc. 15th ACM SIGPLAN Conf. on Object-oriented Programming, Systems, Languages, and Applications, ser. OOPSLA ’00. New York, NY, USA: ACM, 2000, pp. 178–187.
[32] J. Hatcliff et al., “Behavioral Interface Specification Languages,” ACM Comput. Surv.,
vol. 44, no. 3, pp. 16:1–16:58, Jun. 2012.
[33] A. Hejlsberg et al., The C# Programming Language, 4th ed. Upper Saddle River, NJ:
Addison Wesley, Oct. 2010.
[34] J. A. Hoffer et al., Modern Systems Analysis and Design, 7th ed. Boston: Prentice
Hall, Feb. 2013.
152
[35] J. A. Hoffer et al., Modern Database Management, 12nd ed. Boston: Pearson, Jul.
2015.
[36] P. Hudak, “Modular Domain Specific Languages and Tools,” in Proc. 5th Int. Conf. on
Software Reuse, Jun. 1998, pp. 134–142.
[37] J. Juneau, “Java Modularity,” in Java 9 Recipes: A Problem-Solution Approach,
J. Juneau, Ed. Berkeley, CA: Apress, 2017, pp. 605–614.
[38] S. Kent, “Model Driven Engineering,” in Integrated Formal Methods, ser. Lecture Notes Springer Berlin Heidelberg, May 2002,
in Computer Science, M. Butler et al., Eds. no. 2335, pp. 286–298.
[39] A. Kleppe, Software Language Engineering: Creating Domain-Specific Languages Using Metamodels, 1st ed. Upper Saddle River, NJ: Addison-Wesley Professional, Dec. 2008.
[40] T. Kosar et al., “Domain-Specific Languages: A Systematic Mapping Study,” Informa-
tion and Software Technology, vol. 71, pp. 77–91, Mar. 2016.
[41] G. E. Krasner and S. T. Pope, “A Description of the Model-View-Controller User Inter- face Paradigm in the Smalltalk-80 System,” Journal of object-oriented programming, vol. 1, no. 3, pp. 26–49, 1988.
[42] A. v. Lamsweerde, “Formal Specification: A Roadmap,” in Proceedings of the Confer- ence on The Future of Software Engineering, ser. ICSE ’00. New York, NY, USA: ACM, 2000, pp. 147–159.
[43] C. Larman, Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development, 3rd ed. Upper Saddle River, NJ, USA: Prentice Hall PTR, 2004.
[44] D. M. Le, “A Domain-Oriented, Java Specification Language,” in Proc. 7th Int. Conf.
IEEE, Oct. 2015, pp. 25–30. Knowledge and Systems Engineering (KSE).
IEEE, Oct. 2015, pp. 19–24. [45] D. M. Le, “A Tree-Based, Domain-Oriented Software Architecture for Interactive Object-Oriented Applications,” in Proc. 7th Int. Conf. Knowledge and Systems En- gineering (KSE).
153
[46] G. T. Leavens, “JML Reference Manual,” Tech. Rep., 2013.
[47] G. T. Leavens et al., “Preliminary Design of JML: A Behavioral Interface Specification
Language for Java,” SIGSOFT Softw. Eng. Notes, vol. 31, no. 3, pp. 1–38, May 2006.
[48] B. Liskov and J. Guttag, Abstraction and specification in program development. MIT
Press, 1986.
[49] B. Liskov and J. Guttag, Program Development in Java: Abstraction, Specification, and
Object-Oriented Design. Pearson Education, 2000.
[50] M. Mernik et al., “When and How to Develop Domain-specific Languages,” ACM
Comput. Surv., vol. 37, no. 4, pp. 316–344, Dec. 2005.
[51] B. Meyer, Object-Oriented Software Construction, 2nd ed. Santa Barbara (California):
ISE Inc., 1997.
[52] S. Millett and N. Tune, Patterns, Principles, and Practices of Domain-Driven Design.
John Wiley & Sons, Apr. 2015.
[53] M. Nosál and J. Porubän, “XML To Annotations Mapping Definition With Patterns,” Computer Science and Information Systems, vol. 11, no. 4, pp. 1455–1477, 2014.
[54] M. Nosál’ et al., “Language Composition Using Source Code Annotations,” Computer
Science and Information Systems, vol. 13, no. 3, pp. 707–729, 2016.
[55] OMG, “Model Driven Architecture (MDA),” OMG, Tech. Rep. ormsc/2001-07-01, Jul.
2001.
[56] OMG, “Object Constraint Language Version 2.4,” OMG, Tech. Rep. formal/2014-02-03,
2014.
[57] OMG, “Unified Modeling Language version 2.5,” OMG, Tech. Rep. formal/2015-03-01,
2015.
[58] OMG, “Meta Object Facility (MOF) Core Specification,” OMG, Tech. Rep. formal/15-
06-06, Nov. 2016.
[59] Oracle, “Java Persistence API Specification,” 2018.
154
[60] J. Paniza, Learn OpenXava by Example. CreateSpace Independent Publishing Plat-
form, 2011.
[61] Paul Deitel, “Understanding Java 9 Modules,” 2017.
[62] R. Pawson and R. Matthews, “Naked Objects,” in OOPSLA ’02, ser. OOPSLA ’02.
New York, NY, USA: ACM, 2002, pp. 36–37.
[63] Red Hat, “Bean Validation 2.0 (JSR 380),” 2017.
[64] Red Hat, “Hibernate Validator,” 2017.
[65] D. Riehle and H. Züllighoven, “Understanding and Using Patterns in Software Devel-
opment,” Theory Pract. Obj. Syst., vol. 2, no. 1, pp. 3–13, Jan. 1996.
[66] P. Runeson and M. Höst, “Guidelines for Conducting and Reporting Case Study Research in Software Engineering,” Empir Software Eng, vol. 14, no. 2, p. 131, Apr. 2009. URL: http://link.springer.com/article/10.1007/s10664-008-9102-8
[67] D. C. Schmidt, “Model-Driven Engineering,” Computer, vol. 39, pp. 25–31, 2006.
[68] Sculptor Team, “Sculptor - Generating Java Code From DDD-Inspired Textual DSL,”
2016. URL: http://sculptorgenerator.org/
[69] G. Smith, The Object-Z Specification Language, ser. Advances in Formal Methods.
Boston, MA: Springer US, 2000, vol. 1.
[70] I. Sommerville, Software Engineering, 9th ed. Pearson, 2011.
[71] J. M. Spivey, “An Introduction to Z and Formal Specifications,” Software Engineering
Journal, vol. 4, no. 1, pp. 40–50, Jan. 1989.
[72] M. Sulír et al., “Recording Concerns In Source Code Using Annotations,” Computer
Languages, Systems & Structures, vol. 46, pp. 44–65, Nov. 2016.
[73] F. Tomassetti et al., “JavaParser,” 2016. URL: http://javaparser.org/
[74] A. van Deursen et al., “Domain-Specific Languages: An Annotated Bibliography,”
SIGPLAN Not., vol. 35, no. 6, pp. 26–36, Jun. 2000.
155
[75] V. Vernon, Implementing Domain-Driven Design, 1st ed. Upper Saddle River, NJ:
Addison-Wesley Professional, Feb. 2013.
[76] H. Wada and J. Suzuki, “Modeling Turnpike Frontend System: A Model-Driven Devel- opment Framework Leveraging UML Metamodeling and Attribute-Oriented Program- ming,” in Model Driven Engineering Languages and Systems, ser. Lecture Notes in Computer Science, L. Briand and C. Williams, Eds. Springer Berlin Heidelberg, Oct. 2005, no. 3713, pp. 584–600.
[77] J. B. Warmer and A. G. Kleppe, “Building a Flexible Software Factory Using Partial
Domain Specific Models,” Oct. 2006.
[78] J. Warmer, “A Model Driven Software Factory Using Domain Specific Languages,” in Model Driven Architecture- Foundations and Applications. Springer, Berlin, Heidel- berg, Jun. 2007, pp. 194–203.
156
Appendices
157
Appendix A
Helper OCL Functions for DCSL’s ASM
ExprTk
1 context ExprTk :: g e n Li nkRem over PreC ond ( c : Classifier , m : Parameter , y :
Integer ) : String
2
-- return a pre - condition for a link - remover operation depending on m .
type
3
post :
4
5
let ty : Classifier = m . type in let cname : String = c . name . at (1) . toLowerCase () + c . name . substring (2 , c .
name . size () ) in
6
if ty . oclIsKindOf ( CollectionType ) then
7
result = cname + ’ Count - ’+ m . name + ’. size () >= ’ + y
8
else
9
result = cname + ’ Count - 1 >= ’ + y
10
endif
Figure A.1: Utility class ExprTk.
158
11
12 context ExprTk :: g e n L i n kR em o ve r Po st C on d 1 ( a : Field , m : Parameter ) : String
13
-- return post - condition (1) for a link - remover operation depending on m .
type
14
15
pre : a . type . oclIsKindOf ( CollectionType ) post :
16
17
let ty : Classifier = m . type in if ty . oclIsKindOf ( CollectionType ) then
18
result = a . name + ’ = ’+ a . name + ’ @pre - > asSet () - ’+ m . name + ’ - > asSet () ’
19
else
20
result = a . name + ’ = ’+ a . name + ’ @pre - > asSet () - Set { ’+ m . name + ’} ’
21
endif
22
23 context ExprTk :: g e n Li n kR em o ve r Po st C on d 2 ( c : Classifier , a : Field ) : String
24
-- return post - condition (2) for a link - remover operation depending on m .
type
25
26
pre : a . type . oclIsKindOf ( CollectionType ) post :
27
let cname : String = c . name . at (1) . toLowerCase () + c . name . substring (2 , c .
name . size () ) in
28
result = cname + ’ Count = ’+ a . name + ’ - > size () ’
29
30 context ExprTk :: genLi nkAdderPreCond ( c : Classifier , m : Parameter , x :
Integer ) : String
31
32
-- return a pre - condition for a link - adder operation depending on m . type post :
33
34
let ty : Classifier = m . type in let cname : String = c . name . at (1) . toLowerCase () + c . name . substring (2 , c .
name . size () ) in
35
if ty . oclIsKindOf ( CollectionType ) then
36
result = cname + ’ Count + ’+ m . name + ’. size () <= ’ + x
37
else
38
result = cname + ’ Count + 1 <= ’ + x
39
endif
40
41 context ExprTk :: g e n Li nkAdd erPo stCo nd1 ( a : Field , m : Parameter ) : String
42
-- return post - condition (1) for a link - adder operation depending on m .
type
43
44
pre : a . type . oclIsKindOf ( CollectionType ) post :
45
46
let ty : Classifier = m . type in if ty . oclIsKindOf ( CollectionType ) then
47
result = a . name + ’ = ’+ a . name + ’ @pre - > asSet () -> union ( ’+ m . name + ’ - > asSet
() ) ’
159
48
else
49
result = a . name + ’ = ’+ a . name + ’ @pre - > asSet () -> union ( Set { ’+ m . name + ’}) ’
50
endif
51
52 context ExprTk :: g enL i n k Add erPo stCo nd2 ( c : Classifier , a : Field ) : String
53
-- return post - condition (2) for a link - remover operation depending on m .
type
54
55
pre : a . type . oclIsKindOf ( CollectionType ) post : result = g e n Li nk R em o ve rP o st C on d2 (c , a )
Tk
1 context Tk :: isLinkTo ( o1 : Object , a : Field , o2 : Object ) : Boolean
2
3
4
5
-- check if a . value ( o1 ) contains a link to o2 post : let v1 = a . value ( o1 ) in if a . type . oclIsKindOf ( CollectionType ) then v1 - > includes ( o2 ) else v1 = o2
endif
6
7 context Tk :: ancestors ( c : Class ) : Set ( Class )
8
9
10
-- return ancestor classes of c post : if not ( c . gens . oclIsUndefined () ) then
11
result = c . gens - > collect ( g |
12
{ g . super }. union ( ancestors ( g . super ) ) -> excluding ( OclVoid ) ) -> flatten () ->
asSet ()
13
else
14
result = OclVoid
15
endif
Figure A.2: Utility class Tk.
160
Classifier
1 context Classifier
2
-- if this conforms to CollectionType then return elementType else return
self
3
def : elementType () : Classifier =
4
if oclIsKindOf ( CollectionType ) then oclAsType ( CollectionType ) .
elementType else self endif
Class
1 context Class
2
3
-- return all link - remover methods of this def : linkRemovers () : Set ( Method ) =
4
methods - > select ( m | m . opt . type = OptType :: LinkRemover )
5
6
7
-- return all link - adder methods of this def : linkAdders () : Set ( Method ) =
8
methods - > select ( m | m . opt . type = OptType :: LinkAdder )
9
10
11
-- return all overriden methods of this def : overridenMethods () : Set ( Method ) =
12
methods - > select ( m | m . annotations - > select ( n | n . name = ’ Overriden ’) ->
size () = 1)
Method
1 context Method
2
3
-- return the post - condition exprs of a method def : postExps () : Sequence ( OclExpression ) =
4
post . specification . oclAsType ( OpaqueExpression ) .
5
body . oclAsType ( Sequence ( OclExpression ) )
6
7
-- return the pre - condition exprs of a method
8
def : preExps () : Sequence ( OclExpression ) =
9
pre . specification . oclAsType ( OpaqueExpression ) .
10
body . oclAsType ( Sequence ( OclExpression ) )
11
12
13
14
-- return the result expression of the form " result = ..." def : resultExp () : OclExpression = if postExps () -> size () = 1 and
161
15
16
postExps () -> any ( true ) . oclIsType ( VarAssi gnExpre ss io n ) then postExps () -> any ( true ) . oclAsType ( VarAssi gnExpre ss io n )
17
else
18
OclVoid
19
endif
20
21
22
23
-- is this an overriden method def : isOverriden () : Boolean = ( annotations - > select ( n | n . name = ’
Overriden ’) -> size () = 1)
24
25
26
-- is this the mutator method def : isAttrRef ( a : Field ) : Boolean = ( ref . value = a . name )
27
28
29
-- is this a creator method or a mutator method that references a ? def : i sCr e a tor Or M ut ato r Ref ( a : Field ) : Boolean =
30
isCreatorRef ( a ) or isMutatorRef ( a )
31
32
33
-- is this a creator method that contains a parameter referencing a ? def : isCreatorRef ( a : Field ) : Boolean =
34
isCreator () and params - > exists ( isAttrRef ( a ) )
35
36
37
-- is this a mutator method that contains a parameter referencing a ? def : isMutatorRef ( a : Field ) : Boolean =
38
isMutator () and params - > exists ( isAttrRef ( a ) ) )
39
40
41
-- is this the creator method def : isCreator () : Boolean = ( opt . type = OptType :: Creator )
42
43
44
-- is this the mutator method def : isMutator () : Boolean = ( opt . type = OptType :: Mutator )
Parameter
1 context Parameter
2
3
-- does this reference a ? def : isAttrRef ( a : Field ) : Boolean = ( ref . value = a . name )
Field
1 context f : Field
2
-- determine if a field has numeric type
162
3
def : isNumericType () : Boolean =
4
let tyn : String = f . type . name in
5
tyn = ’ Integer ’ or tyn = ’ Real ’ or tyn = ’ UnlimitedNatural ’
DAttr
1 context DAttr
2
3
-- does this preserve another DAttr ? def : preserves ( r : DAttr ) : Boolean =
4
mutable = r . mutable and optional = r . optional and unique = r . unique and
id = r . id and
5
6
7
auto = r . auto and length <= r . length and min <> Double :: INFINITY implies min >= r . min and max <> Double :: INFINITY implies max <= r . max
OclExpression
1 context e : OclExpression
2
3
-- check if the string representation of this is equal to the argument def : equals ( s : String ) : Boolean =
4
e . toString () . equals ( s )
163
Appendix B
MCCL Specification
B.1 Library Rules of the MCCL’s ASM
ModuleConfig
1 context ModuleConfig
2
-- if this is a composite module then return the set of ModuleConfigs of
the
3
4
5
6
7
-- descendant modules else return {} ( empty set ) . -- ( this does not depend on whether contTree is specified or not ) def : descMods () : Set ( ModuleConfig ) = if isComposite () then
8
let G : Set ( ModuleConfig ) = model . domainClass . assocFields - > collect ( f |
9
MCCModel :: getInstance () :: lookUpModuleCfg ( f . type ) ) -> asSet ()
10
11
in G . union (G - > iterate ( g ; G1 : Set ( Set ( ModuleConfig ) ) = Set {}) |
12
G1 - > including ( descMods ( g ) ) ) -> flatten ()
13
14
15
else {} endif
16
17
-- if g is composite then return the ModuleConfigs of the descendant
modules
18
19
20
-- else return {} def : descMods ( g : ModuleConfig ) : Set ( ModuleConfig ) = if g . isComposite () then
R28
164
21
g . descMods ()
22
23
24
else {} endif
25
26
27
28
29
-- return the ModuleConfig of the descendant module of this in t whose -- domain class is mapped to n def : getDescModuleOf ( n : Node ) : ModuleConfig = descMods () -> select ( model . domainClass = n . dclass ) -> any ()
30
31
32
-- if this is a composite module return true else return false def : isComposite () : Boolean = model . domainClass . assocFields - > notEmpty ()
Class
1 context Class
2
3
4
-- if self contains domain fields then return them as Set else return {} def : domFields () : Set ( Field ) = fields - > select ( f | not ( f . atr . oclIsUndefined () ) )
5
6
-- if self contains a domain field whose name is n then return it else
return OclVoid
7
8
def : getDomField ( n : String ) : Field = let F : Set ( Field ) = fields - > select ( f | not ( f . atr . oclIsUndefined () ) and f
. name = n )
9
10
in if F - > notEmpty () then F - > any () else OclVoid endif
11
12
-- if self contains associative domain fields then return them as Set
else return {}
13
14
def : assocFields () : Set ( Field ) = fields - > select ( f | not ( f . atr . oclIsUndefined () ) and not ( f . asc .
oclIsUndefined () ) )
15
16
17
-- whether or not self is a domain class ( i . e . is defined with DClass ) def : isDomainClass () : Boolean = not ( dcl . oclIsUndefined () )
R29
165
Containment Tree
1 context Tree
2
3
4
5
-- determines if there is a path ( i . e . a sequence of edges ) that -- connect n1 to n2 ( in either direction ) def : hasPath ( n1 : Node , n2 : Node ) : Boolean = edges - > exists (( parent = n1 and child = n2 ) or ( parent = n2 and child = n1
) )
6
7
or nodes - > exists ( n3 | hasPath ( n1 , n3 ) and hasPath ( n3 , n2 ) )
R30
1 context Tree
2
-- return set of pairs ( n : Node , s : String ) such that n is the root or
a child node
3
-- and s is the containment scope string of n . edge or of the ScopeConfig
of the Edge
4
5
6
-- in which n is the child def : getContScopes () : Set ( Tuple ( n : Node , s : String ) ) = let C : Set ( Tuple ( n : Node , s : String ) ) =
7
edges - > select ( e | not ( e . scope . stateScope . oclIsUndefined () ) )
8
-> collect ( e | Tuple { n = e . child , s = e . scope . stateScope } ) ->
asSet ()
9
10
11
in if not ( root . stateScope . oclIsUndefined () ) then
12
{ Tuple { n = root , s = root . stateScope }. union ( C )
13
14
15
else C endif
R31
Tk
1 context Tk :: parseContScope ( s : String ) : Set ( String ) 2 -- if s contains ‘,’ then split s into elements ( using ‘,’ as separator ) 3 -- and return them as Set , else return { s } 4 pre : s . indexOf ( ‘ , ’) > 0 implies s . size () >= 3 5 post :
6
result = splitStr (s , ‘ , ’)
R32
166
1 context Tk :: splitStr ( s : String , p : String ) : Set ( String ) 2 -- if s contains p then split s into elements ( using p as separator ) 3 -- and return them as Set , else return { s } 4 pre : p . size () = 1 and ( s . indexOf ( p ) > 0 implies s . size () >= 3) 5 post :
6
7
8
let i : Integer = s . indexOf ( p ) in if i > 0 then
9
result = splitStr ( s . substring (0 ,i -1) , p ) . union (
10
splitStr ( s . substring ( i +1 , s . size () ) ,p ) )
11
else
12
result = { s }
13
endif
R33
MCCModel
In the next OCL rule, we assume the existence of the attribute MCCModel.mcfgs whose type is Set(ModuleConfig). This attribute records all the ModuleConfigs of all the software modules.
1 context MCCModel
2
3
4
-- return the ModuleConfig of the owner module of c def : lo ok UpMo duleC onfig ( c : Class ) : ModuleConfig = mcfgs - > select ( model . domainClass = c ) -> any ()
R34
B.2 Two MCCs of ModuleEnrolmentMgmt
1
2
3
4
@ ModuleDesc ( name = " Mo du leEnr olm e nt M gmt " , modelDesc = @ ModelDesc ( model = EnrolmentMgmt . class ) , viewDesc = @ ViewDesc ( formTitle = " Manage Enrolment Management " , imageIcon = "
enrolment . jpg " ,
5
6
7
8
domainClassLabel = " Enrolment Management " , view = View . class , parentMenu = RegionName . Tools , topX =0.5 , topY =0.0) , controllerDesc = @ ControllerDesc ( controller = Controller . class ) , containmentTree = @CTree ( root = EnrolmentMgmt . class ,
Listing B.1: The MCC of ModuleEnrolmentMgmt with containment tree
167
9
edges ={
10
11
12
13
14
// enrolmentmgmt -> student @CEdge ( parent = EnrolmentMgmt . class , child = Student . class , scopeDesc = @ ScopeDesc ( stateScope ={ " id " , " name " , " helpRequested " , " modules " } ) ) })
15
16
) public class Mod uleEnr olmentMgmt {
17
18
@ AttributeDesc ( label = " Enrolment Management " ) private String title ;
19
20
21
22
23
24
25
26
// student registration @ AttributeDesc ( label = " Student Registration " , layoutBuil derType = T w o Col um nL ay out Bu il der . class , controllerDesc = @ ControllerDesc ( openPolicy = OpenPolicy . I // support many - many association with CourseModule , props ={
27
28
29
// custom Create : to create { @link Enrolment } from the course modules @ PropertyDesc ( name = PropertyName . controller_dataController_create , valueIsClass = C r e a t e O b j e c t A n d M a n y A s s o c i a t e s D a t a C o n t r o l l e r C o m m a n d . class
,
30
31
valueAsString = MetaConstants . NullValue , valueType = Class . class ) , // custom Update command : to update { @link Enrolment } from the course
modules
32
33
@ PropertyDesc ( name = PropertyName . controller_dataController_update , valueIsClass = U p d a t e O b j e c t A n d M a n y A s s o c i a t e s D a t a C o n t r o l l e r C o m m a n d . class
,
34
valueAsString = MetaConstants . NullValue , valueType = Class . class )
35
36
37
}) ) private Collection < Student > students ;
38
39
40
41
// help desk @ AttributeDesc ( label = " Help Request " , type = DefaultPanel . class ) private Collection < HelpRequest > helpDesks ;
42
43
44
45
// class registration @ AttributeDesc ( label = " Class Registration " , type = DefaultPanel . class ) private Collection < SClassRegistration > sclassRegists ;
46
}
168
1
2
3
4
@ ModuleDesc ( name = " M odu l eEn r olm e ntM g mt2 " , modelDesc = @ ModelDesc ( model = EnrolmentMgmt . class ) , viewDesc = @ ViewDesc ( formTitle = " Manage Enrolment Management " , imageIcon = "
enrolment . jpg " ,
5
6
7
8
9
domainClassLabel = " Enrolment Management " , view = View . class , parentMenu = RegionName . Tools , topX =0.5 , topY =0.0) , controllerDesc = @ ControllerDesc ( controller = Controller . class ) , containmentTree = @CTree ( root = EnrolmentMgmt . class , edges ={
10
11
12
13
14
15
// enrolmentmgmt -> student @CEdge ( parent = EnrolmentMgmt . class , child = Student . class , scopeDesc = @ ScopeDesc ( stateScope ={ " id " , " name " , " helpRequested " , " modules " } // custom configuration for ModuleStudent , attribDescs ={
16
17
18
// Student . name is not editable @ AttributeDesc ( id = " id " , type = JLabelField . class ) , @ AttributeDesc ( id = " name " , type = JLabelField . class , editable = false ) ,
19
20
}) ) } )
21
22
) public class Mo d ule E nrolmentMgmt2 {
23
24
@ AttributeDesc ( label = " Enrolment Management " ) private String title ;
25
26
27
28
29
30
31
32
// student registration @ AttributeDesc ( label = " Student Registration " , layoutBuil derType = T w o Col um nL ay out Bu il der . class , controllerDesc = @ ControllerDesc ( openPolicy = OpenPolicy . I // support many - many association with CourseModule , props ={
33
34
35
// custom Create : to create { @link Enrolment } from the course modules @ PropertyDesc ( name = PropertyName . controller_dataController_create , valueIsClass = C r e a t e O b j e c t A n d M a n y A s s o c i a t e s D a t a C o n t r o l l e r C o m m a n d . class
, valueAsString = MetaConstants . NullValue , valueType = Class . class ) ,
36
37
38
// custom Update : to update { @link Enrolment } from the course modules @ PropertyDesc ( name = PropertyName . controller_dataController_update , valueIsClass = U p d a t e O b j e c t A n d M a n y A s s o c i a t e s D a t a C o n t r o l l e r C o m m a n d . class , valueAsString = MetaConstants . NullValue , valueType = Class . class )
Listing B.2: The MCC of ModuleEnrolmentMgmt with custom subview configuration for a descendant module of type ModuleStudent
169
39
40
41
}) ) private Collection < Student > students ;
42
43
44
45
// help desk @ AttributeDesc ( label = " Help Request " , type = DefaultPanel . class ) private Collection < HelpRequest > helpDesks ;
46
47
48
49
// class registration @ AttributeDesc ( label = " Class Registration " , type = DefaultPanel . class ) private Collection < SClassRegistration > sclassRegists ;
50
}
170
Appendix C
DCSL Evaluation Data
C.1 Expressiveness Comparison Between DCSL and the
DDD Frameworks
Table C.1: Comparing the expressiveness of DCSL to AL, XL
DCSL AL XL
DClass
– mutable DomainObject.editing
DAttr
- unique
optional Required
- mutable – (i) jdo(ii).Column.allowsNull, (Property.optionality) Property.editing
id
jpa.Id – (iii) auto
length jpa(iv).Column.length
jdo.PrimaryKey.value – jdo.Column.length, (Property.maxLength) – min
– max Min(v).value Max(v).value
DAssoc
171
– ascName
– ascType
– jpa.OneToMany, jpa.ManyToOne, jpa.ManyToMany – – role
– – endType
– – associate.type
– – associate.cardMin
– – associate.cardMax
DOpt
– – type
– – requires
– – effects
AttrRef
– – value
(i) AL supports property Property.mustSatisfy which may be used to implement the
constraint.
(ii) Java Data Objects (JDO) [18].
(iii) XL supports property ha.Formula that may be use to implement formula for value
generation function.
(iv) Java Persistence API (JPA) [59].
(v) Bean Validator (BV) [63].
172
C.2 Level of Coding Comparison Between DCSL and the
DDD Frameworks
Table C.2: Comparing the max-locs of DCSL to AL, XL
AL XL DCSL Domain Class
DClass.mutable DomainObject.editing, autoCompleteRepository Entity, EntityValidator.value Domain Field
DAttr.length, min, max Column.allowsNull, name, one-of { length, scale }, jdbcType Required, one-of { Column.length, scale }, PropertyValidator.value, Min.value, Max.value, SearchKey
– one-of { OneToMany, ManyToOne, ManyToMany}
Associative Field DAssoc.ascName, ascType, role, endType; associate.type, associate.cardMin, associate.cardMax
173
Table C.3: Comparing the typical-locs of DCSL to AL, XL
DCSL AL XL Domain Class
DClass.mutable DomainObject.editing, autoCompleteRepository Entity, EntityValidator.value Domain Field
one-of { DAttr.length, min, max } one-of { Column.length, scale } one-of { Column.length, Column.scale, Min.value, Max.value }
– one-of { OneToMany, ManyToOne, ManyToMany}
Associative Field DAssoc.ascName, ascType, role, endType; associate.type, associate.cardMin, associate.cardMax
174