[Flex] ClassFactory và ItemRenderer

Trước khi trình bày về ClassFactory và ItemRenderer, chúng ta nên điểm qua về mẫu thiết kế (design pattern) Factory. Mẫu thiết kế Factory được dùng để giải quyết vấn đề tạo ra một đối tượng mà không thể xác định trước chính xác loại (class type) đối tượng cụ thể. Bằng cách định nghĩa một phương thức cho việc tạo đối tượng, và các lớp con thừa kế có thể nạp chồng (override ?)  để chỉ rõ đối tượng nào sẽ được tạo.

Một ví dụ thực tế của Factory chính là trình duyệt ảnh như ACDSee chẳng hạn. Bạn có 1 list các hình ảnh, tuy nhiên mỗi hình ảnh có thể là 1 đối tượng của JPEGRenderer hoặc PNGRenderer, nghĩa là thuôc các lớp hoàn toàn khác nhau. Và khi render list các hình ảnh này thì ACDSee cần phải xác định lớp nào – JPEGRenderer hoặc PNGRenderer sẽ được chọn.  Một FactoryClass sẽ đóng vai trò chọn ra class instance thich hợp.

Bài viết này chi gói gọn trong phạm vi trình bày cách sử dụng ClassFactory và ItemRenderer hơn là đi sâu vào phân tích tính chất của mẫu thiết kế Factory. Hơn nữa mẫu thiết kế này được phân tích rất chi tiết trong tài liệu ActionScript 3.0 Design Patterns.

ClassFactory

Flex ClassFactory cho phép tạo ra một instance của lớp bất kỳ với các thuộc tính giống nhau. Để khởi tạo một đối tượng của FactoryClass thì điều đầu tiên là bạn phải chỉ rõ đối tượng lớp nào cần được khởi tạo bằng cách truyền class vào hàm dựng của ClassFactory

var animalHasTailRenderer:ClassFactory = new ClassFactory(AnimalRenderer);
animalHasTailRenderer.properties = { hasTail: true };

Trong đoạn mã trên,  để tạo ra một class instance của animalHasTailRenderer thì Flex sẽ gọi phương thức newInstance() của đối tượng factory và thiết lập thuộc tính hasTail = true thông qua việc gán setter properties.

ItemRenderers

Khi tiếp cận với DataGrid, List … bạn sẽ va chạm rất nhiều với ItemRenderer . Người tiền nhiệm của ItemRenderer chính là cellRenderer AS2 – nếu bạn đã có kinh nghiệm sử dụng các component của Flash.

Ngữ cảnh sử dụng ItemRenderer thường được dùng với DataGrid – bạn cần đặt các checkbox hay combobox vào từng dòng của DataGrid chẳng hạn, hay mỗi dòng sẽ là một component khác nhau.  Bạn có thể xem một ví dụ điển hình của việc sử dụng itemRenderer như đoạn mã mxml dưới đây

<mx:DataGrid id="myGrid" dataProvider="{customerXMLList}">
     <mx:columns>
          <mx:DataGridColumn dataField="Company" itemRenderer="org.catapult.renderers.CompanyRenderer"/>
          <mx:DataGridColumn dataField="Contact" itemRenderer="org.catapult.renderers.ContactRenderer"/>
     </mx:columns>
</mx:DataGrid>

Một ItemRenderer có thể được tao từ mã ActionScript thuần túy hay mã MXML, tuy nhiên phải được implement từ IFactory. Lý do là bạn phải cài đặt phương thức newInstance để ClassFactory có thể gọi được.

ActionScript

package org.catapult.renderers {
     import mx.containers.VBox;
     import mx.core.IFactory;

     public class CompanyRenderer extends VBox implements IFactory {       
           public function newInstance():* {
                return new CompanyRenderer();
           }
     }
}

MXML

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" implements="mx.core.IFactory">
     <mx:Script>
           <![CDATA[
                public function newInstance():* {
                       return new CompanyRenderer();
                }
            ]]>
    </mx:Script>
</mx:VBox>

Bản chất của việc gán itemRenderer trong đoạn mã trên là việc tạo ra một class instance kiểu object factory.

Tham khảo:

1. ActionScript 3.0 Abstract Factory Design Pattern: Multiple Products and Factories

One thought on “[Flex] ClassFactory và ItemRenderer

  1. chào anh,rất cảm ơn vì anh đã có những bài viết bổ ích về flex,em cũng đang bắt đầu làm quen với flex nên mong anh giúp đỡ.
    em đang tính làm một website bằng flex nhưng em muốn flex kết nối trực tiếp với csdl chứ không thông qua một server trung gian (php hay .net) có được không?anh có tài liệu liên quan có thể share cho em được không? em xin cảm ơn trước ạ

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s