Bài viết hay


18
Jan 09

“Một nghề cho chín còn hơn chín nghề”

Tự nhiên lại nhớ đến blog của Thái nên vào & đọc được 1 bài khá thú vị. Nó đã giúp “chỉnh đốn” lại phần nào tư tưởng của mình trong thời gian khó khăn này :(

người ta nói, cách tốt nhất để ăn một con voi, là ăn một miếng thịt của nó mỗi ngày. ngẫm lại chuyện học, chuyện làm, mình thấy đây là một lời khuyên có lý. tri thức thì bao la vô tận, không thể nào ngày một ngày hai nắm bắt hết được, mà phải có thời gian, kế hoạch và phương pháp.

có thời gian nghĩa là phải kiên nhẫn và tập trung, ví dụ như muốn ăn một con voi, phải dành ra 3 tháng liên tục. có kế hoạch nghĩa là phải biết mình đang ở đâu và phải làm gì tiếp theo, ví dụ như bây giờ là đang ăn cái đầu, tiếp theo sẽ ăn cái mình của con voi.

có phương pháp nghĩa là phải biết lên kế hoạch, làm thế nào để thực thi kế hoạch trong thời gian dự tính, ví dụ như ăn voi thì phải biết cách xẻ thịt nó ra, biết cách ăn, phải biết con voi thì cái gì ngon, cái gì dở, cái gì cần tập trung ăn kỹ, cái gì bỏ đi cũng được.

trong ba yêu cầu này, cái khó nhất là phương pháp. riêng cách (tự) học, thì trường đại học đã dạy, vấn đề ở đây là không biết nên tập trung học cái gì. lúc này thầy cô, bạn bè, những người đi trước…sẽ là những người chỉ đường tốt nhất.

một kinh nghiệm khác mình rút ra được là đối với lĩnh vực tự nhiên, muốn học xa, học sâu, thì phải bắt đầu từ những môn khoa học cơ bản, trong đó toán là bắt buộc.

những năm đầu đại học, mình đã không hiểu được yêu cầu quan trọng này, nên hết sức lơ là trong việc học toán, hậu quả là những ngày này, mình phải bắt đầu học lại các món lẽ ra phải vững rồi.

nhiều lúc mình tự hỏi, học những thứ này có phí thời gian không? trong khi các bạn xung quanh thì đổ xô đi học MBA, thì mình lại ngồi cặm cụi học đại số tuyến tính, học lý thuyết số, học lý thuyết xác suất & thống kê…mình cũng không biết nữa.

dẫu vậy, mình không hiểu được chuyện, chỉ mới làm trong ngành vài năm, mà có một số bạn đã cảm thấy chán, “muốn gác kiếm”, chuyển sang làm kinh doanh hay các vị trí quản lý trung gian, không còn làm kỹ thuật nữa.

mình cũng muốn học về kinh doanh và quản lý, nhưng cái cảm giác chưa nắm vững những kiến thức và kỹ năng nền tảng của cái nghề mình được đào tạo và làm việc bấy lâu nay làm cho mình rất khó chịu.

mỗi lần nghe một bạn lập trình viên kêu chán lập trình sau 3-4 năm làm việc, là mình lại cảm thấy có gì đó rất bứt rứt. kiểu như leo núi, chưa lên đến đỉnh, mà đã vội xuống. đối với mình thì đây mới chính là phí phạm thời gian.

vậy thế nào là lên đến đỉnh, cái gì là nền tảng? mình nghĩ đó là: hiểu hết ngọn ngành và có thể áp dụng tốt những mảng kiến thức của một chương trình đào tạo khoa học máy tính ở các trường đại học.

đây là một nhiệm vụ rất khó, nhưng làm được. làm thế nào thì mình sẽ từ từ trao đổi, dựa trên kinh nghiệm học tập của mình. điều mình muốn nhấn mạnh ở đây là: có cần thiết không?

tôi làm lập trình, thì chỉ cần biết C, Java, .NET hay Ruby, Python là đủ thôi, chứ cần gì phải học về database, operating system hay là networking? tôi làm mạng thì chỉ cần biết TCP/IP, có thêm cái bằng CCNA là tốt rồi, chứ cần gì phải biết lập trình?

kinh nghiệm làm việc của mình cho thấy đây là tư duy sai lầm. biết nhiều hơn bao giờ cũng có lợi, giúp cho công việc đơn giản và dễ dàng hơn rất nhiều

ví dụ một lĩnh vực mà mình biết chắc là nếu học nó, sẽ đem lại nhiều lợi ích, đó là machine learning, nói nôm na là dạy cho máy tính biết cách tự học những kiến thức mới hay nhận dạng được những pattern trong mớ dữ liệu hỗn độn khổng lồ.

cách đây vài năm, mình có mở một công ty, công ty mình có làm một phần mềm chống spam, và phần mềm này chỉ sử dụng một tí xíu kỹ thuật của machine learning thôi, nhưng đã tỏ ra cực kỳ hiệu quả so với các phần mềm không sử dụng kỹ thuật này.

machine learning cũng được đánh giá là kỹ năng số 1 mà bất kỳ nhà tuyển dụng nào cũng muốn ứng viên của họ phải có. cũng phải thôi, với lượng dữ liệu và thông tin khổng lồ được tạo ra mỗi ngày, kẻ nào hiểu được chúng nói gì thì kẻ đó sẽ là người chiến thắng.

quay lại việc các anh kỹ sư máy tính bỏ việc sau khi ra trường vài năm. mình nghĩ đôi khi, chính môi trường làm việc, phải leo cao thì lương nó mới cao, đẩy người ta vào tình thế phải từ bỏ chuyên môn khi chưa đủ độ chín.

mình nghĩ đây cũng là một điểm mà người làm quản lý cần phải chú ý: lương bổng và quyền lợi là một hàm của năng lực và hiệu quả công việc, chứ không phải của chức vụ hay vị trí.

nhìn xung quanh, mình thấy rất khó tìm được ai đó có hơn 10 năm kinh nghiệm làm việc liên tục trong một lĩnh vực kỹ thuật nào đó. cao nhất chỉ là 5 năm.

mình cũng đi làm hơn 5 năm rồi. và mình nghĩ bây nhiêu thời gian chỉ đủ để biết là mình đang thiếu kiến thức và kỹ năng nào, cần phải học thêm cái gì, để làm việc cho tốt hơn.

vả lại, bạn nào cũng học MBA, về làm sếp hết, thì các bạn quản lý ai? những bạn mới ra trường, làm được 3-4 năm khác? rốt cuộc toàn những bạn không có kinh nghiệm và không đủ kiến thức làm việc với nhau.

hậu quả là cái gọi là “nền CNTT VN” toàn phải đi mua đồ của nước ngoài về xài, bởi trong nước không tự sản xuất được, nguyên nhân chính là không có thợ lành nghề. bao nhiêu ngân hàng ở VN sử dụng phần mềm nước ngoài? ngay cả FPT, một công ty tự xem là đi đầu ở VN về công nghệ, nhưng khi thành lập ngân hàng, họ vẫn phải bỏ tiền ra mua phần mềm của Ấn Độ.

nhiều bạn cho rằng, và mình đồng ý, do chúng ta còn non trẻ, chưa có nhiều kinh nghiệm. vậy hà cớ gì khi mới làm việc có vài năm, chưa đâu vào đâu, lại chuyển chuyên môn?

Nguồn: Dương Ngọc Thái’s blog

Vậy nên bây giờ mình sẽ phải lên kế hoạch, đầu tư thời gian, tiền bạc để làm một cái gì đó mới được :( (

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

27
Aug 08

Discuss about Java

Chẳng mấy khi được nghe 2 cao thủ luận bàn, chẳng biết gì nên cứ copy về đây để bao giờ trình độ lên cao thì “nghiệm” vậy :”>

mega2look:

http://www.javavietnam.org/javavn/mvnforum/viewthread_thread,20372_offset,60#87886

Kính thưa các doanh nghiệp Việt Nam,

Hôm nay tôi xin thay mặt công ty SUN Microsystem gởi tới các đồng chí
lời chào thân ái và quyết thắng.

Chắc các đồng chí đều biết công ty chúng tôi là công ty hàng đầu về
bán server đã tối ưu để chạy công nghệ Java, dĩ nhiên công nghệ này
cũng của chúng tôi. Mặc dù tình hình kinh doanh của chúng tôi trong
những năm gần đây không được sáng sủa gì cho lắm, nhưng tôi đảm bảo
rằng chúng tôi vẫn là một trong những công ty hàng đầu trong vài năm
tới miễn là không thua lỗ nhiều quá, và đặc biệt là với sự ủng hộ vô
điều kiện của cộng đồng các nhà phát triển Java đầy tiềm năng tại Việt
Nam thì tương lai của SUN vô cùng sáng lạn.

Công ty chúng tôi chuyên cung cấp các giải pháp cỡ enterprise ở cả
phần mềm lẫn phần cứng. Trước hết tôi xin nói qua về giải pháp phần
mềm. Đây toàn là những phần mềm to vật vã, chức năng vô cùng khủng bố
hoàn toàn hợp với mác Enterprise mà các quí vị đang quan tâm. Để tạo
ra được phần mềm này các quí vị nên xem qua cái chuẩn J2EE (cũng do
chúng tôi định nghĩa ra nốt), nếu các vị chưa chóng mặt vì tầm mức vĩ
đại, kỳ vĩ của nó thì cũng sẽ phải thán phục trước độ phức tạp mà loài
người chưa từng hình dung ra từ trước tới nay.
Continue reading →


19
Aug 08

Vì sao các PHP framework làm cho ứng dụng của bạn nặng nề hơn?

Lang thang được bài viết khá hay của bác Huy :)

Nếu bạn đã từng làm việc với các PHP framework như symfony, Cake, Zend … có thể bạn đã nhận ra những vấn đề này. Tôi xin nêu ra đây cả cách giải quyết của mình.

Việc sử dụng các pattern như Active Record, Data Mapping để làm Model trong các framework là một ác mộng.

Thật vậy, không những làm bạn khó khăn hơn trong việc xoay sở với SQL, nó còn khiến quá trình truy xuất dữ liệu trở nên nặng nề hơn. Các pattern này quy mỗi record trong database thành một object. Việc làm này là cực kỳ không cần thiết. Không phải lúc nào bạn cũng select chúng ra sau đó lại update trở lại database. Những logic nhằm bảo đảm mối quan hệ giữa các object cũng ngốn kha khá tài nguyên. Hơn nữa, các câu SQL được tự động sinh ra sẽ không đạt được mức độ tối ưu như mong muốn. Tối ưu SQL là một công việc quan trọng nhưng các ORM lại cố ngăn bạn khỏi công việc đó.

Giải pháp của tôi

Sử dụng DAO pattern để thay cho Active Record. Hoặc tốt hơn nữa là sử dụng các tính năng được hỗ trợ sẵn trong hệ quản trị cơ sở dữ liệu mà lâu nay lập trình viên PHP/(nhất là MySQL) thường quên đi mất như View, Trigger, Stored Procedured…  Bạn không nên lo ngại việc các lập trình viên của mình phải viết SQL. Suy cho cùng họ là lập trình viên, công việc của họ là viết code.

Lạm dụng sự tự động hoá.

Các framework thường tự động hoá một số giai đoạn trong workflow để trở nên thân thiện hơn đối với developer. Nếu bạn đã dùng qua CakePHP, bạn sẽ hiểu. Cake cho phép bạn khai báo các model và component bạn cần trong controller và tự động load toàn bộ chúng trong quá trình start-up. Điều này làm cho ứng dụng phải mất rất lâu để start-up. Hơn nữa, với cách phân chia ứng dung thành controller/action, bạn gặp phải một vấn đề là không phải lúc nào bạn cũng cần những model/component giống nhau ở tất cả các action trong cùng một controller. Với cách làm của CakePHP, bạn phải load những thứ mình không cần một cách bất đắc dĩ.

Giải pháp của tôi

Dẹp sự tự động hoá sang một bên đi! Hiện đại là hại điện. Tôi nhắc lại một lần nữa, bạn tuyển những lập trình viên và trả lương cho họ để họ viết code. Đừng ngại khi bắt họ làm chuyện đó.

Chính mô hình MVC làm tăng thêm các giai đoạn trong workflow của bạn

Ok, MVC là một mô hình tốt, chẳng ai phủ nhận cả. Nhưng việc phân chia rạch ròi giữa business logic (M) và presentation logic (V) cũng làm cho mọi thứ trở nên rắc rối hơn. Một ví dụ: trong mô hình MVC mà bạn gặp ở các framework mà tôi kể ở trên, Model thường xử lý dữ liệu xong rồi truyền cho View. Giả sử ở đây bạn có một list các bài hát cần in ra. Cách thông thường nhất và gần như duy nhất mà ta thường làm là Model nhận việc select từ database, duyệt qua tập kết quả lần để để tổng hợp nó thành một danh sách (ở PHP thì rất có thể là mảng) rồi sau đó mới truyền cho View. View lại phải duyệt qua mảng đó thêm một lần nữa để in ra.

Giải pháp của tôi

Tôi không có cách giải quyết nào và chấp nhận vấn đề này ở hiện tại. Thật ra nó cũng không ảnh hưởng quá nhiều đến performance, bù lại ta có được sự tách biệt rạch ròi về kiến trúc.

OOP

Lập trình OOP luôn luôn ngốn nhiều tài nguyên hơn so với function-based. Thêm vào đó, với đặc điểm của PHP, việc viết mỗi lớp thành một file riêng sẽ làm phân mảnh code và buộc PHP engine phải làm việc nặng nề hơn (nhất là đối với các framework như Zend).

Giải pháp của tôi

Sử dụng các opcode caching egine như APC, XCache.

Nguồn: byhuy.com

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

29
Jul 08

Mô hình MVC: Vai trò của các thành phần và các vấn đề thiết kế trong các Web Framework

@author pcdinh
@since July 26, 2008
@version 1.0.0
@link http://dev.wvb.com/pubdocs/software_design/mvc.txt
@note Tài liệu được viết trên Notepad (plain text) và xem tốt trên font Courrier New và encoding UTF-8 ở chế độ Word-wrap. Firefox hỗ trợ Wordwrap trên màn hình View Source (Ctrl + U) , chọn View – Wrap long lines

CHANGE LOG
+ July 26, 2008: 1.0.0 – Viết lần đầu

Disclaimer: Bài viết này phản ánh quan điểm của tôi. Nó không phản ánh quan điểm của World’Vest Base hay các software architect mà tôi có dịp làm việc cùng.

———————————————————————-
MÔ HÌNH MVC TRUYỀN THỐNG TRONG CÁC WEB FRAMEWORK
———————————————————————-

Trong mô hình MVC truyền thống, Controller là thành phần đóng vai trò trung tâm trong việc tiếp nhận và chuyển tiếp yêu cầu của user đến các thành phần có liên quan trong đó có 2 bộ phận chính là Model và View. Trong đó Model đóng vai trò là thành phần cung cấp dữ liệu và các dịch vụ có liên quan đến dữ liệu. View đóng vai trò là thành phần cung cấp các logic và cấu trúc liên quan đến việc trình bày dữ liệu.

Tuy nhiên với mô hình này, Controller đóng vai trò là trung tâm điều khiển. Model không biết Controller nào sẽ lựa chọn nó. Nó là Passive Model. Tương tự, View không biết Controller nào sẽ gọi nó ra và cung cấp cho nó dữ liệu gì. Nó là Passive View. Bằng cách đó, View và Model không hề biết nhau. View và Model không biết đến Controller nhưng Controller thì lại biết cả 2 và thậm chí là cả sự phụ thuộc về dữ liệu giữa View và Model.

Như vậy trong các web framework hỗ trợ MVC truyền thống thì

CONTROLLER

Controller là các lớp điều khiển application flow, tiếp nhận user input thông qua HTTP header, chuyển tiếp nó đến các lớp phụ trách trực tiếp xử lý yêu cầu. Tùy theo cách thiết kế kế lớp mà chúng ta thường thấy Controller gồm
+ Front Controller
+ Dispatcher
+ Action Mapping
+ Action Filter
+ Action: lớp xử lý các sự kiện chính, nơi dẫn đến application flow chủ yếu (Main Event Handler)
+ Response
+ Request: xử lý một phần user input ở mức GET, POST và PUT
+ Session: xử lý một phần user input ở mức SESSION

Tùy theo user input, Controller sẽ thực hiện các phép lọc (với dịch vụ lấy từ Model), các tính toán lựa chọn (Action Mapping) dựa trên kiến trúc và cấu hình nhằm xác định thành phần lớp chính sẽ thực hiện yêu cầu của user. Đây chính là chức năng điều khiến application flow của Controller. Vì là nơi đón nhận user input cho nên thường thì các thành phần xử lý form (ví dụ ActionForm trong Struts) sẽ thuộc về Controller. Controller cũng sẽ có chức năng validate form đơn giản nhằm thực hiện chức năng điều khiển luồng của mình.

Một khi xuất hiện các Event phức tạp, như là một Observer, Controller cần bổ sung thêm các lớp mới vào để xử lý chúng theo các quy trình độc lập, giúp phân tán bớt code tập trung vào lớp Action. Do là thành phần điều phối, Controller không nhất thiết phải tương tác với Model rồi mới tương tác với View. Bất cứ lỗi ngoại lệ nào xảy ra hay một trạng thái request không mong muốn xuất hiện thì Controller có thể phản ứng bằng cách chọn View trực tiếp.

Khi giao tiếp với Model, Controller sẽ tiến hành 2 cách
+ extract dữ liệu hay state
+ update dữ liệu

Ví dụ:

1
2
3
4
// Trong lớp Action của Controller
$productId           = $this->request->get('product_id');
$electronicWarehouse = new ElectronicProductWarehouse();
$availableProducts   = $electronicWarehouse->findAvailableProductsById($productId);

Sau khi có được dữ liệu, theo cách hành xử thông thường, View thích hợp sẽ được lựa chọn. COntroller sẽ chuyển tiếp dữ liệu vào View để nó xử lý

Ví dụ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Trong lớp Action của Controller
 
// Load the PHP Savant2 class file and create an view instance.
require_once 'Savant2.php';
$view    = new Savant2();
 
if (true === $availableProducts->empty())
{
    // Assign values to the Savant instance.
    $view->assign('products', $availableProducts);
 
    // Display a template using the assigned values.
    $view->display('products.tpl.php');
}
else
{
    // Display a template using the assigned values.
    $view->display('products_unavailable.tpl.php');
}

CakePHP, Zend Framework, Symfony, Ruby on Rails, Struts hay Spring MVC lựa chọn cách làm này. Bằng việc xóa khỏi bộ não View kiến thức về Model, Controller có thể thay thế nhiều Model, các API trên Model mà nhưng không cần phải nhắc View về điều đó. Điều này là đặc biệt quan trọng khi mà kiến trúc ứng dụng đòi hỏi phải phù hợp với việc các lớp Model cần thay đổi 1 cách linh hoạt (ví dụ như có sự can thiệp của Dependency Injection). Nhưng có vẻ như đây là nhiệm vụ của tầng Integration. Trong bài viết sau chúng ta sẽ xem xét lại vấn đề này với MVC Pull.

Có một số người khi thiết kế ứng dụng theo MVC đã cố gắng dồn hết chức năng điều khiển luồng vào lớp Action cho nên dẫn đến hiện tượng Fat Controller. Ví dụ như những người code Rails sau khi đã định nghĩa Model dựa trên ActiveRecords để làm các công việc như extract data, update data và validate dữ liệu thì họ bỏ hết trách nhiệm xử lý business logic sang cho Controller. Thực tế là
+ Fat Controller, hay Thin Controller là các từ gọi nôm na của một thiết kế tồi. Từ Fat có lẽ đến từ thế giới Ruby on Rails khi mà nhiều người ở đó quá cứng nhắc trong việc tuân thủ theo mô hình Rails mà không biết rằng bản thân Controller cũng có thể có các sub layer giúp giải phóng các tác vụ dạng thủ tục thành các thành phần nhỏ riêng biệt, nhưng vẫn thuộc về Controller. Hoặc theo 1 hướng khác, Model tỏ ra vô tránh nhiệm với dữ liệu trả về khiến cho công việc điều khối của Controller thêm nặng nề. (xem bên dưới)
+ Tôi cho rằng Controller cần làm đúng nhiệm vụ của nó. Nó không phải là God Class. Nó không thể đẩy trách nhiệm cho Model hay cho View chỉ bởi vì nó có nhiều việc hơn 2 thành phần kia trong 1 hay 1 số user case cụ thể nếu như giao diện giữa chúng đã đủ compact.
+ Theo code mẫu trên thi View có vẻ như hơi ít trách nhiệm. Một phần trách nhiệm xác định cấu trúc để hiển thị đã được đẩy sang cho Controller. Đây cũng là vấn đề làm cho Controller trở nên nặng nề hơn.

Do tính chất công việc của Controller là khá phức tạp và đa dạng cho nên việc Event Handler Controller có thể tiếp tục tách ra nhỏ hơn cũng là điều cần tính đến thay vì thực hiện việc xử lý tất cả các signal, user input … trên cùng một lớp.

MODEL

Model là các lớp cung cấp dữ liệu, dịch vụ liên quan đến dữ liệu và business logic. Chúng có thể là

+ Đánh giá tính hợp lệ của dữ liệu.
Ví dụ kiểm tra user input có đúng với rule của hệ thống không (ví dụ user credentials…)
+ Chuyển đổi dữ liệu:
Ví dụ convert định dạng file, chuyển đổi tỉ giá, language translation ….
+ Đưa ra quyết định về nghiệp vụ:
Ví dụ đưa ra các dữ liệu, lời khuyên tư vấn đầu tư dựa trên user input và các dữ liệu đang có
Ví dụ có tính integration: thực hiện chính sách của công ty là từ ngày 20 – 24 thì áp dụng cách tính giá của phòng Sale 1. Sau thời điểm đó thì áp dụng cách tính giá của phòng Sales 2.
+ Thực hiện việc xử lý dữ liệu theo một quy trình (workflows): ví dụ controller tiếp nhận yêu cầu xuất kho 300 chiếc ô tô từ kho A từ user. Sau khi kiểm tra tính chính quy của việc gửi yêu cầu, Controller chuyển yêu cầu này thành lợi gọi hệ thống để thông báo cho Model. Tuy nhiên việc xuất kho 300 chiếc ô tô cần phải được thực hiện theo 1 workflow mà chỉ có Model biết. Tạm thời bỏ qua sự xuất hiện của một rule engine, chúng ta có thể thấy Model thực hiện một số đoạn code có tính thủ tục như: 1) Thông báo với module sales về việc bán được 300 chiếc ô tô và yêu cầu trả lời. 3) Model sales ghi nhận và kiểm tra chính sách hoa hồng và thời điểm hiện tại và chuyển tiếp yêu cầu đến module Inventory và module Accounting 4) module Accounting thực hiện việc tính toán, báo giá thanh toán theo USD và VND với tỉ giá ở thời điểm hiện tại cũng như không quên trừ triết khấu và hoa hồng và gửi kèm thông báo thanh toán theo theo yêu cầu xuất kho 5) module Inventory kiểm tra yêu cầu xuất kho từ Sales và thông báo thanh toán từ Accounting để xuất kho, và ghi nhận giao dịch bằng cách ghi lại mã số yêu cầu của Sales và mã số thanh toán của Accounting. module này tiếp tục kiểm tra số ô tô có trong kho theo chất lượng và đặc tả yêu cầu rồi trả lời: có được hay không 6) Nếu được, nó sẽ thành lập thông báo xuất kho ….. Cuối cùng Model trả lại trạng thái xử lý và dữ liệu nếu có.

