Sunday, August 17, 2008

پلت فرم های توسعه وب

تا به حال چندین نفر از من در مورد تکنولوژی های توسعه وب (Web Development Technologies) سوال کرده اند. بیشتر هم توقع داشته اند که به آن ها بگویم مثلا J2EE بهتر از PHP هست، بروید آن را یاد بگیرید. می دانید که تکنولوژی های زیادی برای این کار وجود دارد. اسم PHP، J2EE یا همان JavaEE و .NET را همه شنیده اند. به هر حال بخث خیلی مفصل هست. اینجا و اینجا را ببینید.

راستش را بخواهید دو سه سالی هست که به طور جدی روی توسعه برنامه های وبی کاری انجام نداده ام. ولی به عنوان کسی که سه چهار سالی با J2EE کار می کرده و با PHP، .NET و برخی تکنولوژی های دیگر آشنایی مختصری دارد، گفتم شاید چیزی بنویسم که به درد کسی بخورد. ولی به هر حال مطالب این پست را به قول خارجی ها as is در نظر بگیرید.

اگر در این زمینه آدم با تجربه ای نباشید، شاید فکر کنید یک آدم با تجربه بتواند به شما بگوید که کدام یک از این تکنولوژی ها بهتر است. باید بگویم که مساله خیلی پیجیده تر از این است که یک نفر بتواند به شما بگوید این تکنولوژی بهتر است یا آن یکی. اگر یکی از آن ها بهتر از بقیه بود، بعد از هفت هشت ده سال، آن یکی که بهتر بود باقی مانده بود و بقیه حذف می شدند. یا حداقل یکی می شد تکنولوژی غالب و بقیه می شدند مغلوب. مسئله این است که هیچ کدام از آن ها بهتر از یکی دیگر نیست. شاید بشود گفت در این شرایط و برای این کار و با این آدم ها، این بهتر از آن است ولی به طور کلی نمی شود این را گفت.

این را هم بگویم که بحث خیلی مفصل هست. در مورد هر کدام از تکنولوژی ها و راه کار آن ها برای حل مسئله می شود به اندازه چند کتاب صحبت کرد. ولی نه من آن قدر بلد هستم و نه اینجا جای نوشتن کتاب هست. فاکتور های خیلی زیادی در تصمیم گیری برای انتخاب تکنولوژی دخالت دارند. اینکه زمان یادگیری آن چقدر هست. اینکه هزینه و زمان توسعه آن چقدر هست و بعدا چقدر هزینه برای نگه داری صرف می شود. اینها همه بستگی به نوع پروژه دارد. مثلا توی یک پروژه ای که زیاد با پایگاه داده کار می کند ممکن است تکنولوژی A بهتر از B باشد. به علاوه خیلی وقت ها عوامل غیر فنی شما را مجبور می کند تصمیم خود را تغییر دهید. مثلا مشتری دلش می خواهد شما پروژه را با .NET انجام بدهید که کلاس بالاتری داشته باشد! شما هم هیچ طوری نمی توانید به او بفهمانید که در مورد این مسئله شما باید تصمیم بگیرید. ولی عموما این طور نیست که این پروژه را با این تکنولوژی انجام دهید و آن یکی را با آن. منطقی است که توی هر شرکت یا تیم، پروژه ها را با تکنولوژی ای که بر آن تسلط دارند توسعه بدهند.

توی دنیای دات نت معمولا کار اینطور شروع می شود. شما یک کتاب ASP.NET می خرید و یک سی دی ویژوال استدیو دو هزار و چند از رفیقتان قرض می گیرید یا یکی از این چیچی اکسپرس ها را از سایت مایکروسافت دانلود می کنید. بعد از اینکه سی دی را نصب کردید از صفحه اول کتاب شروع می کنید و توی فصل اول کتاب هم نوشته که چطور بروید توی منوی فایل و یک پروژه جدید بسازید. در ادامه کتاب هم نوشته چطور از کجا کدام چیز را روی صفحه drag کنید و بعد از جدول Properties کدام ویژگی را تغییر بدهید و اف چند را با کدام انگشتتان بزنید که پروژه اجرا شود. این خیلی خوب هست؛ از این جهت که شما بعد از خواندن یک کتاب چیزهای خوبی یاد می گیرید و می توانید پروژه های نسبتا خوبی را انجام دهید.

دنیای PHP شاید در شروع کار از این هم ساده تر باشد. اگر شما از HTML، JavaScript و CSS سر در بیاورید و قبلا با یک زبان برنامه نویسی هم کار کرده باشید، خیلی ساده و در عرض چند روز می توانید کار کردن با PHP را شروع کنید و در زمان کوتاهی تا حد قابل قبولی بر آن مسلط شوید. البته بلد بودن HTML، JavaScript و CSS که مهارت های پایه ای توی وب به حساب می آید، یادگیری هر تکنولوژی وبی را آسان تر می کند ولی نیاز به دانستن آن ها وقتی PHP کار می کنید بیشتر حس می شود.

