( تعداد نمایش : 2085 )

عمومی سازی و بومی سازی در جاوا

۱- مقدمه
عمومی سازی به فرآیند طراحی یک نرم افزار بمنظور تطبیق با زبانها و کشورهای مختلف بدون نیاز به تغییر در کد برنامه گفته می‌شود. یک برنامه عمومی شده دارای مشخصات زیر است:

  • در کنار یکسری اطلاعات بومی شده، برنامه می تواند در هر کشور و به هر زبانی اجرا شود.
  • عناصر متنی مانند پیغامها و عنوان اجزا رابط کاربر، در داخل کد برنامه (hard coding) مشخص نمی‌شوند، بلکه در یک منبع خارج از کد برنامه ذخیره و بصورت دینامیک بازیابی می‌شوند.
  • پشتیبانی از زبانهای جدید بدون نیاز به کامپایل مجدد برنامه.
  • اطلاعات حساس به منطقه جغرافیایی از قبیل تاریخ، پول و اعداد مطابق با استانداردهای تعریف شده در کشور کاربر نهایی نمایش داده می‌شود.
  • به آسانی قابل بومی سازی است.

بومی سازی به فرآیند تطبیق نرم افزار برای یک منطقه یا زبان خاص با اضافه کردن اجزا مربوط به آن منطقه و نیز ترجمه پیغامها گفته می‌شود. معمولا” بیشترین زمان فاز بومی سازی صرف ترجمه متن می‌شود . سایر اطلاعات از قبیل صدا و تصویر در صورت نیاز بومی سازی می‌شود. تیم بومی ساز نرم افزار همچنین امکان نمایش اطلاعاتی از قبیل تاریخ، اعداد و پول را برای یک منطقه خاص فراهم می آورند.

۱٫۱- Internationalization
عمومی سازی در حوزه برنامه نویسی عبارتست از فرآیند طراحی و نوشتن یک برنامه بطوریکه بتوان بصورت سراسری و در کشورهای مختلف از آن استفاده کرد.

یک برنامه عمومی شده قابلیت پشتیبانی زبانهای مختلف و پارامترهای وابسته مانند تاریخ، زمان، پول و… را بدون نیاز به تغییر کد برنامه دارا می‌باشد. این ایده تحت عنوان (soft coding) یا جداسازی اجزاء رابط کاربر از کد منطق برنامه نیز مطرح می‌شود.

11113 عمومی سازی و بومی سازی در جاوا

به جای کلمه Internationalization از مخفف آن I18N استفاده می‌شود. توضیح اینکه بین کاراکترهای شروع و پایان این کلمه ۱۸ کاراکتر وجود دارد. بنابراین برای سهولت از کلمه I18N و همچنین از I18N’d به جای Internationalizationed استفاده می‌شود.

۲٫۱- Localization
بومی‌سازی به فرآیند طراحی و پیاده‌سازی یک نرم افزار با قابلیت تطابق با یک زبان، فرهنگ، کشور و منطقه خاص گفته می‌شود. بسیاری از برنامه‌های نوشته شده برای یک کشور یا منطقه خاصی تنها در آن محدوده جغرافیائی قابل استفاده‌ می‌باشند.

به جای کلمه Localization از مخفف آن L10N نیز استفاده می‌شود.

22223 عمومی سازی و بومی سازی در جاوا

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

۲- عمومی سازی و بومی سازی در زبان جاوا
برخلاف سایر زبانهای برنامه‌نویسی، برنامه‌نویسان جاوا از امکانات و قابلیت‌های خوبی برای I18N برخوردار هستند.

۱٫۲- پشتیبانی یونی‌کد (Unicode Support)
کاراکترست (Character Set) زبان جاوا بر مبنای یونی‌کد (Unicode) است، بدین منظور نوع داده‌ای char برای تطابق با یونی‌کد، دو بایتی (۱۶ بیت) در نظر گرفته شده است. بنابراین نوع داده‌ای String که با استفاده از char ساخته می‌شود نیز یونی‌کد را پشتیبانی می‌کند. یونی‌کد طوری تعریف شده است که مقادیر ۰ تا ۱۲۷ برای استاندارد ASCII و ۰ تا ۲۵۵ برای استاندارد ISO 8859-1 (Latin-1) را در برمی‌گیرد. به دلیل شروع شدن دو استاندارد با عدد صفر، برنامه‌نویسانی که از قابلیت‌های I18N استفاده نمی‌کنند یا آشنا نیستند نیز می‌توانند بدون نیاز به شناخت یونی‌کد، برنامه‌هایی بنویسند که یونی‌کد را پشتیبانی کند، اما برنامه‌نویسانی که در محیط ویندوز برنامه می‌نویسند بایستی از تفاوت‌های استاندارد ISO 8859-1 و Windows Latin-1 (CP1252) آگاهی داشته باشند.