Do có 2 vai trò tương đối tách biệt cho nên một Model thường được tách thành các lớp có các domain xử lý khác biệt
+ Business logic thường là xử lý rule hay policy của nghiệp vụ cũng như business workflows. Tầng này có sự góp mặt của các rule engine và các integration engine (trong đó có Spring bên Java và Flow3, Scarlet, Seasar, PHPCrafty bên PHP).
+ Domain data: Cung cấp/lưu trữ dữ liệu và việc chuyển đổi dữ liệu thành các dạng khác nhau theo yêu cầu. Các tầng như Persistent Layer nằm ở đây. Vì thế chúng ta sẽ gặp các lớp của PDO (PHP Data Object), Pear MDB2, PHP Doctrine, JDBC, JTA, JPA, Hibernate, JDO … và cả các lớp thực hiện DAO.

Trong các tình huống đơn giản, Model chỉ làm vài thao tác đơn giản như fetch dữ liệu từ database. Trong các tình huống phức tạp, việc xử lý có thể là tổ hợp của hàng trăm lớp diễn ra trên 1 hoặc vài server hoặc thậm chí dữ liệu hay quyết định được đưa ra từ Model lại là tổng hợp kết quả từ 1 vài data center nằm rải rác trên vài lục địa. Do vậy trong Model không chỉ có các thao tác trên database và có còn là file system, memory, networking I/O …

