QV T Query/View/Transformation

Một phần của tài liệu Thao tác mô hình trong phát triển hướng mô hình (Trang 33)

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.

22

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.

 Mô hình nguồn đƣợc biểu diễn bởi XML:

<class name="Person" package="de.unifrei">

23

<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" /> (adsbygoogle = window.adsbygoogle || []).push({});

(<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

24

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:

25

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à: (adsbygoogle = window.adsbygoogle || []).push({});

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.

26

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 gồm một số ít khái niệm và sự diễn tả liên quan tới miền ứng dụng. Hơn nữa, vì sự đơn giản, xác suất lỗi logic trong khuôn mẫu giảm đi. Hạn chế quan trọng nhất là thiếu sự mở rộng, sự thừa kế trong những ngôn ngữ nhƣ vậy.

3.4.3 Sử dụng ngôn ngữ chuyển đổi mô hình chuyên dụng

Đối với việc sinh mã hƣớng mô hình, thì trong những năm gần đây dạng ngôn ngữ dùng cho chuyển đổi mô hình sang văn bản, đƣợc sử dụng nhiều bởi các hãng hay các dự án mã nguồn mở, có thể hoặc là biến thể của ngôn ngữ định kiểu, hoặc ngôn ngữ chuyên biệt miền. Tuy nhiên chƣa có một chuẩn chung nào đƣợc sử dụng cho tất cả các dự án, mà mỗi dự án tự sáng tạo và áp dụng theo mục đích riêng của mình, nhƣng nhìn chung thì những dạng ngôn ngữ này đều đƣợc sử dụng với phƣơng pháp chuyển

27

đổi dựa theo khuôn mẫu hƣớng mô hình đã đề cập ở các phần trƣớc. Một số loại ngôn ngữ chuyển đổi từ mô hình sang văn bản đang đƣợc áp dụng đƣợc trình bày nhƣ dƣới đây.

3.4.3.1 JET (Java Emitter Templates)

JET là công cụ mã nguồn mở. Nó cung cấp một khung làm việc (framework) và các tiện ích cho việc sinh mã. Các file khuôn mẫu dạng JSP đƣợc sử dụng và những ngƣời mà đã quen thuộc với công nghệ JSP dễ dàng học và sử dụng. Nó cũng dễ mở rộng với các thẻ (tag) tuỳ biến giống nhƣ với JSP.

JET cũng đƣợc hỗ trợ mạnh bởi các công cụ đƣợc tích hợp trong Eclipse. Một dự án chuyển đổi cụ thể có thể đƣợc tạo trong Eclipse IDE và cung cấp các file cần thiết. Ngoài ra, một trình soạn thảo riêng cho JET và cấu hình triển khai để bắt đầu chuyển đổi cũng đƣợc cung cấp.

Mặc định JET yêu cầu file XML là đầu vào, file XML này không nhất thiết là một dạng XML cụ thể nào, và không liên quan đến mô hình hoá phần mềm. Xpath là ngôn ngữ đƣợc sử dụng để truy cập các nốt (nodes) khác nhau trong file nguồn XML, và điều hƣớng chúng giữa các thành phần. Xpath cũng là một ngôn ngữ phạm vi rộng đƣợc biết đến bởi rất nhiều lập trình viên (xem Hình 3.8).

Hình 3.8 JET Engine

Khi mà khuôn mẫu JET (*.jet) đƣợc phát triển và đƣợc lƣu trong trình soạn thảo JET (Editor, Designer) thì một lớp Java (*.class) đƣợc sinh ra bên ngoài nó (xem Hình 3.9). Lớp khuôn mẫu (*.class) này có thể đƣợc gọi trực tiếp bởi mã nguồn Java khác (main() program). Vì vậy có thể lập trình một bộ phân tích cú pháp (parser) chuẩn bị cho mô hình nguồn đƣợc chuyển đổi bởi lớp khuôn mẫu JET.

Sự chuyển đổi có thể đƣợc xem nhƣ là kế hoạch chi tiết đƣợc áp dụng cho mô hình nguồn. Mô hình nguồn đôi khi chỉ đƣợc gọi qua một tập các tham số, bởi vì nó định nghĩa giá trị đƣợc sử dụng khi mà kế hoạch chi tiết đƣợc áp dụng. Một sự chuyển đổi JET có thể đƣợc minh hoạ nhƣ sau: Tham số + Kế hoạch = Các yếu tố mong muốn.

28

Hình 3.9 Quy trình chuyển đổi của JET

Nhƣ đã phân tích ở trên thì chúng ta có thể thấy rằng JET là một bộ sinh (engine) dựa trên nền tảng công nghệ sẵn có, nó dễ dàng đƣợc học bởi các lập trình viên đã quen với các công nghệ nhƣ JSP. Một dự án chuyển đổi cũng dễ dàng đƣợc thiết lập trong thời gian ngắn.

Tuy nhiên JET cũng có những hạn chế, đó là với MDSD nó không hỗ trợ việc phân tích miền cụ thể, đơn cử là không thể kiểm tra đƣợc khuôn mẫu khi mà khuôn mẫu đƣợc lƣu bởi trình soạn thảo JET, điều này không đƣợc nhƣ trình soạn thảo Xpand. Vì vậy mà đối với những dự án lớn đòi hỏi việc xử lý nhiều mô hình phức tạp thì sẽ trở nên khó khăn cho JET khi mà không có công cụ hỗ trợ mở rộng cho miền cụ thể.

Xây dựng chuyển đổi dựa theo JET trong Eclipse liên quan đến nhiều kiến thức khác mà lập trình viên phải thực sự hiểu nhƣ Eclipse Resource và UI API, đây cũng là một hạn chế cho việc tạo chuyển đổi. Mặt khác, JET cũng chỉ hỗ trợ sinh mã Java, hạn chế mở rộng cho các nền tảng khác.

3.4.3.2 Xpand

Ngôn ngữ Xpand [24] đƣợc phát triển nhƣ là một phần của dự án openArchitecture-Ware (oAW) dùng cho việc chuyển đổi gồm cả từ mô hình sang mô hình và mô hình sang văn bản. Xpand là một dạng của ngôn ngữ chuyên biệt miền. Các khuôn mẫu xây dựng trên ngôn ngữ này đƣợc sử dụng bởi bộ sinh mã là một phần của luồng phát triển của nền tảng oAW (xem Hình 3.10). Xpand là độc lập với các dạng mô hình. Các mô hình nguồn khác nhau đƣợc xử lý bởi một bộ phân tích cú pháp (parser) mà đƣợc liên kết tới luồng xử lý của oAW. Bộ phân tích cú pháp có thể đƣợc viết cho bất kỳ mô hình nguồn nào và nền tảng oAW có thể cung cấp bộ phân tích cú pháp ngoài luồng cho các mô hình đầu vào đƣợc xây dựng bởi nhiều nền tảng khác nhau.

29

Hình 3.10 Quy trình chuyển đổi trong oAW [5]

Một trong những lợi ích lớn nhất của nền tảng oAW thế hệ thứ 4 đó là việc hỗ trợ công cụ mở rộng, vì nó đƣợc tích hợp ở phạm vi rộng với nền tảng mô hình hoá EMF của Eclipse. Điều này là rất cần thiết cho việc mở rộng phạm vi thiết kế phụ thuộc vào các yêu cầu thay đổi thƣờng xuyên. (adsbygoogle = window.adsbygoogle || []).push({});

Ngoài ra, ngôn ngữ Xpand cũng rất dễ học vì nó có bộ từ vựng nhỏ nhƣng rất hữu hiệu cho việc viết các khuôn mẫu. Ví dụ dƣới đây mô tả một khuôn mẫu đƣợc viết bằng Xpand:

3.4.3.3 MOFM2T

MOFM2T [18] là một chuẩn của OMG tuân thủ theo kiến trúc hƣớng mô hình (MDA). Ngôn ngữ này quy định cú pháp và thực thi chuyển đổi từ mô hình sang dạng văn bản: Mã nguồn, báo cáo, tài liệu… Cách tiếp cận của MOFM2T là sử dụng template, template quy định tập các ánh xạ giữa mô hình nguồn và mô hình đích (mã nguồn). Cụ thể hơn, một template đặc tả một template dạng văn bản, với các vị trí (placeholder) cho dữ liệu đƣợc lấy từ các mô hình. Các vị trí này cơ bản là các biểu thức biểu diễn cụ thể qua các thực thể meta-model, với các truy vấn là các cơ chế chủ

Một phần của tài liệu Thao tác mô hình trong phát triển hướng mô hình (Trang 33)