طول ۱۶ بیتی نوع داده‌ای char امکان ذخیره سازی مقادیر ۰ تا ۶۵۵۳۵ را فراهم می‌سازد. یک مقدار یونی‌کد با ‘\u’ شروع و یک مقدار هگزادسیمال (مبنای ۱۶) از ۰۰۰۰ تا FFFF پس از آن قرار می‌گیرد. دو خط مثال زیر، کاراکتر a را تعریف می‌کند:

char c1 = 'a'
char c2 = '\u0061'

نسخه JDK 1.3 یونی‌کد ۲٫۱ و نسخه JDK 1.4 یونی‌کد ۳٫۰ را پشتیبانی می‌کند.

سؤالی که مطرح می‌شود این است که آیا همه پلاتفرم‌ها یونی‌کد را پشتیبانی می‌کنند؟ جواب: در جاوا تمام استریم‌ها (Stream) که کاراکترها را پشتیبانی می‌کنند (java.io.Reader و java.io.Writer) به صورت اتوماتیک یک لایه مخفی که وظیفه تبدیل یونی‌کد به Encoding خاص سیستم عامل و بالعکس را انجام می‌دهند را فراخوانی می‌سازند. از طرف دیگر کلاسهای java.io.InputStreamReader و java.io.OutputStreamWriter دارای متدهایی برای تبدیل Encoding می‌باشند.

۲٫۲- Locale
Locale در زبان جاوا مجموعه‌ای از کلاسها برای سفارشی کردن، تغییر، نمایش و شکل دهی اطلاعات است. این کلاسها روی انتخاب زبان، تقویم، تاریخ و زمان تأثیر می‌گذارند. یک شیء از کلاس java.util.Locale نشان‌دهنده یک ناحیه جغرافیائی خاص با زبان آن ناحیه می‌باشد.

۳٫۲- Language
زبانهای قابل استفاده در Locale طبق استاندارد ISO 639 می‌باشد. جدول زیر چند مثال از نام زبان و کد تعریف شده را نشان می‌دهد. یک کد زبان با جزئیات آن زبان در نواحی مختلف استفاده نمی‌شود، برای مثال ممکن است Canadian French و Swiss French دارای گرامر و قوانین و واژه‌های متفاوت باشند ولی برای هر دو این زبانها کد fr در نظر گرفته می‌شود. به همین دلیل تنها زبانهای عمومی تعریف شده‌اند:

کد زبان زبان
en English
fr French
zh Chinese
ja Japanese
ar Arabic

4.2- Country
کشورهای قابل استفاده در Locale طبق استاندارد ISO 3165 می‌باشد. کد کشور در این استاندارد ۲ رقمی و با حروف بزرگ تعریف شده است. جدول زیر تعدادی از کشورهای تعریف شده را نشان می‌دهد.

کد کشور کشور
US United States
FR France
CA Canada
SA Saudi Arabia

5.2- Variant
Variant یک پسوند اختیاری برای یک Locale می‌باشد. Variant یک Locale سفارشی تعریف می‌کند که با Language و Country قابل ساخت نیست. از Variant می‌توان برای اضافه کردن یک مشخصه اضافی برای تعریف Locale استفاده کرد. برای مثال en _ us نشاندهنده English (United States) است اما en_us_ca برای تعریف English (U.S.A, California) یا en_us_mac برای تعریف English (U.S.A, Macintosh) می‌باشد.

۳- استفاده از Locale در جاوا
کلاس Locale دو سازنده (Constructor) دارد:

Locale (String language, String country)
Locale (String language, String country, String variant)

مثال:

Locale mylocale = new Locale (“en”, “US”)