Worlflow mà Model điều khiển hoàn toàn có tính nghiệp vụ đặc thù. Nó khác với Application Flow vốn có tính hệ thống và thiên về technical analysis (phần cứng hay phần mềm) của Controller. Applicaton flow được xử lý như thế nào chủ yếu là do software architect xác định nhưng với workflows thì đó là do các business analyst xác định do nó thiên về nghiệp vụ (gần với cuộc sống và cách tổ chức quy trình làm việc của 1 tổ chức chứ không phải là quy trình kĩ thuật của thiết kế hướng đối tượng).

Model là Passive để hoạt động như là một Service Layer nhằm có thể re-use giữa các Controller nhưng nó không phải là dead-end. Thay vào đó nó cần biết giao tiếp với Controller như thế nào cho có hiệu quả. Sự hiệu quả này thể hiện ở 2 hướng

+ Signal hay message
+ Data type

Một software architect của Microsoft thường nhấn mạnh đến The Power Of Sameness trong software development trong đó bao gồm
+ Coding standard
+ Naming matters
+ Common interface

Khi Controller gọi Model thông qua API của Model, nó cần biết 1 số behavior chung của Model (tức là common interface). Ví dụ:

+ Cách Model đó gửi signal về quá trình nó xử lý yêu cầu. Có hay không có Exception, kiểu của Exception, Exception trong trường hợp nào. Những cái đó cần được comment chi tiết
+ Kiểu trả lại cần nhất quán và well-defined