البته این شروع کار است. مسائل دنیای واقعی معمولا خیلی پیچیده تر و بزرگ تر از آن است که بشود با خواندن یکی دوتا کتاب آن ها را حل کرد. ولی به هر حال شروع به کار خیلی مهم است.

این را هم بگویم که دنیای PHP و دات نت خیلی با هم تفاوت دارد. تفاوت اول یک جورهایی سیاسی یا فرهنگی است. دات نت یک تکنولوژی در انحصار (proprietary) مایکروسافت هست ولی پی اچ پی تفکرات و فرهنگ اپن سورس را با خودش دارد. استفاده از دات نت یعنی این که شما باید از ویژوال استدیو و ویندوز استفاده کنید (من تا به حال شرکتی را ندیده ام که از mono تحت سیتم عاملی غیر از ویندوز به جای اس دی کی مایکروسافت استفاده کند، دوستان دات نتی نظر بدهند). پی اچ پی یک جور هایی با My SQL و Apache و تا حد زیادی با Linux گره خورده. این مسئله موقعی اهمیت پیدا می کند که می بینیم این فرهنگ توی پروژه ها و کتابخانه های موجود برای این پلت فرم ها هم نفوذ کرده. تعداد پروژه های اپن سورسی که با PHP انجام شده خیلی بیشتر از پروژه های اپن سورسی است که با دات نت انجام شده و تقریبا برای هر کاری که تصور بکنید یک کتابخانه اپن سورس که با PHP نوشته شده باشد پیدا می کنید.

تفاوت دوم یک تفاوت فنی هست. پی اچ پی زبانی هست اسکریپتی که اصولا برای کار وب طراحی شده. در حالی که توی پلت فرم دات نت معمولا از C# و یا VB.NET که زبان هایی همه منظوره و کامپایلری (Compiled) هستند، برای نوشتن کدها استفاده می شود. من شخصا اینجا PHP را بیشتر می پسندم و فکر می کنم برای کار وب یک زبان اسکریپتی خیلی بهتر از یک زبان کامپایلری و Statically Typed مثل سی شارپ یا جاوا هست. در این رابطه اگر فرصت شد بعدا بیشتر توضیح می دهم.

فکر کنم باز هم دارد طولانی می شود. فعلا همینجا بس می کنم. بعدا شاید یکی دو پست دیگر در این رابطه نوشتم. خوشحال می شوم نظر بقسه دوستان وب کار را در این رابطه بشنوم.

Friday, August 01, 2008

آدم ها موجودات جالبی هستند. بعضی هایشان عجیب. بعضی هایشان فوق العاده. اصلا نمی توانم تصور کنم رندی پاوشی(Randy Pausch) که محرم سه چهار ماه پیش به من معرفی کرد، حالا مرده باشد. فیلم Last Lecture او توی دانشگاه Carnegie Malone خیلی مرا تحت تاثیر قرار داد. آدمی که می داند چند ماه دیگر در این دنیا نیست، اینقدر امیدوار و خوشحال است. محرم توی وبلاگش صحبت حکیمانه ای کرده: "به هر حال باقیمانده زندگی همه ما محدود است چه چند روز باشد چه چندین دهه! مهم نحوه استفاده مطلوب از این فرصت محدود است.". توصیه می کنم فیلم Last Lecture رندی پاوش را حتما ببینید. می تواند تاثیر خوبی توی زندگی شما داشته باشد.

Sunday, May 18, 2008

فوتبال

دوست دارم با یک نگاه اجتماعی این پست را بخوانید، نه ورزشی!