در مثال بالا en زبان انگلیسی و US کشور آمریکا را تعریف می‌کند.

۱٫۳- Number
عبارت ۱,۲۳۴ چه عددی را نشان می‌دهد؟ جواب به منطقه و کشور بستگی دارد. در آمریکا این عبارت معنی “یک هزار و دویست و سی و چهار” را دارد اما در فرانسه این عبارت به معنی “یک و دویست و سی و چهار هزارم” است. بنابراین در نظر گرفتن قوانین نمایش اعداد و جدا کننده‌ها بسیار مهم بنظر می‌رسد. کلاس java.text.NumberFormat تعریف چگونگی نمایش اعداد برای یک منطقه خاص را به عهده دارد.

۲٫۳- Currency
هر کشور یا منطقه دارای واحد پولی جداگانه است. علاوه بر این مواردی از قبیل علامت اعداد منفی، صفر، جداکننده رقم‌ها، علامت نقطه اعشاری و مکان قرار گرفتن علامت پول ($۱۰، ۱۰ ریال) نیز در کشورها متفاوت است. متد getCurrencyInstance در کلاس java.text.NumberFormat امکان پرداختن به جزئیات شکل دهی اعداد پولی یک کشور خاص را فراهم می‌سازد.

۳٫۳- Date
مشابه سایر ساختارهای حساس به موقعیت جغرافیایی، فیلد تاریخ نیز جزئیات خاص خود را دارد. کوتاه یا کامل بودن تاریخ، جدا کننده روز، ماه و سال و نیز ترتیب آنها در کشورهای مختلف با یکدیگر متفاوت است.

۴٫۳- Calendar
کلاس java.text.Calendar بسیار نزدیک به کلاس java.util.Date است و اجازه می‌دهد سال، ماه، روز و زمان را از یک تاریخ استخراج نمایند. متد getCalendarInstance یک Calendar برای کشور مورد نظر بر می‌گرداند. تنها تقویم پیاده‌سازی توسط شرکت سان میکرو سیستم تقویم Gregorian می‌باشد. برای ساختن تقویم‌های محلی توصیه می‌شود از کلاس Calendar جاوا استفاده شود.

۵٫۳- Resource Bundle
ویژگی عمومی ساختن در JDK، مکانیزمی برای جداسازی عناصر رابط کاربر و سایر اطلاعات حساس به منطقه جغرافیایی از منطق برنامه است. این جداسازی انتقال فرآیند و تبدیل را آسان می‌سازد. بدین معنی که یک کد واحد نوشته می‌شود، در حالیکه ممکن است ۳۰ نسخه به زبان‌های مختلف از آن تولید شود.

Resource Bundle شامل یک فایل با فرمت ASCII است. نام این فایل شامل دو قسمت، نام اصلی و یک پسوند است. برای مثال برای ایجاد یک Resource Bundle با نام MyBundle برای زبانهای ژاپنی و فرانسوی دو فایل بنام‌های MyBundle_ja_JP و MyBundle_fr_FR با پسوند properties تعریف می‌شود. هر فایل Resource Bundle شامل یکسری زوج کلید / مقدار است. در هر خط بایستی یک زوج کلید / مقدار تعریف شود. مثال:

#MyResource.properties
#<key>=<value>
Text_not_found=The file could not be found
Text_Hello=Hello, world!

متد getBundle در کلاس java.util.ResourceBundle امکان دسترسی به یک Resource Bundle را فراهم می‌سازد. مثال کاملی از تعریف Locale برای زبان فارسی در انتهای این مقاله ذکر شده است.

۶٫۳- Character Sets
زبان جاوا با استفاده از یونی‌کد برای نمایش متن، فرآیند ذخیره سازی، دستکاری و نمایش کاراکترها را آسان ساخته است. یونی‌کد یک کارکترست ۱۶ بیتی است بدین معنی که می‌تواند ۲۱۶ کاراکتر تعریف کند. هر کاراکتر در این مجموعه منحصر بفرد است.

۷٫۳- Layout Manager
Layout Manager در یک برنامه چند زبانه بدلیل دو مشکل اساسی در هنگام ترجمه رابط کاربر بسیار مهم است:

  • افزایش و کاهش طول متن ترجمه شده
  • موقعیت اجزاء رابط کاربر