Cái mà Controller quan tâm đến output của Model chính là trạng thái (message : false, true) hay dữ liệu. Vì Model thực hiện phần nghiệp vụ nên dữ liệu trả lại của nó cần phải phản ánh tính nghiệp vụ. Thông thường một kiểu trả lại được coi là well-defined nếu nó là một BO (Business Object) tức là một lớp getter/setter để nhận và xuất dữ liệu. BO thường là có kiểu phản ánh bản chất dữ liệu mà nó có ví dụ như

+ User
+ Product
+ Employee

Bằng cách trả lại các đối tượng được định nghĩa rõ ràng, Model trả tỏ ra có trách nhiệm với Controller hay các thành phần gọi nó để giúp các thành phần này bớt confused (giảm các đoạn mã if/else/switch/instanceof/try/catch) và tạo ra sức mạnh của cái gọi là The Power Of Sameness. Tuy nhiên, việc BO có thể chỉ là một data container thuần túy hay là một Domain Object thì còn đang gây tranh cãi vì getter/setter thuần túy sẽ gây sự nghi ngờ về tính hợp lệ của encapsulation. Tuy nhiên tôi vẫn có một quan điểm khác về kiểu của BO trong khi lập trình PHP.

Tương tự như trong trường hợp Controller lấy state từ Model, khi Controller cung cấp thông số cho Model để Model trả lại state theo hướng mà Controller mong muốn từ Controller cũng phải định nghĩa được 1 common interface.

VIEW

