با حمایت ما%۵
تخفیف بگیرد

logo-samandehi

برنامه نويسي اندرويد 13- قوائد نوشتار برنامه


Code Convention : (
قوائد نوشتار برنامه )

در هر کاری استانداردهایی وجود دارد. بخشی از این استانداردها به بهبود کیفیت کمک می کند، بخشی به تسریع توسعه، بخشی به بهبود فروش و ... . در برنامه نویسی هم استانداردهای بسیار زیادی وجود دارند که در این قسمت فقط به استاندارد نوشتاری برنامه توجه می شود.

قوائد نوشتار برنامه به هیچ عنوان دلخواه و اختیاری نیست بلکه یک امر بسیار مهم و واجب است. یک برنامه نویس با دیدن اینکه شما Code Convention را رعایت نکرده اید به راحتی می تواند بگوید که شما هیچ چیز از برنامه نویسی نمی دانید و درست هم می گوید. از طرفی صرف رعایت این نکات شما را برنامه نویس نمی کند اما سرعت شما را در رسیدن به اهدافتان بسیار زیاد خواهد کرد.

 

چرا باید Code Convention ها را رعایت گردند:

♦ 80% از زمان تولید برنامه صرف نگهداری و دیباگ آن می شود پس باید کد خوانا و قابل نگهداری باشد

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

♦ رعایت Code Convention ها موجب افزایش خوانایی برنامه شده و به سایر برنامه نویسان پروژه در فهمیدن سریع برنامه کمک خواهد کرد.

♦ اگر قرار باشد سورس برنامه به همراه برنامه عرضه شود نیاز است که تمیز و برای برنامه نویسان ثانوی قابل درک و استاندارد باشد.

در صورتیکه شما مطمئن هستید که همیشه خودتان کدهای خودتان را ویرایش می کنید لزوم استفاده از قوائد نوشتار از بین نمی رود و برای 80% زمان نگهداری برنامه هم که شده باید آنها را رعایت کنیم.

برای یک زبان برنامه نویسی مثل Java قوائد نوشتار متفاوتی وجود دارد که بعضی ترکیبی از دو یا چند قائده هستند. همه این قوائد بر حسب تجربه برای همه برنامه نویسان آشناست. در این قسمت از آموزش به قوائد نوشتاری که توسط شرکت Oracle تعیین شده بسنده می کنیم و با تغییراتی که هر کدام علت مهمی دارند تغییراتی در آن می دهیم.

 

قوائد مربوط به فایل:

» پسوند فایلهای سورس جاوا java خواهد بود مثل SomeClass.java

» از نوشتن بیشتر از 2000 خط برنامه در یک فایل جاوا پرهیز کنید

» محتوای یک فایلهای جاوا به ترتیب زیر نوشته می شود:

        » Comment هایی که برای مستند سازی کد است مانند توضیحاتی در مورد فایل یا کلاس، نام برنامه نویس و ... که در پایین توضیح داده شده.

        » نام package کلاس و سپس نام package های مورد نیاز کلاس که با استفاده از import معرفی می شوند

        » تعریف کلاس ( یا interface ) اصلی فایل

 

فاصله ها و خطوط:


» برای عمق دادن باید از 4 تا space استفاده کرد، استفاده از کاراکتر Tab غلط است. در IDE تنظیم میشود که TAB چهار Space باشد.

» طول خطوط نباید بیشتر از 80 کاراکتر عرض داشته باشد (به این گزینه توجه نمی کنیم چرا که توجه نکردن به آن در خوانایی برنامه بیشتر اثر دارد)

» هر متغیر در یک سطر تعریف می شود و نباید دو متغیر را در یک سطر تعریف کرد مثال:


  1. int someVariable1, someVariable2; // BAD
  2.  
  3. int someVariable1; // GOOD
  4. int someVariable2; // GOOD

 