متن ترجمه شده اغلب کوتاه‌تر یا بلندتر از متن اصلی است. Layout Manager نقش بسیار مهمی دارد چون اندازه اجزاء رابط کاربر را با توجه به طول متن استفاده شده در عنوان آن تغییر می‌دهد و همچنین جابجایی اجزاء رابط کاربر را بدلیل تغییر اندازه متن کنترل می‌کند.

۴- یک مثال ساده
در این قسمت یک مثال ساده که پیغام‌هایی را به چندین زبان نمایش می‌دهد توضیح داده می‌شود. در این مثال با کلاسهای Locale و ResourceBundle جاوا آشنا می‌شوید.

۱٫۴- قبل از Internationalization
در نظر بگیرید که یک برنامه نوشته اید که چند پیغام را نمایش می‌دهد:

public class NotI18N {
    static public void main(String[] args) {
        System.out.println("Hello.");
        System.out.println("How are you?");
        System.out.println("Goodbye.");
    }
}

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

۲٫۴- بعد از Internationalization
کد زیر تغییر یافته برنامه شما را نشان می‌دهد. توجه کنید که متن پیغامها از داخل کد برنامه خارج شده است:

import java.util.*;

public class I18NSample {

    static public void main(String[] args) {

        String language;
        String country;

        if (args.length != 2) {
            language = new String("en");
            country = new String("US");
        } else {
            language = new String(args[0]);
            country = new String(args[1]);
        }

        Locale currentLocale;
        ResourceBundle messages;

        currentLocale = new Locale(language, country);

        messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);
        System.out.println(messages.getString("greetings"));
        System.out.println(messages.getString("inquiry"));
        System.out.println(messages.getString("farewell"));
    }
}

برای کامپایل و اجرای برنامه به فایلهای زیر نیاز دارید:

- I18NSample.java
- MessageBundle.properies
- MessageBundle_de_DE.properties
- MessageBundle_en_US.properties
- MessageBundle_fr_FR.properties
- MessageBundle_ar_SA.properties

3.4- اجرای برنامه
برنامه عمومی شده انعطاف پذیر است: این برنامه به کاربر نهایی اجازه می‌دهد کشور و زبان را بصورت پارامتر به برنامه وارد کند.

مثال زیر نتیجه اجرای برنامه را برای زبان فرانسوی (French) fr و کشور فرانسه (France) FR نشان می‌دهد:

greetings = Bonjour
farewell = Au revoir
inquiry = Comment allez-vous?

فایل MessageBundle_fr_FR.properties

% java I18NSample fr FR

Bonjour.
Comment allez-vous?
Au revoir.

خروجی برنامه

مثال بعدی نتیجه اجرای برنامه را برای زبان انگلیسی (English) en و کشور آمریکا (United States) US نشان می‌دهد:

greetings = Hello
farewell = Goodbye
inquiry = How are you?

فایل MessageBundle.properties

% java I18NSample en US

Hello.
How are you?
Goodbye.

خروجی برنامه

۵- اقدامات لازم برای I18N
بسیاری از برنامه‌ها از ابتدا عمومی و چند زبانه نیستند. این برنامه ها ممکن است از یک Prototype شروع شوند و یا قابلیت چند زبانه بودن در آنها در نظر گرفته نشده باشد. برای I18N ساختن یک برنامه موجود، بایستی مراحل زیر طی شده باشد:

۱٫۵- شناسایی اطلاعات حساس به زبان و منطقه
پیغامهای متنی صریح ترین فرم اطلاعاتی هستند که به زبان و منطقه جغرافیایی وابستگی دارند. بهرحال سایر اطلاعات نیز ممکن است به این دو عامل وابستگی داشته باشند. لیست زیر اطلاعات حساس به ملیت را نشان می‌دهد:

  • پیغامها
  • عنوان اجزای رابط کاربر
  • صداها
  • رنگها
  • گرافیک و تصاویر
  • تاریخ
  • زمان
  • پول
  • واحدهای اندازه گیری
  • شماره تلفن
  • آدرسهای پستی
  • طراحی صفحات

۲٫۵- جداسازی متنهای قابل ترجمه و انتقال به Resource Bundles
فرآیند ترجمه هزینه بر و گران است. شما می توانید این هزینه را با جداسازی متنهای نیازمند ترجمه و قرار دادن آنها در یک Resource Bundle کاهش دهید.