View là các lớp định nghĩa cách thức trình bày dữ liệu (không update dữ liệu). Trong các web framework, nó gồm 2 phần chính:
+ Template file định nghĩa cấu trúc và cách thức trình bày dữ liệu cho user. Ví dụ như layout, color, windows …
+ Logic xử lý cách áp dụng dữ liệu vào cấu trúc trình bày. Logic này có thể bao gồm việc kiểm tra định dạng dữ liệu, chuyển đổi định dạng dữ liệu sang một sạng dữ liệu trung gian để có thể hiển thị với cấu trúc template đang có…, kiểm tra trạng thái và đặc tính của dữ liệu để lựa chọn một cấu trúc hiện thị phù hợp. Tất nhiên là trong Passive View thì việc lựa chọn cấu trúc hiện thị đôi khi lại do Controller.

Bản thân View cũng là một tổ hợp của nhiều lớp. Và nó cũng có thể có SubView để giảm tải trên 1 số lớp chính và để sử dụng lại mã. Và do vậy tính logic của View có thể là logic của một cây phân cấp.

Trong mô hình truyền thống, View có trách nhiệm chuyển đổi dữ liệu hay state của Model thành cấu trúc visual. Do vậy dữ liệu của Model cần well-defined (xem ở trên). Sự tách biệt của 2 thành phần này sẽ giúp cho người lập trình phân định được 1 biên giới rõ ràng giữa cách thức lưu trữ/lấy dữ liệu và cách trình bày dữ liệu. Do vậy tính phức tạp của quy trình lấy dữ liệu, xử lý dữ liệu cũng như (sự thay đổi của chúng theo thời gian) trước khi trả về sẽ không làm ảnh hưởng đến việc trình bày dữ liệu. Do vậy sự khác biệt về công nghệ lấy dữ liệu và công nghệ render không gây ảnh hưởng đến ứng dụng. Điều này khá quan trọng trong việc tích hợp các ứng dụng.

Ngoài ra, cách làm này thực sự đảm bảo việc tách biệt vai trò của người thiết kế giao diện với vai trò của lập trình viên thiên về dữ liệu. Như vậy khi làm việc theo nhóm, PM có thể tổ chức nhóm phát triển thành các nhóm kĩ năng và phát triển ứng dụng song song với nhau

+ Page designer
+ Application flow developer
+ Business Process and Data developer

Tuy nhiên, View của thế giới hiện tại đã khác đi nhiều. Có một lớp lập trình viên thiên về tầng presentation đã ra đời. Do vậy, nhóm kĩ năng mới sẽ là

+ Page designer: những người hiểu template file và cách design nó sao cho đẹp
+ Presentation Developer: những người hiểu template, hiểu template cần dữ liệu từ nguồn nào và còn hiểu cả cách cấu trúc template cần thay đổi như thế nào với dữ liệu và sự kiện từ Action Controller gửi xuống. Họ còn quan tâm đến việc View đó được sử dụng và sử dụng lại như thế nào trong các application flows khác nhau (ví dụ bối cảnh ajax). Đặc biệt họ quan tâm đến các ứng dụng mashup.
+ Application flow developer: người hướng đến việc render toàn bộ trang, page navigation và để trách nhiệm render từng khối cụ thể của trang vào Presentation Developer
+ Business Process and Data developer: người chỉ quan tâm đến việc kiểm tra tính hợp lệ của user input, business workflows, tính tích hợp của quy trình và dữ liệu nhưng không quan tâm đến dữ liệu đó được sử dụng ở đâu và theo cách render nào.

Vai trò của View cần thay đổi đặc biệt là các ứng dụng web thiên về View phức tạp khi vai trò của Model đã trở nên ổn định.

—————————————————————-
FAT CONTROLLER, THIN CONTROLLER VÀ GOD CLASS
—————————————————————-

Trong cộng đồng CakePHP, Zend Framework và Rails từ 1 – 2 năm trở lại đây bắt đầu xuất hiện lời ca thán về fat controller hay thin controller. Theo họ, việc chuyển một số công việc của Controller vào Model là hợp lý hơn. Phải chăng đó là dấu hiệu của God Class? Trong lập trình hướng đối tượng với MVC, việc tạo là một God Class là điều nên tránh. Fat Controller có thể là hiện tượng rời rạc của cái gọi là God Class. Tuy nhiên nó có thể chỉ là cách quan sát và nhận thức về tính thủ tục và labour-extensive của Controller hay View và tính tự động hóa do framework-backed của Model. Nhu cầu điều phối lại chức năng của Model, Controller và View rõ ràng là dấu hiệu của Code Smells.

Ví dụ: việc thiết kế Model thiếu trách nhiệm khiến cho công việc lọc và xử lý dữ liệu trả lại trên Controller và View trở nên labour-extensive hơn: http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model

Theo quan điểm của tôi, nếu bạn thấy Controller của bạn hay View làm nhiều hơn logic của nó cần có trong khi Model lại hơi ít việc quá thì hay xem lại cách thức giao tiếp giữa 3 thành phần này. Giao diện giữa chúng càng compact thì mô hình của bạn càng hiệu quả.

—————————————————————-
KHI CONTROLLER TRỞ THÀNH GOD CLASS
—————————————————————-

Controller có lẽ thành phần bị phê phán nhiều nhất trong MVC. Như đã nói ở trên rất nhiều những người code Rails sau khi đã định nghĩa Model dựa trên ActiveRecords để làm các công việc như extract data, update data và validate dữ liệu thì họ bỏ hết trách nhiệm xử lý business logic sang cho Controller. Controller cũng đóng vai trò là thành phần quản lý việc cung cấp dữ liệu cho View nên View thực sự là Passive. Thậm chí Controller còn biết cả cấu trúc tên biến dữ liệu sẽ dùng trên View. Lúc đó View giảm tính Logic của nó xuống chỉ là còn là điều khiển việc render trên 1 cấu trúc có sẵn. Vì thế ta thấy có công thức View = ViewRenderer.

Các khái niệm như partial hay slot chỉ là một cách tăng cường tính sử dụng lại view template và các view helper cũng chỉ làm 1 số logic xử lý dữ liệu trên View trước khi nó được render trên 1 cấu trúc template. Dữ liệu hoàn toàn là do Controller cung cấp. Theo cách này DRY biến mất vì cùng một thao tác cung cấp dữ liệu cho View có thể được duplicate trên nhiều Controller. Trên thực tế việc sử dụng lại View chẳng qua chỉ là sử dụng lại cấu trúc HTML và cách render dữ liệu trên trang HTML đó. Muốn dùng lại dữ liệu, bạn có thể cần pass cả đối tượng Model xuống View. http://mentalized.net/journal/2006/12/08/simplifying_my_rails_views/ Tôi gọi đây là một bad practice.

Cái mà View template cần chính là một thứ DTO (VOs) hoặc BO không phải là cả model vì chúng ta cần tránh phô trương quá nhiều logic trên template. Chúng ta nên tập trung các thao tác trên dữ liệu trên 1 hay 1 số node chính (đặc biệt là các node điều phối) của mô hình MVC thay vì trên các nhánh phụ để tổ chức và quản lý tài nguyên và nghiệp vụ cho dễ hơn.