» علامت های } و { بالافاصله به شکل زیر نوشته می شوند:


  1. // BAD
  2. private void someMethod()
  3. {
  4.     // statements
  5. }
  6.  
  7. // GOOD
  8. private void someMethod() {
  9.     // statements
  10. }
  11.  
  12. // BAD
  13. for (int i = 0; i < max; i++)
  14. {
  15.     // statements
  16. }
  17.  
  18. // GOOD
  19. for (int i = 0; i < max; i++) {
  20.     // statements
  21. }

 

» برای دریافتن قوائد ویرگول و اپراتور ها به مثال های زیر توجه کنید:


  1. if (a == b && c == d) // BAD
  2. if ((a == b) && (c == d)) // GOOD
  3.  
  4. for (expr1;expr2;expr3) // BAD
  5. for (expr1; expr2; expr3) // GOOD
  6.  
  7. a = (a+b)/(c*d); // BAD
  8. a = (a + b) / (c * d); // GOOD
  9.  
  10. prints("size is "+foo+"\n"); // BAD
  11. prints("size is " + foo + "\n"); // GOOD

 

 

بلوک ها و حلقه ها:


» برای دریافتن قالب صحیح به عبارات زیر توجه کنید:


  1. // GOOD
  2. return;
  3. return mArray.size();
  4. return (size ? size : defaultSize);
  5.  
  6.  
  7. // GOOD
  8. if (condition) {
  9.     statements;
  10. }
  11. if (condition) {
  12.     statements;
  13. } else {
  14.     statements;
  15. }
  16.  
  17. if (condition) {
  18.     statements;
  19. } else if (condition) {
  20.     statements;
  21. } else if (condition) {
  22.     statements;
  23. }
  24.  
  25.  
  26. // GOOD
  27. for (initialization; condition; update) {
  28.     statements;
  29. }
  30.  
  31.  
  32. // GOOD
  33. while (condition) {
  34.     statements;
  35. }
  36.  
  37. // GOOD
  38. do {
  39.     statements;
  40. } while (condition);
  41.  
  42.  
  43. // GOOD
  44. switch (condition) {
  45.     case ABC:
  46.         statements;
  47.         /* falls through */
  48.     case DEF:
  49.         statements;
  50.         break;
  51.  
  52.     case XYZ:
  53.         statements;
  54.         break;
  55.  
  56.     default:
  57.         statements;
  58.         break;
  59. }
  60.  
  61.  
  62. // GOOD
  63. try {
  64.     statements;
  65. } catch (ExceptionClass e) {
  66.     statements;
  67. }

 

 

تعریف کلاس:


» توضیحات کلاس نوشته می شود

» پس از توضیحات، نام کلاس نوشته می شود

» نام کلاس باید یک اسم باشد مثل Helper یا Worker و نباید فعل باشد.

» نام کلاس با حرف بزرگ شروع می شود و بعد از آن هر کلمه هم با حرف بزرگ شروع می شود مثل SomeWorker

» در حروف مخفف فقط حرف اول بزرگ نوشته می شود مثل HtmlParser و نه HTMLParser

» فیلدهای یک کلاس بعد از نام کلاس و قبل از هر متدی تعریف می شوند.

» فیلدها باید کاملاً نام گویایی داشته باشند تا از نام آنها کارایی آنها مشخص شود

» در صورتیکه فیلد private یا protected باشد از _ یا m در ابتدای آن استفاده می کنیم مثل private _someField یا private mSomeField

» در صورتیکه فیلد public باشد از p در ابتدای آن استفاده می کنیم مثل public pSomeField

» در صورتیکه فیلد یک ثابت باشد(static و final) آنرا با حروف بزرگ مینویسیم و کلمات را با _ جدا میکنیم مثل public static final SOME_CONST

» لزومی در مقداردهی اولیه برای 0، null، false وجود ندارد

» حرف اول فیلدها(بعد از m یا p) با حرف بزرگ و کلمات بعدی هم با حرف بزرگ شروع می شوند مثل private mSomeField

» برای نام نهادن از نوع boolean از can، is، should و مشابه این استفاده می کنیم مثل boolean canConnect یا boolean isConnected

» فیلدهای به ترتیب زیر مرتب می شوند:

» فیلدهای استاتیک به ترتیب public سپس protected سپس private

» فیلدهای غیر استاتیک به ترتیب public سپس protected سپس private

» پس از نام فیلدهای constructor ها نوشته می شود

» پس از constructor ها متدها نوشته می شوند

» متدهای مربوط به هم نزدیکتر به هم نوشته می شود و خواص public, protected, private اثری در آن ندارد

» بین متدهای یک کلاس یک تا سه فاصله به همراه توضیحات آن متد قرار می گیرد

» نام متدها فعل است و گویای وظیفه آن خواهد بود مثل void doWork یا void parse

» نام متدها با حروف کوچک شروع و کلمات بعدی با حروف بزرگ شروع می شود مثل void someMethod

» قوائد حروف اختصاری در اینجا هم رعایت می شود مثل HtmlParser و نه HTMLParser

» متغیر های محلی یک متد دقیقاً زمانی تعریف می شوند که باید تعریف شوند و در جایی که لازم نیست تعریف نشده باشند، نباید تعریف شوند مثال:


  1. private void someMethod(){
  2.     int var1;
  3.     someCompute(var1);
  4.  
  5.     int n = 10;
  6.     int sum = 0;
  7.     for (int i=0; i
  8.         // statements
  9.         sum += i;
  10.     }
  11.  
  12.     someCompute(sum);
  13. }

 

» کلاس ها درونی ( Nested or Inner ) در انتها تعریف می شوند

» تمامی قوائد نوشتار کلاسها برای interface ها هم صادق است
 

 

بخش توضیحات ( comments و javadoc ):

توضیحات به سه فرم نوشته می شود.

♦ در حالت اول توضیحاتی برای یک کلاس یا متد یا فیلد می نویسیم، این توضیحات با استفاده از ابزارهایی نظیر javadoc generator به فایلهای html تبدیل شده و مانند یک کتاب الکترونیکی به سایر برنامه نویس ها در فهمیدن و استفاده از کد کمک می کند، نظیر آن چیزی که در اکثر راهنماها در اینترنت قابل مشاهده است. مثال:

 


  1. /**
  2.  * Here is a block comment with some very special
  3.  * formatting about your class
  4.  * you can use html tags like some bold text
  5.  * one
  6.  * two
  7.  * three
  8.  */
  9. public static MyClass {
  10.  
  11. }

 

♦ حالت دوم برای زمانی است که می خواهیم برای یک قسمت از کد توضیحات تکمیل تری بنویسیم، این توضیحات در javadoc درج نمی شوند و برای خواننده کد قابل دیدن هستند. مثال:


  1. /*
  2.  * Here is a block comment for some parts of code
  3.  */

 

♦ حالت سوم برای توضیح یک خط از کد است که نیاز به چند سطره شدن ندارد. معمولاً از این روش بیشتر برای غیر فعال کردن خطوط کد استفاده می شود. مثال:


  1. if (foo > 1) {
  2.     // Do a double-flip.
  3.     ...
  4. } else {
  5.     return false; // Explain why here.
  6. }
  7.  
  8. //if (bar > 1) {
  9. //    // Do a triple-flip.
  10. //    ...
  11. //} else {
  12. //    return false;
  13. //}

 

 

یک نمونه کد صحیح از نظر نوشتار:


  1. /*
  2.  * %W% %E% Behnam Aghajani
  3.  * Copyright (c) 2011-2012 Your Corporation Name, Inc. All Rights Reserved.
  4.  * This software is the confidential and proprietary information of
  5.  * Your Corp, Inc. ("Confidential Information"). You shall not
  6.  * disclose such Confidential Information and shall use it only in
  7.  * accordance with the terms of the license agreement you entered into
  8.  * with Your Corp.
  9.  * Your Corp MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  10.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  11.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  12.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  13.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  14.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  15.  */
  16. package com.uncocoder.course.lessons;
  17.  
  18. import android.util.Log;
  19.  
  20. /**
  21.  * Class description goes here.
  22.  *
  23.  * @version 1.00 24 May 2012
  24.  * @author Behnam Aghajani
  25.  */
  26. public class SomeClass extends Object {
  27.  
  28.     /* A class implementation comment can go here. */
  29.  
  30.     /** this constant used for logging */
  31.     public static final String LOG_TAG = "LOG";
  32.  
  33.     /** pClassVar1 documentation comment */
  34.     public static int          pClassVar1;
  35.  
  36.     /**
  37.      * _classVar2 documentation comment that happens to be
  38.      * more than one line long
  39.      */
  40.     private static Object      _classVar2;
  41.  
  42.     /** pInstanceVar1 documentation comment */
  43.     public Object              pInstanceVar1;
  44.  
  45.     /** _instanceVar2 documentation comment */
  46.     protected int              _instanceVar2;
  47.  
  48.     /** _instanceVar3 documentation comment */
  49.     private Object[]           _instanceVar3;
  50.  
  51.  
  52.  
  53.     /**
  54.      * ...constructor documentation comment...
  55.      */
  56.     public SomeClass() {
  57.         int someLocalVariable = 3;
  58.         String someLocalObject = "Test String";
  59.         Log.i(LOG_TAG, "LogOut: " + someLocalObject + someLocalVariable);
  60.         // ...implementation goes here...
  61.     }
  62.  
  63.  
  64.  
  65.     /**
  66.      * ...method doSomething documentation comment...
  67.      */
  68.     public void doSomething() {
  69.         // ...implementation goes here...
  70.     }
  71.  
  72.  
  73.  
  74.     /**
  75.      * ...method doSomethingElse documentation comment...
  76.      *
  77.      * @param someParam description
  78.      */
  79.     public void doSomethingElse(Object someParam) {
  80.         // ...implementation goes here...
  81.     }
  82. }

 

 

نام گذاری منابع پروژه اندروید:

از آنجایی که قائده خاصی برای خود منابع اندروید وجود ندارد چند قائده مناسب را تعریف می کنم که به تمیز نگه داشتن کد شما کمک می کند:

» در نام فایل های layout از کلمات form و dialog و adapter استفاده کنید و همه حروف را کوچک نوشته و کلمات را به _ جدا کنید مثال:

form_main.xml

form_list.xml

form_about.xml

dialog_confirm.xml

adapter_book.xml

» برای نام گذاری فایلهای تصویری هم از حروف کوچک استفاده شده و کلمات مانند بالا با _ جدا می شوند.

» برای نام گذاری Drawable ها و animation ها ( که هنوز آموزش داده نشده اند ) نیز از قائده حروف کوچک و _ استفاده می کنیم.

» توجه داشته باشید که سیستم عامل اندروید مبتنی بر linux بوده و در آن حروف بزرگ و کوچک با هم تفاوت دارند.

 

پاورقی:

♦ همانطور که تا کنون متوجه شده اید، تنظیمات eclipse که در قسمت اول آموزشها دانلود و استفاده کردید، از نظر code convention استاندارد بوده و بدون نگرانی می توانید به کار خود ادامه دهید. تنها نکته ای که رعایت آن توسط شما باید انجام گیرد، نامگذاری و مرتب نمودن فیلدها و متدهای یک کلاس است و چیزهایی نظیر فاصله خطوط، نوع comment، تعداد space ها و ... همگی صحیح هستند.

♦ در آموزشهای گذشته بسیار از code convention ها نام گذاری و مرتب سازی رعایت نگردید. تنها علت این بود که طریقه خاص نوشتار و نام گذاری شما را گمراه نکند. ولی از این پس کدها با رعایت اصول کامل نوشته خواهند شد.

♦ نوشتن comment ها باید به زبان انگلیسی صورت گیرد اما برای خوانندگانی که میانه خوبی با آن ندارند، comment ها مانند مطالب گذشته به زبان فارسی نوشته خواهد شد.

♦ در بعضی شرایط به دلایل مشخص و قوی، قوائد نوشتاری را زیر پا می گذاریم. هدف از رعایت آنها نوشتن کدی مرتب تر است، حال اگر این کار با ضد این قوانین ممکن شود پس از آن استفاده می کنیم. یکی از این مثال ها استفاده از نام tag ها در فایل xml مربوط به layout اندروید است که در java هم دقیقاً با همان نام متغیر آنرا نام گذاری می کنید مثل txt_caption بجای mCaption یا pCaption. در اینگونه موارد بیان می شود که code convention رعایت نگردیده است و شما هم به همین طریق آنرا رعایت نکنید. این نوع نقض نوشتار بندرت اتفاق می افتد و نباید به یک روش مرسوم تبدیل گردد.

 

ویرایش - بخش کوچکی از سورس کد اندروید ( جهت بازبینی ) :


  1. /*
  2.  * Copyright (C) 2006 The Android Open Source Project
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16.  
  17. package android.view;
  18.  
  19. import android.content.Context;
  20. import android.content.ContextWrapper;
  21. import android.content.res.Resources;
  22.  
  23. /**
  24.  * A ContextWrapper that allows you to modify the theme from what is in the
  25.  * wrapped context.
  26.  */
  27. public class ContextThemeWrapper extends ContextWrapper {
  28.     private Context mBase;
  29.     private int mThemeResource;
  30.     private Resources.Theme mTheme;
  31.     private LayoutInflater mInflater;
  32.  
  33.     public ContextThemeWrapper() {
  34.         super(null);
  35.     }
  36.     
  37.     public ContextThemeWrapper(Context base, int themeres) {
  38.         super(base);
  39.         mBase = base;
  40.         mThemeResource = themeres;
  41.     }
  42.  
  43.     @Override protected void attachBaseContext(Context newBase) {
  44.         super.attachBaseContext(newBase);
  45.         mBase = newBase;
  46.     }
  47.     
  48.     @Override public void setTheme(int resid) {
  49.         mThemeResource = resid;
  50.         initializeTheme();
  51.     }
  52.     
  53.     @Override public Resources.Theme getTheme() {
  54.         if (mTheme != null) {
  55.             return mTheme;
  56.         }
  57.  
  58.         if (mThemeResource == 0) {
  59.             mThemeResource = com.android.internal.R.style.Theme;
  60.         }
  61.         initializeTheme();
  62.  
  63.         return mTheme;
  64.     }
  65.  
  66.     @Override public Object getSystemService(String name) {
  67.         if (LAYOUT_INFLATER_SERVICE.equals(name)) {
  68.             if (mInflater == null) {
  69.                 mInflater = LayoutInflater.from(mBase).cloneInContext(this);
  70.             }
  71.             return mInflater;
  72.         }
  73.         return mBase.getSystemService(name);
  74.     }
  75.     
  76.     /**
  77.      * Called by {@link #setTheme} and {@link #getTheme} to apply a theme
  78.      * resource to the current Theme object.  Can override to change the
  79.      * default (simple) behavior.  This method will not be called in multiple
  80.      * threads simultaneously.
  81.      *
  82.      * @param theme The Theme object being modified.
  83.      * @param resid The theme style resource being applied to theme.
  84.      * @param first Set to true if this is the first time a style is being
  85.      *              applied to theme.
  86.      */
  87.     protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
  88.         theme.applyStyle(resid, true);
  89.     }
  90.  
  91.     private void initializeTheme() {
  92.         final boolean first = mTheme == null;
  93.         if (first) {
  94.             mTheme = getResources().newTheme();
  95.             Resources.Theme theme = mBase.getTheme();
  96.             if (theme != null) {
  97.                 mTheme.setTo(theme);
  98.             }
  99.         }
  100.         onApplyThemeResource(mTheme, mThemeResource, first);
  101.     }
  102. }

 

 

توصیه ها:

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

 

مطالب مرتبط

آخرین شرکتهای طرف قرارداد

دارولند

طراحی فروشگاه اینترنتی

آف مکس

طراحی سایت تخفیف گروهی

نمایندگان بیمه ما

طراحی وب سایت و پورتال نمایندگان

پژند الکترونیک

طراحی وب سایت و پرتال

نمایندگی بوش

طراحی وب سایت شرکتی

ایران بزرگ

طراحی وب سایت، اتوماسیون اداری و خدمات شبکه پایگاه خبری ایران بزرگ

ستون فقرات تهران

طراحی پورتال تخصصی پزشکی ستون فقرات تهران

آخرین توییت ها

آخرین مقالات آموزشی

استفاده از تکنولوژی روز دنیا در شرکت فناوران راتا رایان