متنهای قابل ترجمه شامل پیغامهای وضعیت، پیغامهای خطا، فایلهای log و عنوان اجزا GUI می‌باشند. ضمن جداسازی این اطلاعات از کد برنامه، متغیرهایی که از این عنوانها استفاده می کنند بایستی بطور صریح و جداگانه تعریف شوند:

String buttonLabel = "OK";
...
JButton okButton = new JButton(buttonLabel);

3.5- پیغامهای ترکیبی (Compound Messages)
پیغامهای ترکیبی حاوی اطلاعات متغیر است. برای مثال در پیغام “.The disk contains 1100 files” عدد ۱۱۰۰ می تواند متغیر باشد. ترجمه این نوع پیغام بسیار مشکل است، زیرا برای مثال محل قرار گرفتن عدد ۱۱۰۰ در این عبارت در زبانهای مختلف با یکدیگر متفاوت است. پیغام زیر قابل ترجمه نیست چون ترتیب قرار گرفتن قسمتهای این جمله در داخل کد برنامه مشخص شده است.

Integer fileCount;
...
String diskStatus = "The disk contains " + fileCount.toString() + " files.";

4.5- نمایش اعداد و پول
اگر برنامه اعداد یا پول را نمایش می‌دهد، بایستی این اطلاعات به روشی مستقل از کشور یا منطقه خاص نمایش داده شود. کد زیر عمومی نیست چرا که نمی تواند اعداد را بصورت صحیح در تمام کشورها نمایش دهد:

Double amount;
TextField amountField;
...
String displayAmount = amount.toString();
amountField.setText(displayAmount);

در جاوا کلاس NumberFormat برای تغییر نمایش اعداد به زبانهای مختلف در نظر گرفته شده است.

۵٫۵- نمایش تاریخ و زمان
نمایش تاریخ و زمان نیز مشابه اعداد با توجه به زبان و کشور متفاوت است. اگر شما کدی مشابه زیر در برنامه دارید، بایستی آنرا تغییر دهید:

Date currentDate = new Date();
TextField dateField;
...
String dateString = currentDate.toString();
dateField.setText(dateString);

در زبان جاوا کلاس DateFormat وظیفه تنظیم چگونگی نمایش تاریخ و زمان را بر عهده دارد.

۶٫۵- استفاده از قابلیتهای یونی‌کد
کد زیر سعی می‌کند کاراکتر بودن یک حرف را بررسی کند:

char ch;
...
if ((ch >= 'a' && ch <= 'z') ||
    (ch >= 'A' && ch <= 'Z'))       // WRONG!

این کد تنها برای زبان انگلیسی قابل استفاده است. برای مثال این کد، حرف ü در کلمه آلمانی Grün را یا حرف پ در کلمه پارس را کاراکتر تشخیص نمی‌دهد.

متدهای مقایسه موجود در کلاس Character از استاندارد یونی‌کد برای شناسایی کاراکترها استفاده می‌کند. بنابراین کد بالا را می توان بصورت زیر تغییر داد:

char ch;
...
if (Character.isLetter(ch))

7.5- مقایسه رشته‌ها
معمولا هنگام مرتب سازی متن، رشته ها با یکدیگر مقایسه می‌شوند. یک برنامه معمولی برای مقایسه دو رشته ممکن است از کدی بصورت زیر استفاده کند:

String target;
String candidate;
...
if (target.equals(candidate)) {
...
if (target.compareTo(candidate) < 0) {
...

متدهای String.equals و String.compareTo عمل مقایسه را بصورت باینری انجام می دهند که برای بیشتر زبانهای موجود ناکارآمد است. برای مقایسه دو رشته بهتر است از کلاس Collator استفاده شود.

۸٫۵- تبدیل متنهای غیر یونی‌کد
کاراکترها در زبان برنامه نویسی جاوا بصورت یونی‌کد ذخیره می‌شود. اگر برنامه شما از اطلاعات غیر از یونی‌کد استفاده می‌کند، بایستی اطلاعات را به یونی‌کد تبدیل نمایید.

دیدگاه خود را بیان کنید.

باید وارد سایت شده باشید برای دیدگاه دادن