Nếu như Controller xử lý quá nhiều (ví dụ như edit hay add 1 multi-step form là trường hợp tôi thấy khó chịu nhất) thì đó thường là liên quan đến xử lý user input thành dạng được chuẩn hóa trước khi phân tích nó thành 1 lời gọi trên Model. Thường thì khi đến Model, user input đã phải khá là fine grained. Tuy nhiên đối với các form phức tạp với nhiều checkbox có tính phân nhánh thì việc để Controller thực hiện việc validate dữ liệu là rất nặng nề. Như thôi đã nói ở trên Controller chỉ thực hiện các basic validation (ví dụ diễn giải URL thành các module, controller class và action method). Nhưng đối mặt với các form phức tạp với 20 – 30 input có phân nhánh mà để xử lý Controller có thể phải phân tích đến 10+ trường hợp và mỗi trường hợp có thể có đến nhiều hơn 1 trường hợp phụ thì Controller đã có nguy cơ phình to. Khi đó nhu cầu phân tách Controller đã xuất hiện.

Thông thường Controller được tách thành 3 lớp chính
+ Dispatcher
+ Filter
+ Event Handler: lớp Action trên Struts hay Zend hoặc Controller trên CakePHP, chính là nơi sẽ làm việc với user input và các quyết định trên View

Khi Event Handler Controller bị phình thì rõ ràng có lý do để xét đến
+ User Input Validation
+ Multistep View Handler
+ Changes Committer
+ View Selection

Theo cách làm của tôi, User Input Validation Logic nên được chuyển về cho Model và xác nhận rõ việc đánh giá user input theo các rule của application là một vấn đề business logic thay vì application flow logic. Điều này có tính hợp lý riêng. Ví dụ: trên trang contact, input có tên là job position không cần phải validate nhưng trên trang sign up thì lại cần. Lý do của sự khác biệt: do yêu cầu của nghiệp vụ. Rõ ràng là cách quy định này có thể thay đổi từ app này sang app khác mà không phụ thuộc vào software architect.

Khi đó thay vì dùng if/else, lớp thực hiện User Input Validation sẽ cài đặt các rule có sẵn hoặc custom rule hoàn toàn cách khỏi lớp Event Handler. Controller phụ trách event handler sẽ gọi đến Model chuyên biệt về xử lý user input này và yêu cầu validate hoặc không. Trong các trường hợp đặc biệt một form validation như vậy có thể re-use lại ở nhiều Controller khác nhau và hỗ trợ tính kế thừa.

Ví dụ:
+ Controller A sử dụng PasswordChangeForm để validate dữ liệu với các input pass1, pass2 và email
+ Controller B sử dụng PasswordChangeForm2 extends từ PasswordChangeForm với thêm input là username

Như vậy việc tách user input ở mức form ra khỏi Controller sẽ giúp

+ Reuse code thông qua re-use cả class hoặc extend
+ Reuse rule checking thông qua việc định nghĩa rule thành các chuẩn riêng
+ Reuse tính gắn kết rule vào form và do đó đơn giản hóa việc apply quy trình nghiệp vụ trên form.

Bằng cách này bạn sẽ thấy Event Handler Controller đã đơn giản đi rất nhiều. Trong phần tiếp theo tôi sẽ trình bày cách thiết kế MVC Pull của tôi để tiếp tục giảm vai trò điều phối của Controller và tăng tính chủ động của View

(còn tiếp)

—————————————————————-
Phụ lục
—————————————————————-

Code demo về việc tách form ra khỏi Controller. Các đoạn code dưới đây là các code thực sự chạy vận hành trên PONE framework để cung cấp 1 số dịch vụ tại World’Vest Base Inc. Tuy nhiên, đây là các code ở mức application developer. Do vậy, code này chỉ có thể test nếu có PONE framework. PONE cung cấp mô hình Observer pattern để các lớp dưới đây vận hành được.

File Home_PagesController: file Controller. Xem method contactAction()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
_layout->attachCss('home');
 
        // Attach file: javascript
        $this->_layout->attachScript('home');
 
        // Attach file: meta
        $this->_layout->attachMeta('home');
    }
 
    /**
     * When use comes to this page by a mistake, redirect them to the about-us page
     *
     * @link   http://www.wvbresearch.com/home/pages
     * @name   index
     * @access public
     */
    public function indexAction()
    {
        $this->forward('home', 'pages', 'about');
    }
 
    /**
     * Show the introduction page about the website and company behind it
     *
     * @link   http://www.wvbresearch.com/home/pages/about
     * @name   about
     * @access public
     */
    public function aboutAction()
    {
        // Attach placeholder: the name of ElementGroup
        $this->_layout->registerBody('homeAbout');
 
        // Set content for the response
        $this->_response->setContent($this->_layout->render());
    }
 
    /**
     * Show the contact page
     *
     * @link   http://www.wvbresearch.com/home/pages/contact
     * @name   contact
     * @access public
     */
    public function contactAction()
    {
        // Instantiate form object
        $this->initForm('contact');
        // Create action state object
        $this->initState();
 
        try
        {
            // Check if the form is submitted and/or is submitted correctly
            if (false === $this->_form->isPost() || false === $this->_form->validate())
            {
                throw new Exception();
            }
 
            // Initialize the model object wih an appropriate database access object
            $model    = new ContactModel($this->getDatabaseConnection('oracleweb', true));
 
            // Persist the form data into data storage medium (database, file system, messaging server, email server, file-backed memory server)
            if (false === $model->save($this->_form))
            {
                throw new Exception();
            }
        }
        catch (Exception $ex)
        {
            // the form input is not complete. User need to fill it (if the form is rendered at the first time)
            // or user need to correct the data and submit again
            $this->_state->setState(Pone_Action_State::FORM_INCOMPLETE);
        }
 
        // Render the body part that contains contact form
        $this->_layout->registerBody('homeContact');
 
        // Set content for the response
        $this->_response->setContent($this->_layout->render());
    }
 
    /**
     * Show the faqs page
     *
     * @link   http://www.wvbresearch.com/home/pages/faq
     * @name   faq
     * @access public
     */
    public function faqAction()
    {
        // Attach placeholder: the name of ElementGroup
        $this->_layout->registerBody('homeFaq');
 
        // Set content for the response
        $this->_response->setContent($this->_layout->render());
    }
 
    /**
     * Show the WVB global offices page
     *
     * @see    Group_HomeGlobalOffices
     * @see    index.tpl.php
     * @link   http://www.wvbresearch.com/home/pages/offices
     * @name   WVB Global Offices
     * @access public
     */
    public function officesAction()
    {
        // Attach placeholder: the name of ElementGroup
        $this->_layout->registerBody('homeGlobalOffices');
 
        // Set content for the response
        $this->_response->setContent($this->_layout->render());
    }
 
    /**
     * Show the sitemap page
     *
     * @link   http://www.wvbresearch.com/home/pages/sitemap
     * @name   faq
     * @access public
     */
    public function sitemapAction()
    {
        // Attach placeholder: the name of ElementGroup
        $this->_layout->registerBody('homeSitemap');
 
        // Set content for the response
        $this->_response->setContent($this->_layout->render());
    }
 
    /**
     * Show the terms and conditions page
     *
     * @link   http://www.wvbresearch.com/home/pages/termsandconditions
     * @name   termsandconditions
     * @access public
     */
    public function termsandconditionsAction()
    {
        // Attach placeholder: the name of ElementGroup
        $this->_layout->registerBody('homeTerms');
 
        // Set content for the response
        $this->_response->setContent($this->_layout->render());
    }
 
    /**
     * Show the terms and conditions page
     *
     * @link   http://www.wvbresearch.com/home/pages/termsandconditions
     * @name   termsandconditions
     * @access public
     */
    public function privacyAction()
    {
        // Attach placeholder: the name of ElementGroup
        $this->_layout->registerBody('homePrivacy');
 
        // Set content for the response
        $this->_response->setContent($this->_layout->render());
    }
}
 
