Ngày nay phát triển hƣớng mô hình đã đƣợc quan tâm và nghiên cứu nhiều hơn, cũng bởi vậy mà nhiều công cụ chuyển đổi mô hình theo hƣớng tiếp cận MDA ra đời. Trong khuôn khổ của luận văn này, tôi xin đƣợc đề cập đến một số công cụ phổ biến nhƣ sau:
3.2.1 EMF - Eclipse Modeling Framework
Khung mô hình hoá Eclipse (EMF) [7] là một bộ khung sinh mã mã mạnh mẽ hƣớng đến xây dựng các ứng dụng Java dựa trên định nghĩa các mô hình. Nó đƣợc thiết kế để tạo các mô hình hoá thiết thực và hữu ích cho các lập trình viên Java. EMF là sự thống nhất ba bền tảng quan trọng: Java, XML và UML. Mô hình có thể đƣợc định nghĩa khi sử dụng công cụ mô hình hoá UML, lƣợc đồ XML hoặc thậm chí là các chú thích đơn giản trên giao diện Java. Vì vậy ở đây ngƣời các nhà phát triển chỉ việc xây dựng các mô hình trừu tƣợng và phần còn lại là thực hiện tự động. EMF đƣợc phát hành nhƣ một dự án con của Eclipse vào năm 2003, nhƣng giờ đây nó là nền tảng mô hình hoá tinh vi đằng sau trình phát triển Eclipse và dƣờng nhƣ không thể thiếu trong phát triển hƣớng mô hình [6].
EMF phần lớn là tƣơng thích MDA với chỉ duy nhất sai lệch nhỏ từ một vài tiêu chuẩn. Ví dụ, nền tảng của ngôn ngữ mô hình meta-model của EMF đƣợc biết đến là Ecore. Ecore không giống nhƣng rất sát với Essential MOF (EMOF) đƣợc mô tả trong MOF 2.0 của MDA. EMF thƣờng có thể tải một EMOF meta-model, các ánh xạ và chuyển đổi đƣợc phát triển giữa EMOF và Ecore.
Hình 3.1 Khung Eclipse Modeling Framework [8]
EMF đi cùng với các cơ chế tiêu chuẩn dùng cho việc xây dựng meta-model và lƣu lại chúng nhƣ các giao diện có thể lập trình đƣợc, cũng nhƣ mã nguồn và dữ liệu dạng XML. Một khung soạn thảo mô hình (Editor) và khung sinh mã (Generators) cũng đƣợc cung cấp (xem Hình 3.1). EMF đƣợc tích hợp chặt chẽ với Eclipse và khả năng tận dụng kiến trúc và cơ sở hạ tầng của Eclipse hỗ trợ việc tích hợp meta-data riêng rẽ, qua nhiều công cụ trong một hệ sinh thái chung ăn theo Eclipse. Điều này nâng cao mức độ tƣơng tác giữa các công cụ phần lớn tƣơng thích với MDA.
Mô hình đƣợc sử dụng để biểu diễn mô hình trong EMF là Ecore. Ecore chính là một mô hình EMF do đó nó vừa là model, vừa là metamodel thậm chí nó còn là meta- metamodel. Ecore là thành phần cốt lõi của EMF, Ecore đƣợc tạo ra từ một trong ba nguồn: Mô hình UML, lƣợc đồ XML, hoặc ký hiệu Java Interface. Hình 3.2 cho thấy mô hình Ecore sau khi thực thi bởi Java sẽ sinh ra mô hình đích nhƣ đã lựa chọn.
Hình 3.2 Mô hình Ecore và nguồn của nó [6]
Do tiêu chuẩn chuyển đổi mô hình vẫn tiếp tục phát triển và các sản phẩm thu nhận đƣợc đều từ chính việc sinh mã, nên hầu hết các công cụ hiện tại đều tập trung vào sinh mã từ mô hình. Nhìn chung, trên thị trƣờng các công cụ MDA sử dụng EMF vẫn đang trƣởng thành ở cả hai lĩnh vực thƣơng mại cũng nhƣ các dự án mã nguồn mở.
3.2.2 Atlas Transformation Language - ATL
ALT [12] là một ngôn ngữ sử dụng trong việc chuyển đổi mô hình sang mô hình (M2M). ATL chỉ hỗ trợ cho phép chuyển đổi mô hình theo một hƣớng. Một chƣơng trình chuyển ATL bao gồm các luật chuyển mô tả cách tạo ra các phần tử của mô hình đích. Ngôn ngữ đƣợc đặc tả nhƣ là metamodel và với cú pháp cụ thể dƣới dạng ký tự. ATL đƣợc tích hợp trong môi trƣờng phát triển của Eclipse và có thể làm việc với các mô hình dựa trên EMF. Mã nguồn ATL đƣợc biên dịch và sau đó đƣợc chạy trên máy chuyển mô hình.
3.2.3 AndroMDA
AndroMDA [2] [8] là nền tảng mã nguồn mở tƣơng thích MDA, nó có cơ chế cho phép các nền tảng và các thành phần hỗ trợ có thể hoán đổi trong và ngoài bất cứ lúc nào. Nó đƣợc khai thác nhiều bởi các dự án nguồn mở hiện tại cho cả mục đích xây dựng dịch vụ phụ thuộc nền (XDoclet cho EJB) và dịch vụ nền tảng chung (Apache Velocity cho việc xây dựng khuôn mẫu chuyển đổi).
Với AndroMDA, lập trình viên có thể mở rộng ngôn ngữ mô hình hoá hiện tại qua các tiện ích nhƣ “metafacades”. Phần mở rộng đƣợc phản ánh qua một UML Profile trong thƣ viện mô hình hoá và khuôn mẫu trong các công cụ chuyển đổi. AndroMDA hỗ trợ chủ yếu việc chuyển đổi từ mô hình sang mã.
3.2.4 ArcStyler
ArcStyler [22] là công cụ phát triển phần mềm hàng đầu theo hƣớng MDA. ArcStyler là nền tảng, môi trƣờng tiêu chuẩn hoàn toàn đƣợc cài đặt trên Java hỗ trợ cho việc thiết kế, mô hình hoá, phát triển và quản lý chất lƣợng cao. Nó dùng cho xây dựng các ứng dụng trong công nghiệp phần mềm không giới hạn phạm vi lớn nhỏ dựa trên công nghệ Java/J2EE và .NET cũng nhƣ khả năng tuỳ chỉnh nền tảng hạ tầng. Ngoài UML Profile, nó sử dụng cơ chế của chính nó để biểu diễn thông tin trong PIM. Cũng nhƣ AndroMDA, ArcStyler hỗ trợ cơ chế mở rộng cho việc sinh mã. Công cụ này cũng hỗ trợ việc chuyển đổi tuân thủ toàn bộ MDA với các luật chuyển đổi rõ ràng.
3.2.5 OptimaJ
OptimalJ [23]là môi trƣờng phát triển tuân thủ toàn bộ MDA. Mô hình trong OptimalJ có nhiều mức trừu tƣợng nhƣ:
Mô hình miền (OptimalJ Domain Model) tƣơng ứng với PIM trong MDA. Nó định nghĩa miền nghiệp vụ (Business Domain) mà không có bất cứ thông tin chi tiết nền tảng cụ thể nào. Nó đƣợc định nghĩa bằng cách mô hình hoá các tính năng và hành vi của ứng dụng, thông tin phụ thuộc miền đƣợc xây dựng dựa trên MOF bằng UML.
Mô hình miền đƣợc chuyển đổi tự động sang mô hình ứng dụng (OptimalJ Application Model), tƣơng ứng với PSM trong MDA. Miền ứng dụng định nghĩa ứng dụng, dựa trên công nghệ đƣợc lựa chọn nhƣ J2EE.
Cuối cùng miền ứng dụng đƣợc chuyển đổi tự động sang mô hình mã (OptimalJ Code Model) tƣơng ứng với Code/Text trong MDA
3.2.6 QVT - Query/View/Transformation
QVT - Query/View/Transformation [21] là một ngôn ngữ chuẩn cho chuyển mô hình đƣợc tạo ra bởi OMG. QVT sử dụng ngôn ngữ ràng buộc OCL, MOF và đƣợc định hƣớng theo kiến trúc MDA. Cũng giống nhƣ cái tên của nó đã thể hiện rõ rằng QVT cho phép thực hiện: Chuyển đổi mô hình (transformation), biểu diễn mô hình (View) và truy vấn (Query). Truy vấn mô hình và biểu diễn mô hình đƣợc xem nhƣ một phƣơng pháp đặc biệt của chuyển đổi mô hình. QVT cũng đƣợc tích hợp trên Eclipse.
QVT định nghĩa ba ngôn ngữ trong việc chuyển đổi mô hình tới mô hình (M2M) tuân thủ theo chuẩn MOF 2.0:
QVT Relational: Là một ngôn ngữ chuyển đổi mô hình khai báo. Hai dạng cú pháp đƣợc định nghĩa trong QVT là cú pháp dạng ký tự và cú pháp dạng đồ hoạ. Ngôn ngữ QVT hỗ trợ chuyển đổi hai chiều. Một phép chuyển đƣợc đặc tả nhƣ là một tập quan hệ giữa các metamodel nguồn và đích. Phép chuyển này cũng có thể đƣợc kiểm tra tính hợp lệ của hai mô hình.
QVT Core: Chính là nền tảng cho ngôn ngữ QVT Relational, nó là một ngông ngữ chuyển đổi mô hình khai báo cấp thấp.
QVT Operational: Là ngôn ngữ chuyển đổi mệnh lệnh, đƣợc áp dụng để cho phép chuyển đổi theo một hƣớng duy nhất.
3.3 Một số phương pháp sinh mã hướng mô hình
Đối với MDA việc sinh mã tự động hƣớng mô hình đƣợc mô tả nhƣ Hình 3.3. Trong đó mô hình nguồn (Source Model) đƣợc xây dựng bởi các ngôn ngữ mô hình hoá khác nhau. Đích (Target) là các đoạn mã phù hợp với cú pháp của các ngôn ngữ nền tảng nhƣ Java, C#, PHP… Đích cũng đƣợc xem nhƣ là mã nguồn hay chƣơng trình (Code/Program). Bộ sinh mã (Code Generator) và định nghĩa sinh mã (Code Generation Definition) đƣợc xem nhƣ là Meta-Program.
Hình 3.3 Chuyển đổi mô hình sang mã theo MDA
Source Model đƣợc mô hình hoá bởi Source Meta-Model, Target Meta-Model biểu diễn Target Model hay Code/Program. Code Generation Definition định nghĩa việc chuyển đổi từ Source Model sang Target Model bằng việc sử dụng các thành phần của Meta-Model. Code Generator sẽ đọc các thông tin đầu vào từ Source Model, điền thông tin theo khuôn mẫu đã đƣợc định nghĩa bởi Code Generation Definition để sinh mã (Code/Program).
Vậy các bộ sinh mã (Code Generator) đƣợc xây dựng và hoạt động nhƣ thế nào? Theo Markus Voelter [13] thì có một số phƣơng pháp sinh mã nhƣ: Phƣơng pháp Template + filterling; Phƣơng pháp Template + Metamodel; Phƣơng pháp sinh mà dựa trên API hay Phƣơng pháp sinh mã Inline Code.
3.3.1 Phương pháp Template + Filterling
Phƣơng pháp này mô tả cách đơn giản nhất để sinh mã. Thông thƣờng, mã đƣợc tạo bằng cách áp dụng khuôn mẫu cho đặc tả mô hình văn bản (thƣờng là XML/XMI), và sau khi lọc một vài phần của đặc tả. Một phần của mã nguồn cũng đƣợc nhúng trong khuôn mẫu.
Hình 3.4 Mô hình phƣơng pháp Template + Fillerling Ví dụ sau mô tả việc sinh mã Java dựa vào đặc tả mô hình XML. Ví dụ sau mô tả việc sinh mã Java dựa vào đặc tả mô hình XML.
Mô hình nguồn đƣợc biểu diễn bởi XML:
<class name="Person" package="de.unifrei">
<attribute name="age" type="int"/> </class>
Khuôn mẫu (template) đƣợc viết bằng XSTL. Mã Java đƣợc nhúng trực tiếp vào khuôn mẫu cùng với các Bộ lọc. Các bộ lọc này sẽ đọc giá trị từ mô hình nguồn để điền vào khuôn mẫu.
<xsl:template match="/class">
package <xsl:value-of select="@package"/>;
public class <xsl:value-of select="@name"/>
{ <xsl:apply-templates select="attribute"/> }
</xsl:template>
<xsl:template match="attribute"> <xsl:variable name="capname"
select="concat( translate( substring( @name, 1, 1), ’abcdefghijklmnopqrstuvwxyz’,
’ABCDEFGHIJKLMNOPQRSTUVWXYZ’ ), substring(@name, 2))" />
private <xsl:value-of select="@type"/> <xsl:value-of select="@name"/>;
public <xsl:value-of select="@type"/>
get<xsl:value-of select="$capname" /> () {return <xsl:value-of select="@name"/>;}
public void set<xsl:value-of select="$capname" />
(<xsl:value-of select="@type"/> <xsl:value-of select="@name"/>)
{this.<xsl:value-of select="@name"/> = <xsl:value-of select="@name"/>;}
</xsl:template>
File Java đƣợc sinh ra:
package de.unifrei;
public class Person {
private String name;
public String getName () {return name;}
public void setName (String name) {this.name=name;}
private int age;
public int getAge () {return age;}
public void setAge (int age) {this.age=age;}}
3.3.2 Phương pháp Template + Metamodel
Phƣơng pháp này là một sự mở rộng của phƣơng pháp “Template and Filtering” (xem Hình 3.5). Thay vì áp dụng khuôn mẫu trực tiếp vào mô hình, thì việc đầu tiên là khởi tạo một meta-model từ đặc tả sau đó mới áp dụng khuôn mẫu. Khuôn mẫu đƣợc
mô tả trong phạm vi của meta-model. Meta-model có thể đƣợc mở rộng để bao gồm các khía cạnh miền hay kiến trúc cụ thể.
. Hình 3.5 Mô hình phƣơng pháp Template + Metamodel
3.3.3 Phương pháp sinh mã Inline-Code
Phƣơng pháp này mô tả kỹ thuật ở đó việc sinh mã đƣợc hoàn thành một cách ngầm định trong suốt việc thông dịch hay biên dịch của một chƣơng trình thông thƣờng, hay bằng cách của một trình tiền biên dịch. Quá trình này thƣờng chỉnh sửa chƣơng trình rồi sau đó chƣơng trình đƣợc biên dịch hoặc thông dịch lại.
Hình 3.6 Mô hình phƣơng pháp sinh mã Inline-Code
Ví dụ trong việc phát triển ứng dụng cho các nền tảng khác nhau (Windows, Linux), chúng ta chỉ muốn dùng một nền tảng mã nguồn để có thể biên dịch cho nhiều nền tảng đích, để làm đƣợc điều đó, ví dụ với ứng dụng viết bằng C/C++, chúng ta cần dùng các chỉ thị tiền biên dịch để khai báo thƣ viện cho nền tảng đích.
Hiện nay, nhìn chung giải pháp cho nhu cầu sinh mã tự động là sử dụng bộ tạo mã dựa trên khuôn mẫu hƣớng mô hình (Model-driven Template-based Code-Generators) nhƣ đã trình bày ở mục 3.3.1 và mục 3.3.2. Kiến trúc bậc cao điển hình của hệ thống tạo mã hƣớng mô hình là dựa trên khuôn mẫu đƣợc mô tả cụ thể nhƣ sau:
Hình 3.7 Sinh mã dựa trên Template
Bộ tạo mã lấy thông tin từ mô hình (Models) và khuôn mẫu (Templates) làm đầu vào, sau đó chuyển đổi khuôn mẫu sang mã nguồn/chƣơng trình (Programs).
Lợi thế của bộ sinh mã dựa trên khuôn mẫu hƣớng mô hình so với các dạng khác, đó là ngƣời dùng có thể đặc tả đƣợc cả nội dung và định dạng của mã nguồn đƣợc sinh ra. Việc này mở rộng phạm vi phân loại các bộ tạo mã và giúp chúng phù hợp với phạm vi nhiệm vụ rộng hơn trong tiến trình phát triển. Các thành phần lõi đặc trƣng của một bộ tạo mã hƣớng mô hình dựa trên khuôn mẫu gồm các dạng mô hình nó sử dụng để tạo mã, các dạng ngôn ngữ nó dùng để mô tả chỉ thị trong khuôn mẫu và vòng đời của mã đƣợc tạo ra.
3.4 Ngôn ngữ xây dựng Template trong các bộ sinh mã
Nhƣ mục 3.3 đã đề cập bộ sinh mã hƣớng mô hình dựa trên khuôn mẫu. Vậy những dạng ngôn ngữ nào đƣợc sử dụng để mô tả các chỉ thị trong khuôn mẫu. Mỗi ngôn ngữ thích hợp cho thành phần của các khuôn mẫu bảo đảm ngắn gọn, mạnh mẽ và sát với miền mà bộ tạo mã hƣớng tới. Trong phần này sẽ mô tả, cũng nhƣ đƣa ra những thuận lợi và bất lợi của các dạng ngôn ngữ khác nhau.
3.4.1 Sử dụng ngôn ngữ
Sử dụng ngôn ngữ (Genneral – purpose language) cho việc định nghĩa khuôn mẫu, cung cấp cho lập trình viên những đặc điểm tính toán không giới hạn, nhƣng nó cũng liên quan đến nguy cơ xuất hiện các lỗi logic trong khuôn mẫu, khi mà cú pháp của chúng phức tạp hơn. Có hai loại ngôn ngữ dạng này là:
3.4.1.1 Ngôn ngữ định kiểu mạnh
Ngôn ngữ định kiểu mạnh (strongly type language) chính là những ngôn ngữ lập trình nhƣ C/C++, Java hoặc C# đƣợc dùng để xây dựng các khuôn mẫu (template). Việc sử dụng ngôn ngữ này cho phép lập trình viên xác định và giải quyết nhiều lỗi logic sử dụng phƣơng pháp phân tích tĩnh. Tuy nhiên, cú pháp của những ngôn ngữ nhƣ vậy liên quan nhiều đến việc ép kiểu, khai báo biến… sẽ làm tăng kích thƣớc của khuôn mẫu và ngƣời phát triển sẽ mất nhiều thời gian để xây dựng khuôn mẫu.
3.4.1.2 Ngôn ngữ định kiểu yếu
Những ngôn ngữ định kiểu yếu (Loosely Typed Languages ) là những ngôn ngữ lập trình không đặt nặng về kiểu nhƣ Pert, Php, hoặc các ngôn ngữ kịch bản khác. Lập trình với các ngôn ngữ kịch bản nhƣ JavaScript hay VBScript làm cho lập trình viên giảm đƣợc công sức khai báo, ép kiểu và việc viết các khuôn mẫu trở nên nhỏ gọn và dễ dàng hơn. Tuy nhiên, việc sử dụng những ngôn ngữ nhƣ vậy làm cho sự xuất hiện lỗi khi chạy ở các khuôn mẫu thƣờng xảy ra nhiều hơn, các lỗi cú pháp có thể chỉ đƣợc bắt gặp trong quá trình thông dịch, trong khi các lỗi khác sẽ chỉ đƣợc xác định trong lúc chạy ứng dụng.
Sử dụng ngôn ngữ trong việc xây dựng các khuôn mẫu phục vụ cho các bộ sinh mã sau thực tế nhiều năm ứng dụng cho thấy rằng ngôn ngữ đánh máy không đƣợc trọng dụng nhƣ ngôn ngữ kịch bản (Php, Perl…) hay các dạng ngôn ngữ biến thể của ngôn ngữ định kiểu (nhƣ VBScript cho VB, Web Macro cho Java…)
3.4.2 Sử dụng ngôn ngữ chuyên biệt miền
DSL - Ngôn ngữ chuyên biệt miền (Domain-Specific Languages) đƣợc sử dụng để mô tả hệ thống dƣới các góc nhìn khác nhau. Mỗi góc nhin là một miền và đƣợc mô tả bằng một mô hình. Các mô hình này đƣợc định nghĩa bởi DSL. Nội bản thân DSL có hai góc nhìn là cú pháp trừu tƣợng và cú pháp cụ thể. Cú pháp trừu tƣợng là một metamodel định nghĩa các khái niệm và mối quan hệ giữa chúng trong một mô hình. Cú pháp cụ thể định nghĩa mức thể hiện vật lý giữa các khái niệm và mối quan hệ. Hay nói cách khác ở góc nhìn cụ thể, các khái niệm và quan hệ đƣợc ánh xạ thành các biểu tƣợng thể hiện vật lý. Cú pháp trừu tƣợng thể hiện bằng văn bản hoặc hình vẽ.
Khuôn mẫu mà bộ tạo mã sử dụng đƣợc viết bằng ngôn ngữ DSL đơn giản là chỉ áp dụng cho miền ứng dụng (ví dụ SQL cho CSDL, HTML cho Web). Ngôn ngữ nhƣ vậy thƣờng gồm các đặc điểm cho sự lặp đi lặp lại và không cung cấp các tính năng cao hơn nhƣ tính toán. Lợi thế của những ngôn ngữ này là dễ học, khi chúng thƣờng