Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 193 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
193
Dung lượng
6,8 MB
Nội dung
Vietnam National University, Hanoi VNU University of Engineering and Technology LE MINH DUC u iệ il Tà A Unified View Approach to Software Development Automation U VN 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 u iệ il Tà 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 U VN 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 Tà u iệ il Specialisation: Software Engineering Code: 9480103.01 U VN Doctor of Philosophy Dissertation in Information Technology Supervisors: Assoc Prof., Dr Nguyen Viet Ha 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 il Tà u iệ Chuyên ngành: Kỹ thuật Phần mềm Mã số: 9480103.01 U VN LUẬN ÁN TIẾN SĨ NGÀNH CÔNG NGHỆ THÔNG TIN NGƯỜI HƯỚNG DẪN KHOA HỌC: PGS TS Nguyễn Việt Hà TS Đặng Đức Hạnh Hà Nội – 2020 Declaration u iệ il Tà 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 U VN Le Minh Duc Abstract u iệ il Tà 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 U VN u iệ il Tà 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 configurations 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 language 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 U VN 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 mơ hình lên phương pháp luận quan trọng kỹ nghệ phần mềm Ở trung tâm phương pháp luận có hai phương pháp có tính bổ trợ là: kỹ nghệ phần mềm hướng mơ hình (model-driven software engineering (MDSE)) thiết kế hướng miền (domain-driven design (DDD)) Trong MDSE mang mục tiêu Tà rộng tham vọng mục tiêu DDD lại khiêm tốn thực tế hơn, tập trung vào cách áp dụng kỹ thuật kỹ nghệ dựa mô hình để giải il iệ phức tạp vốn có yêu cầu miền Phương pháp DDD bao gồm u tập nguyên lý để xây dựng mơ hình miền dạng khả thi cho triển khai viết VN mã ngôn ngữ lập trình đích Tuy nhiên phương pháp cịn thiếu giải U 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 áp dụng DDD vào tảng ngơn ngữ lập trình hướng đối tượng (object oriented programming language (OOPL)): (i) thành phần cấu tạo nên mơ hình miền có mức độ diễn đạt thiết yếu? (ii) xây dựng cách hiệu phần mềm từ mơ hình miền nào? Luận án đặt mục đích khắc phục hạn chế DDD cách sử dụng ngôn ngữ chuyên biệt miền dựa ghi (annotation-based domain-specific language (aDSL)), phát triển OOPL, để không biểu diễn mô hình miền hợp 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 Thứ nhất, luận án đề xuất aDSL, tên ngôn ngữ đặc tả lớp miền (domain class specification language (DCSL)), bao gồm tập ghi để biểu diễn ràng buộc cấu trúc thiết yếu hành vi thiết yếu lớp miền Tác giả cẩn thận lựa chọn đặc trưng thiết kế từ số nguồn tài liệu học thuật có uy tín kỹ nghệ phần mềm kỹ nghệ hệ thống lập luận đặc trưng tạo thành không gian thiết kế tối giản cho lớp miền Thứ hai, luận án đề xuất phương thức tiếp cận mơ hình hóa miền hợp nhất, sử dụng DCSL để biểu diễn thành phần mô hình hóa cấu trúc 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 trình bày cách biểu diễn đặc trưng chuyên biệt trạng thái ngôn ngữ DCSL Để chứng tỏ tính thực tiễn cách tiếp cận, luận án định nghĩa tập mẫu mơ hình hóa miền hợp cho tốn thiết kế liên quan trực tiếp đến năm luồng hoạt động UML Thứ ba, luận án đề xuất mơ tả đặc điểm gồm bốn tính chất cho phần mềm xây dựng trực tiếp từ mơ hình miền Bốn tính chất định nghĩa dựa 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, Tà lớp mô-đun trực tiếp bao quanh lớp lõi lớp phần mềm il Thứ tư, luận án đề xuất aDSL thứ hai, tên ngôn ngữ lớp cấu hình mơ-đun u iệ (module configuration class language (MCCL)), dùng để thiết kế lớp cấu hình mơ-đun (module configuration classes (MCCs)) kiến trúc phần mềm dựa VN mô-đun Mỗi MCC cung cấp định nghĩa dạng lớp cho tập cấu hình U mơ-đun lớp mơ-đun Các MCC dễ dàng sử dụng lại để tạo biến thể lớp mô-đun mà không cần sửa thiết kế bên mô-đun Thứ năm, luận án phát triển công cụ dành cho DCSL, MCCL sinh mã ngôn ngữ này, dạng thành phần phần mềm khung, tên JDOMAINAPP Để đánh giá kết trên, luận án trước hết trình diễn tính thực tiễn phương pháp cách áp dụng vào trường hợp nghiên cứu tương đối phức tạp 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 ngơn ngữ đặc tả đánh giá hiệu việc sử dụng MCCL xây dựng mô-đun phần mềm cách tự động Chúng tơi cho rằng, đóng góp luận án giúp phương pháp DDD trở nên cụ thể đầy đủ Một mặt, phương pháp trở nên cụ thể với giải pháp giúp áp dụng cách hiệu vào tảng OOPL Mặt khác, phương pháp trở nên đầy đủ với giải pháp cho khía cạnh thiết kế chưa xem xét tới Acknowledgement u iệ il Tà 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 U VN 48 else result = a name + ’ = ’+ a name + ’ @pre - > asSet () -> union ( Set { ’+ m name + ’}) ’ endif 49 50 51 52 53 54 55 context ExprTk :: g enLi nkAdd erPo stCo nd2 ( c : Classifier , a : Field ) : String return post - condition (2) for a link - remover operation depending on m type pre : a type oclIsKindOf ( CollectionType ) post : result = ge n Li nk R em o ve rP o st C on d2 (c , a ) Tk u iệ il Tà U VN Figure A.2: Utility class Tk context Tk :: isLinkTo ( o1 : Object , a : Field , o2 : Object ) : Boolean 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 10 11 12 13 14 15 context Tk :: ancestors ( c : Class ) : Set ( Class ) return ancestor classes of c post : if not ( c gens oclIsUndefined () ) then result = c gens - > collect ( g | { g super } union ( ancestors ( g super ) ) -> excluding ( OclVoid ) ) -> flatten () -> asSet () else result = OclVoid endif 160 Classifier context Classifier if this conforms to CollectionType then return elementType else return self def : elementType () : Classifier = if oclIsKindOf ( CollectionType ) then oclAsType ( CollectionType ) elementType else self endif Class context Class return all link - remover methods of this def : linkRemovers () : Set ( Method ) = methods - > select ( m | m opt type = OptType :: LinkRemover ) Tà u iệ return all link - adder methods of this def : linkAdders () : Set ( Method ) = methods - > select ( m | m opt type = OptType :: LinkAdder ) il 11 U 12 return all overriden methods of this def : overridenMethods () : Set ( Method ) = methods - > select ( m | m annotations - > select ( n | n name = ’ Overriden ’) -> size () = 1) VN 10 Method context Method return the post - condition exprs of a method def : postExps () : Sequence ( OclExpression ) = post specification oclAsType ( OpaqueExpression ) body oclAsType ( Sequence ( OclExpression ) ) 10 return the pre - condition exprs of a method def : preExps () : Sequence ( OclExpression ) = pre specification oclAsType ( OpaqueExpression ) body oclAsType ( Sequence ( OclExpression ) ) 11 12 13 14 return the result expression of the form " result = " def : resultExp () : OclExpression = if postExps () -> size () = and 161 15 postExps () -> any ( true ) oclIsType ( VarAssignExpression ) then postExps () -> any ( true ) oclAsType ( VarAssignExpression ) else OclVoid endif 16 17 18 19 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 30 is this a creator method or a mutator method that references a ? def : i sCre ator OrMut ator Ref ( a : Field ) : Boolean = isCreatorRef ( a ) or isMutatorRef ( a ) Tà 31 32 iệ 34 is this a creator method that contains a parameter referencing a ? def : isCreatorRef ( a : Field ) : Boolean = isCreator () and params - > exists ( isAttrRef ( a ) ) il 33 36 38 is this a mutator method that contains a parameter referencing a ? def : isMutatorRef ( a : Field ) : Boolean = isMutator () and params - > exists ( isAttrRef ( a ) ) ) U VN 37 u 35 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 context Parameter does this reference a ? def : isAttrRef ( a : Field ) : Boolean = ( ref value = a name ) Field context f : Field determine if a field has numeric type 162 def : isNumericType () : Boolean = let tyn : String = f type name in tyn = ’ Integer ’ or tyn = ’ Real ’ or tyn = ’ UnlimitedNatural ’ DAttr context DAttr does this preserve another DAttr ? def : preserves ( r : DAttr ) : Boolean = mutable = r mutable and optional = r optional and unique = r unique and id = r id and auto = r auto and length = r and max Double :: INFINITY implies max collect ( f | MCCModel :: getInstance () :: lookUpModuleCfg ( f type ) ) -> asSet () in G union (G - > iterate ( g ; G1 : Set ( Set ( ModuleConfig ) ) = Set {}) | G1 - > including ( descMods ( g ) ) ) -> flatten () else {} endif VN u iệ il R28 Tà ModuleConfig 16 17 18 19 20 if g is composite then return the ModuleConfigs of the descendant modules else return {} def : descMods ( g : ModuleConfig ) : Set ( ModuleConfig ) = if g isComposite () then 164 21 g descMods () else {} endif 22 23 24 25 26 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 () 27 28 29 30 31 if this is a composite module return true else return false def : isComposite () : Boolean = model domainClass assocFields - > notEmpty () 32 Class 10 if self contains a domain field whose name is n then return it else return OclVoid def : getDomField ( n : String ) : Field = let F : Set ( Field ) = fields - > select ( f | not ( f atr oclIsUndefined () ) and f name = n ) in if F - > notEmpty () then F - > any () else OclVoid endif U VN u iệ context Class if self contains domain fields then return them as Set else return {} def : domFields () : Set ( Field ) = fields - > select ( f | not ( f atr oclIsUndefined () ) ) il Tà R29 11 12 13 14 if self contains associative domain fields then return them as Set else return {} 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 () ) 165 Containment Tree R30 context Tree 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 )) or nodes - > exists ( n3 | hasPath ( n1 , n3 ) and hasPath ( n3 , n2 ) ) R31 11 12 13 14 15 U 10 VN u iệ il Tà context Tree return set of pairs ( n : Node , s : String ) such that n is the root or a child node and s is the containment scope string of n edge or of the ScopeConfig of the Edge in which n is the child def : getContScopes () : Set ( Tuple ( n : Node , s : String ) ) = let C : Set ( Tuple ( n : Node , s : String ) ) = edges - > select ( e | not ( e scope stateScope oclIsUndefined () ) ) -> collect ( e | Tuple { n = e child , s = e scope stateScope } ) -> asSet () in if not ( root stateScope oclIsUndefined () ) then { Tuple { n = root , s = root stateScope } union ( C ) else C endif Tk R32 context Tk :: parseContScope ( s : String ) : Set ( String ) if s contains ‘,’ then split s into elements ( using ‘,’ as separator ) and return them as Set , else return { s } pre : s indexOf ( ‘ , ’) > implies s size () >= post : result = splitStr (s , ‘ , ’) 166 R33 10 11 12 13 context Tk :: splitStr ( s : String , p : String ) : Set ( String ) if s contains p then split s into elements ( using p as separator ) and return them as Set , else return { s } pre : p size () = and ( s indexOf ( p ) > implies s size () >= 3) post : let i : Integer = s indexOf ( p ) in if i > then result = splitStr ( s substring (0 ,i -1) , p ) union ( splitStr ( s substring ( i +1 , s size () ) ,p ) ) else result = { s } endif Tà MCCModel u iệ il 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 R34 context MCCModel return the ModuleConfig of the owner module of c def : lookUpModuleConfig ( c : Class ) : ModuleConfig = mcfgs - > select ( model domainClass = c ) -> any () B.2 U VN Two MCCs of ModuleEnrolmentMgmt Listing B.1: The MCC of ModuleEnrolmentMgmt with containment tree @ ModuleDesc ( name = " ModuleEnrolmentMgmt " , modelDesc = @ ModelDesc ( model = EnrolmentMgmt class ) , viewDesc = @ ViewDesc ( formTitle = " Manage Enrolment Management " , imageIcon = " enrolment jpg " , 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 , 167 10 11 12 13 14 15 16 17 18 edges ={ // enrolmentmgmt -> student @CEdge ( parent = EnrolmentMgmt class , child = Student class , scopeDesc = @ ScopeDesc ( stateScope ={ " id " , " name " , " helpRequested " , " modules " } ) ) }) ) public class ModuleEnrolmentMgmt { @ AttributeDesc ( label = " Enrolment Management " ) private String title ; 19 20 // student registration @ AttributeDesc ( label = " Student Registration " , layoutBuilderType = T wo Col um nL ay out Bu il der class , controllerDesc = @ ControllerDesc ( openPolicy = OpenPolicy I // support many - many association with CourseModule , props ={ // 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 ) , // custom Update command : 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 ) }) ) private Collection < Student > students ; 21 22 23 24 25 Tà 26 27 il 28 iệ 29 u 30 VN 31 U 32 33 34 35 36 37 38 39 // help desk @ AttributeDesc ( label = " Help Request " , type = DefaultPanel class ) private Collection < HelpRequest > helpDesks ; 40 41 42 43 // class registration @ AttributeDesc ( label = " Class Registration " , type = DefaultPanel class ) private Collection < SClassRegistration > sclassRegists ; 44 45 46 } 168 Listing B.2: The MCC of ModuleEnrolmentMgmt with custom subview configuration for a descendant module of type ModuleStudent 10 11 12 13 15 18 23 24 U 22 VN 20 21 u 19 iệ 17 il 16 Tà 14 @ ModuleDesc ( name = " ModuleEnrolmentMgmt2 " , modelDesc = @ ModelDesc ( model = EnrolmentMgmt class ) , viewDesc = @ ViewDesc ( formTitle = " Manage Enrolment Management " , imageIcon = " enrolment jpg " , 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 ={ // enrolmentmgmt -> student @CEdge ( parent = EnrolmentMgmt class , child = Student class , scopeDesc = @ ScopeDesc ( stateScope ={ " id " , " name " , " helpRequested " , " modules " } // custom configuration for ModuleStudent , attribDescs ={ // Student name is not editable @ AttributeDesc ( id = " id " , type = JLabelField class ) , @ AttributeDesc ( id = " name " , type = JLabelField class , editable = false ) , }) )} ) ) public class ModuleEnrolmentMgmt2 { @ AttributeDesc ( label = " Enrolment Management " ) private String title ; 25 26 27 28 29 30 31 32 33 34 35 36 37 38 // student registration @ AttributeDesc ( label = " Student Registration " , layoutBuilderType = T wo Col um nL ay out Bu il der class , controllerDesc = @ ControllerDesc ( openPolicy = OpenPolicy I // support many - many association with CourseModule , props ={ // 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 ) , // 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 ) 169 39 }) ) private Collection < Student > students ; 40 41 42 43 // help desk @ AttributeDesc ( label = " Help Request " , type = DefaultPanel class ) private Collection < HelpRequest > helpDesks ; 44 45 46 47 // class registration @ AttributeDesc ( label = " Class Registration " , type = DefaultPanel class ) private Collection < SClassRegistration > sclassRegists ; 48 49 50 } u iệ il Tà U VN 170 Appendix C DCSL Evaluation Data C.1 Expressiveness Comparison Between DCSL and the Tà iệ il DDD Frameworks u Table C.1: Comparing the expressiveness of DCSL to AL, XL VN DCSL AL U DClass XL mutable DomainObject.editing – unique – (i) - optional jdo Column.allowsNull, (Property.optionality) Required mutable Property.editing - id jdo.PrimaryKey.value jpa.Id auto – – (iii) length jdo.Column.length, (Property.maxLength) jpa(iv) Column.length – Min(v) value max – Max(v) value DAttr (ii) DAssoc 171 – – ascType – jpa.OneToMany, jpa.ManyToOne, jpa.ManyToMany role – – endType – – associate.type – – associate.cardMin – – associate.cardMax – – type – – requires – – – – – – ascName DOpt AttrRef value u iệ il Tà effects (ii) Java Data Objects (JDO) [18] U VN (i) AL supports property Property.mustSatisfy which may be used to implement the constraint (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 DCSL Domain Class DClass.mutable AL XL DomainObject.editing, autoCompleteRepository Entity, EntityValidator.value Column.allowsNull, name, one-of { length, scale }, jdbcType Required, one-of { Column.length, scale }, PropertyValidator.value, Min.value, Max.value, SearchKey Domain Field DAttr.length, min, max u iệ il Tà – U VN Associative Field DAssoc.ascName, ascType, role, endType; associate.type, associate.cardMin, associate.cardMax 173 one-of { OneToMany, ManyToOne, ManyToMany} Table C.3: Comparing the typical-locs of DCSL to AL, XL XL DomainObject.editing, autoCompleteRepository Entity, EntityValidator.value one-of { Column.length, Column.scale, Min.value, Max.value } Domain Field U VN Associative Field DAssoc.ascName, ascType, role, endType; associate.type, associate.cardMin, associate.cardMax one-of { Column.length, scale } u one-of { DAttr.length, min, max } il Tà DClass.mutable AL iệ DCSL Domain Class – 174 one-of { OneToMany, ManyToOne, ManyToMany}