?>

File Form_Contact đóng vai trò như là Form Model, một model đặc biệt phục vụ cho việc xử lý form validation dựa trên business rules dành cho form.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
setFormKey('contact');
 
        $this->setFormFeedbackHeader(_t('common.error.form.false'));
 
        $titleRules = array(
        Pone_Form_Rule::NOT_EMPTY => array('feedback' => _t('common.error.title.empty'))
        );
        $this->setValidationRule('title', $titleRules);
 
        $nameRules = array(
        Pone_Form_Rule::NOT_EMPTY => array('feedback' => _t('common.error.name.empty'))
        );
        $this->setValidationRule('name', $nameRules);
 
        $emailRules = array(
        Pone_Form_Rule::EMAIL => array('feedback' => _t('common.error.email.notvalid'))
        );
        $this->setValidationRule('email', $emailRules);
 
        $contentRules = array(
        Pone_Form_Rule::NOT_EMPTY => array('feedback' => _t('common.error.content.empty'))
        );
        $this->setValidationRule('content', $contentRules);
    }
}
?>

File Group_HomeContact: Vùng View sẽ tương tác trực tiếp với Form trên

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
getFront()->getActionController();
		$this->form = $action->getDataForm();
 
		if (null    === $this->form)
		{
			throw new Pone_Exception('This element group is form-based so the action controller needs to initialize a form object for being re-used in this object');
		}
 
		$message    = $action->getActionState();
 
		if (Pone_Action_State::OK === $message->getState())
		{
			$this->_templateFile  = 'homeContactCompletion';
		}
	}
}
?>
[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

28
Apr 08

6 giai đoạn của một người học lập trình (*)

Để học bất cứ một ngôn ngữ lập trình nào những người mới bao giờ cũng phải trải qua 6 giai đoạn.

1. Quan niệm
2. Thử nghiệm
3. Trải nghiệm
4. Kiểm nghiệm
5. Chiêm nghiệm
6. Sáng tạo

Quan niệm
Hãy xác định nhiệm vụ học cho các bạn. Không có định hướng, không còn tầm nhìn bao quát về thế giới phần mềm và không có cá tính, bạn chắc rồi cũng rời bỏ sớm ngành phần mềm nếu không thì cũng chỉ là một coder hay tester ba phải, người mà lúc nào cũng chỉ được coi là một nhân vật bình thường về mọi mặt, không có sự nổi bật và luôn đứng đầu trong đề cử danh sách về hưu non.

Tiêu chuẩn số 1 của một nhà phát triển phần mềm giỏi là sự đề cao tự học. Trường lớp hay trung tâm không phải là nơi đáng tin cậy để học vì người giỏi ko bao giờ chịu mài đũng quần trên ghế bục giảng để giảng đi giảng lại một thứ kiến thức liên tục cũ đi sau vài tháng. Nếu người giỏi thích nói chuyện thì conference là chỗ của họ vì họ thích trao đổi với các industry expert chứ không phải là dọa dẫm học viên.

Diễn đàn này cũng có thể là nơi để học hỏi nhưng đừng nghĩ là người có hiểu biết sẽ trả lời bạn một cách tường tận và chi tiết như thể họ là ông nội của bạn vậy. Muốn họ trả lời hãy học cách hỏi, trước khi hỏi hãy search. Sau khi nhận được câu trả lời hãy search.

Thử nghiệm
PHP là một công nghệ bao gồm có 6 bộ phận:
+ Bộ thông dịch
+ Ngôn ngữ
+ Cấu trúc dữ liệu
+ Các thuật toán trên dữ liệu hay còn gọi là các API
+ Các công nghệ đi kèm hoặc có thể giao tiếp được với PHP.
+ Các best practice đặc thù của riêng công nghệ đó.

Hãy tập cài đặt bộ thông dịch PHP, Apache, MySQL và chạy triển khai các ứng dụng PHP có sẵn.
Hãy thử nghiệm ngôn ngữ PHP với các vòng lặp, điều kiện, in, nhúng HTML, làm quen function, method, class
Cấu trúc dữ liệu là một phần khác của PHP. Ở công nghệ này Hash, Array và Map đều được gộp vào kiểu array. Rất dễ chịu cho bạn khi bạn đã từng làm quen với các cấu trúc dữ liệu của C# hay Java.
Cấu trúc dữ liệu không phải là một cấu trúc chết. PHP cung cấp khoảng hơn 1000 function (API) xử lý nó. Array là một kiểu như vậy. DOM là một kiểu khác. Làm bài tập trên các API dạng này là một cách tốt để làm quen với ngôn ngữ và bộ thông dịch. Các bài tập có thể chỉ là in ra một cái resume, tạo một cái layout đơn giản nhất từ việc sử dụng include, tạo một form nhập liệu đơn giản, tạo một form upload đơn giản…

Tài liệu sách vở thì có rất nhiều. Bạn nên đọc các chương trong PHP Manual. Đọc các tutorial trên mạng và luyện tiếng Anh. Các ebook đáng chú ý:

++ Apress Beginning PHP and MySQL 5 From Novice to Professional 2nd Edition (2006)
++ Apress Beginning PHP and PostgreSQL E.Commerce (2006)
++ Prentice Hall PHP 5 Power Programming (2004)
++ O’reilly Programming PHP 2nd Edition (2006)

Các công nghệ đi kèm với PHP là một thế giới cực kì phức tạp. Bạn có thể sẽ làm quen với các công nghệ opcode hay biên dịch mã PHP ra mã nhị phân để chạy thay vì nhìn nó dưới dạng text. Nó là một extension nguồn mở của công nghệ PHP. Bạn cũng có thể quan tâm đến việc sử dụng PHP để giao tiếp với các hệ thống con trong Linux như shared memory, gettext, socket, stream… Socket và stream là các công cụ vạn năng để PHP giao tiếp với các hệ thống phần cứng và phần mềm. Bạn cũng có thể quan tâm đến sử dụng PHP và C trên cùng một file PHP thông thường hay nhúng mã dll của các thư viện trên Windows vào PHP và sử dụng lại. PHP làm việc này thông qua việc sử dụng một ext. mã nguồn mở do Wez viết có thể tải về PECL. Bạn cũng có thể quan tâm đến việc sử dụng PHP để viết các ứng dụng desktop mà bạn có lẽ vẫn dùng VB để viết bằng cách sử dụng thư viện GTK.

Tuy nhiên điều bạn có thể sẽ quan tâm hơn cả là liệu PHP được hỗ trợ như thế nào để giao tiếp với các hệ thống khác. PHP có thư viện để giao tiếp với Active Directory, LDAP, các hệ thống hỗ trợ SMTP/POP3/IMAP/FTP/SSL, SMS Gateway, GIS server, Router… PHP được Java hỗ trợ tốt để trở thành một công nghệ trên Java platform và nhờ đó bạn có thể gọi các gói Java để sử dụng lại hay sử dụng các application server của Java như Sun One Webserver, Glassfish application server thay cho Apache server hoặc sử dụng các dịch vụ Java khác như OpenSSO. JSON và XML được hỗ trợ buit-in trong PHP cũng là phần rất đáng tìm hiểu vì các nhà công nghiệp phần mềm ở các tổ chức chuẩn công nghiệp như OASIS, ECMA hay W3C sử dụng các gọi này để giúp PHP hỗ trợ kiến trúc Webservice/SOA, SDA, MDA (phần này do IBM đóng góp cho cộng đồng PHP)…..

Phần PHP giao tốt tốt nhất có lẽ là database. OCI do Oracle đóng góp, DB2 do IBM đóng góp, libmysql do MySQL AB đóng góp và pgsql do cộng đồng PostgreSQL đóng góp và luôn hỗ trợ các bản database mới nhất. Ngoài ra PHP có sẵn một database server SQLite nhúng đi kèm với mọi bản PHP 5.0+ có thể giúp bạn tiện trong việc xử lý các nhóm data nhỏ nhưng đủ mạnh mẽ như Access.

PHP là một công nghệ đặc biệt và nó có các đặc trưng riêng như share nothing. Điều này làm cho PHP có tính scalability rất tốt và được các mạng xã hội rất chuộng. Không phải ngẫu nhiên mà Tim Bray, giám đốc các công nghệ Web của Sun lại cho là PHP có tính scalable hơn Java trên tầng presentation (http://www.tbray.org/talks/php.de.pdf) trong khi từ trước đến nay họ vẫn tự hào là công nghệ Java cho họ thống trị thế giới web doanh nghiệp, các phần mềm ngân hàng và thị trường viễn thông, vượt trội cho với công nghệ .NET của Microsoft. Đặc điểm này của PHP cũng là tâm điểm tạo ra các best practice mà bạn cần khai thác khi lập trình với PHP.

Trải nghiệm
Là giai đoạn bạn bắt đầu quan tâm đến việc dùng PHP để code các ứng dụng sản xuất bằng việc tự tin sử dụng các API. Giai đoạn này hoàn toàn phù hợp với việc lấy một chứng chỉ Zend nếu bạn muốn. Tuy nhiên Zend chỉ chứng nhận bạn là có kĩ năng để nhớ API, một điều khá cần để code API với notepad Đặc trưng của giai đoạn này là thực hành để có các cảm nhận chung về kĩ năng code. Giai đoạn này sẽ đem lại cho bạn một niềm tự hào trẻ con nhưng rất cần thiết. Giai đoạn này bạn sẽ phải kết hợp PHP với CSS/XHTML, graphic design, SQL, web authoring, Javascript, web hosting, system scripting… Là một lập trình PHP, bạn tự biết mình phải đa tài hơn các lập trình viên ASP.NET, nơi tooling thống trị kĩ năng handcode, hơn Java, nơi mà kĩ năng viết business logic được chú trọng hơn

Kiểm nghiệm
Nếu như giai đoạn trải nghiệm là giai doạn code bung bét, bug tùm lum, bảo mật bằng không thì đây chính là lúc bạn quan tâm đến việc refactor lại code. Bạn có thể tạo ra nhiều function và class hơn trong một nỗ lực cố gắng làm cho chúng modular hơn. Bạn sẽ cố áp dụng các thư viện như PEAR hay Smarty, PHPSavant vào ứng dụng của bạn để làm cho cách code của bạn đi vào chiều hướng ổn định. Lúc này bạn đã thấy được sự cần thiết phải có một coding convention nhất quán ([url=http://pcdinh.googlepages.com/phpvietnamcodingstandards]Reference[/url). Bạn sẽ quan tâm đến bảo mật hơn. Giai đoạn này sẽ giúp bạn có một lối tư duy chín chắn hơn nhưng nhiều lo ngại hơn vì bạn cho rằng bạn vẫn chưa thực sự hiểu PHP.

Chiêm nghiệm
Đây là giai đoạn bạn đã tiến đến mức cao. Bạn đã nắm được bản chất của PHP. Bạn quan tâm đến cơ chế PHP vận hành ở mức compiler hơn. Bạn bắt đầu học UML, design pattern, tìm hiểu về các hệ thống lớn. Bạn đã vững vàng trong việc tạo ra các lớp và muốn tổ chức các lớp đó cho khoa học hơn. Bạn quan tâm đến các software engineering processes và tự hỏi làm sao để áp dụng XP, Scrum hay các agile methodology khác. Bạn sẽ quan tâm đến performance, object oriented engineering, database design, system architect, code review. Bạn sẽ bắt đầu chán Pear và ghét Smarty. Việc tương tác giữa PHP và các hệ thống khác như Python, Ruby, Jaav, Erlang .. trở nên quan trọng hơn với bạn lúc này vì cuối cùng thì bạn đã nhận ra PHP có nhiều điểm yếu nhưng không tới mức phải thay thế PHP bằng 1 giải pháp khác. Các công nghệ mã nguồn mở và tự do sử dụng phân phối như Java, Perl, Python, Ruby, JRuby, Groovy, Erlang, Lua… cho phép chúng tận dụng các thư viện của nhau cũng như các điểm mạnh riêng của nhau. Đó là thời gian bạn thấy sung sướng vì đã chọn 1 công nghệ nguồn mở như Java hay PHP hay Python.

Sáng tạo
Là giai đoạn cao nhất và cũng phức tạp nhất vì lúc này bạn đã hiểu công nghệ đến mức có thể triển khai các hệ thống lớn, customize và migrate các ứng dụng phức tạp. Có đủ tư duy và kiến trúc cũng như độ trải nghiệm thực tế để thiết kế hệ thống . Lúc này bạn đã có thể tự đặt cho mình mục tiêu làm các ứng dụng lớn với PHP kiểu như
+ Flickr: 60 000 LOC
+ Digg: 200 000 LOC
Bạn cũng có thể hoàn toàn tự tin dùng PHP để tạo ra các ứng dụng ERP, CRM, Forecast System vốn thường được code bằng Java, ASP.NET hay Delphi có truyền thống đắt đỏ, kén server, đòi hỏi nhiều tài nguyên. Lúc đó, PHP trong tay bạn đã vượt ra khỏi phạm vi của một công nghệ web vì bạn đã biết đủ PHP và mối quan hệ với các công nghệ bổ sung cũng như kinh nghiệm triển khai các công nghệ đó.

Bạn đột nhiên quan tâm nhiều đến các cuộc hội thảo. Bạn thấy kinh nghiệm của các industry expert thật cần thiết và gần gũi với khả năng của bạn. Có thể một lúc nào đó, bạn thấy mình gần như là một thought leader. Một lúc khác, bạn lại muốn nhập vai một C hacker.

Lúc này bạn đã lớn rồi. Ai dám khuyên bạn nữa chứ Cẩn thận, bạn có thể là một PHP Dictator đấy.

Tác giả: Phạm Công Định  

 (*) Tên bài viết do tôi tự đặt, vì bài viết này pcdinh reply 1 topic trên ddth.com nên không có title :)

[Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]