راستش را بخواهید از قهرمان شدن پرسپولیس خیلی خوشحال شدم. نه اینکه پرسپولیسی باشم؛ اتفاقا بیشتر به رنگ آبی علاقه دارم تا قرمز. خوشحال شدم برای اینکه فکر می کنم افشین قطبی ثابت کرد برای رسیدن به موفقیت در این جامعه راهی غیر از هوچی گری، دروغ گویی، حاشیه سازی و تظاهر هم وجود دارد. ثابت کرد که با صداقت داشتن، کوشش کردن، مصمم بودن و بدون حاشیه زندگی کردن هم می شود موفق بود. ثابت کرد که اگر مصمم باشی می توانی در یک محیط نا مناسب شرایط مناسبی را درست کنی. با اینکه همیشه بعد از بازی مصاحبه می کرد، یک بار به تصمیم داور اعتراض نکرد. یک بار نشد بگوید باخت ما به خاطر نوع بازی تیم مقابل بوده و مسئولیت شکست را خودش قبول می کرد. با اینکه 6 امتیاز از این تیم کسر شده بود یک بار سر و صدا نکرد که چرا اینطور شده. مطمئن هستم اگر این امتیازها از یک تیم دیگر کسر شده بود زمین را به آسمان می دوختند. این اخلاق قطبی یک جور هایی بقیه تیم را هم تحت تاثیر قرار داده بود. امیدوارم بتواند تاثیری هر چند کوچک روی بقیه جامعه داشته باشد. امروز ناخود آگاه یاد آن روزی افتادم که مصطفی کارخانه با تیم والیبال نوجوانان نایب قهرمان جهان شد. آن آدم هم شخصیت جالبی داشت. بدون حاشیه و مصمم. نمی دانم چرا فکر می کنم ارتباط معنی داری بین شخصیت افشین قطبی و مصطفی کارخانه وجود دارد.

Tuesday, April 29, 2008

نمای 320 درجه از آزمایشگاه پردازش موازی، جایی که هفته ای 50 ساعت از عمرم در آن می گذرد. با گوشی جدیدم عکس گرفتم :)







Saturday, February 23, 2008

Using Aspectj and Java Annotations to Try Again

We are working on a program that interacts with a hardware device using a com port for some months. After implementing many parts of software, we found that the communication channel is not as reliable as we expected, so we decided to add some "Try Again" functionality to our code. You have seen the "Try Again" dialog many times, but have you ever taught of how to implement one?

All you need is to invoke a method, if an exception occurs ask the user "Try Again?" and if the answer is "Yes" reinvoke the method. At first it seems so simple to me but after playing with some of OO design patterns I realized that many lines of code should be modified to implement the functionality in OO, so I decided to play a little AOP.

Here is the solution I found:

The first thing we need is to specify what methods must be tried again, Thanks to Java 5 annotations, this is very easy to tag some methods, so the first thing we need is a TryAgain Java annotation:

 
 

package com.blogspot.zoftware.aspects;

 
 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 
 

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface TryAgain {

int count() default 2;

boolean interactive() default true;

}

 
 

The count parameter specifies how many times the method should be reinvoked and the interactive parameter specifies if the user should be asked to try again or not. The second thing we need is an aspect which reinvokes the annotated methods, there are many AOP implementations in the java world but I like the annotation based aspectj the most, as it is very simple and supports standard java syntax, here is the code for the aspect:

 
 

package com.blogspot.zoftware.aspects;

 
 

import java.lang.reflect.Method;

 
 

import javax.swing.JOptionPane;

 
 

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.reflect.MethodSignature;

 
 

@Aspect

public class TryAgainAspect {

 
 

@Around("call(@TryAgain * *..*(..))")

public Object retry(ProceedingJoinPoint jp) throws Throwable{

Method method = ((MethodSignature)jp.getSignature()).getMethod();

TryAgain annotation = method.getAnnotation(TryAgain.class);

Throwable err = null;

 
 

for (int i = 0; i < annotation.count(); i++) {

try {

return jp.proceed();

} catch (Throwable e) {

err = e;

if(annotation.interactive() && !askRetry(e)) {

break;

}

}

}

 
 

throw err;

}

 
 

private boolean askRetry(Throwable e) {

String msg = "The following error occured:\n" + e + "\nRetry?";

return JOptionPane.showConfirmDialog(null, msg) == JOptionPane.YES_OPTION;

}

}


 

 
 

The retry advice, reinvokes every method which is tagged with @TryAgain annotation if an exception occurs (at most count times), so all you need to use this mechanism is to tag the methods that should be reinvoked on failures. Here is a sample usage:

 
 

package com.blogspot.zoftware.demo;

 
 

import com.blogspot.zoftware.aspects.TryAgain;

 
 

public class Foo {

 
 

@TryAgain(count = 3)

public void oftenFails() {

if(Math.random() < 0.6) {

throw new RuntimeException("Sorry, Failed!");

}

}

 
 

public static void main(String[] args) {

new Foo().oftenFails();

System.out.println("Passed");

}

}


 

 
 

The oftenFails method is the method that should be reinvoked, so I annotated it using @TryAgain. To run the code you need aspectj libraries (download here); you can use either dynamic (load time) or static weaving. To use load time weaving, place the following piece of XML into aop.xml under META-INF folder, then run the Foo class with -javaagent:aspectjweaver.jar command line argument.

 
 

<aspects>

<aspect name="com.blogspot.zoftware.aspects.TryAgainAspect" />

</aspects>


 

The mixture of Annotations and AspectJ is a powerful tool to solve many common software engineering problems.