Facebook Pixel
Searching...
فارسی
EnglishEnglish
EspañolSpanish
简体中文Chinese
FrançaisFrench
DeutschGerman
日本語Japanese
PortuguêsPortuguese
ItalianoItalian
한국어Korean
РусскийRussian
NederlandsDutch
العربيةArabic
PolskiPolish
हिन्दीHindi
Tiếng ViệtVietnamese
SvenskaSwedish
ΕλληνικάGreek
TürkçeTurkish
ไทยThai
ČeštinaCzech
RomânăRomanian
MagyarHungarian
УкраїнськаUkrainian
Bahasa IndonesiaIndonesian
DanskDanish
SuomiFinnish
БългарскиBulgarian
עבריתHebrew
NorskNorwegian
HrvatskiCroatian
CatalàCatalan
SlovenčinaSlovak
LietuviųLithuanian
SlovenščinaSlovenian
СрпскиSerbian
EestiEstonian
LatviešuLatvian
فارسیPersian
മലയാളംMalayalam
தமிழ்Tamil
اردوUrdu
Effective Java

Effective Java

Programming Language Guide
توسط Joshua Bloch 2001 252 صفحات
4.51
7k+ امتیازها
گوش دادن
گوش دادن

نکات کلیدی

1. کارخانه‌های استاتیک به جای سازنده‌ها: نام‌گذاری، کنترل و انعطاف‌پذیری

ارائه یک روش کارخانه استاتیک به جای یک سازنده عمومی دارای مزایا و معایبی است.

مزایای نام‌گذاری. روش‌های کارخانه استاتیک نام‌های توصیفی ارائه می‌دهند، بر خلاف سازنده‌ها، که به خوانایی و قابلیت استفاده از کد کمک می‌کند. این موضوع به‌ویژه زمانی مفید است که پارامترهای سازنده به‌وضوح شیء ایجاد شده را نشان ندهند. به‌عنوان مثال، یک روش به نام BigInteger.probablePrime() توصیفی‌تر از یک سازنده BigInteger(int, int, Random) است.

کنترل نمونه. کارخانه‌های استاتیک ملزم به ایجاد اشیاء جدید در هر بار فراخوانی نیستند، که به کلاس‌های غیرقابل تغییر اجازه می‌دهد تا نمونه‌ها را کش کرده و از ایجاد غیرضروری اشیاء جلوگیری کنند. این می‌تواند به‌طور قابل‌توجهی عملکرد را بهبود بخشد، به‌ویژه برای اشیاءی که به‌طور مکرر درخواست می‌شوند. روش Boolean.valueOf(boolean) نمونه‌ای از این موضوع است، زیرا همیشه همان نمونه‌های Boolean.TRUE یا Boolean.FALSE را برمی‌گرداند.

انعطاف‌پذیری زیرنوع. کارخانه‌های استاتیک می‌توانند اشیاءی از هر زیرنوع نوع بازگشتی خود را برگردانند، که به APIها اجازه می‌دهد اشیاء را بدون عمومی کردن کلاس‌هایشان برگردانند. این موضوع API را فشرده‌تر کرده و اجازه می‌دهد کلاس بازگشتی بر اساس پارامترهای ورودی یا حتی در نسخه‌های مختلف تغییر کند، که به نگهداری و انعطاف‌پذیری کمک می‌کند. این اساس چارچوب‌های ارائه‌دهنده خدمات مانند Java Cryptography Extension (JCE) است.

2. پیاده‌سازی Singleton: سازنده‌های خصوصی و دسترسی عمومی

یک singleton به سادگی کلاسی است که دقیقاً یک بار نمونه‌سازی می‌شود [Gamma98، ص. 127].

تضمین یکتایی. Singletonها که نمایانگر اجزای منحصر به فرد سیستم هستند، با خصوصی کردن سازنده و ارائه یک عضو استاتیک عمومی برای دسترسی، تحمیل می‌شوند. این موضوع تضمین می‌کند که تنها یک نمونه وجود دارد. دو رویکرد رایج وجود دارد: استفاده از یک فیلد نهایی یا یک روش کارخانه استاتیک.

رویکرد فیلد نهایی. عضو استاتیک عمومی یک فیلد نهایی است که با نمونه singleton مقداردهی اولیه می‌شود. این رویکرد ساده است و مشخص می‌کند که کلاس یک singleton است. به‌عنوان مثال:

  • public static final Elvis INSTANCE = new Elvis();

رویکرد کارخانه استاتیک. یک روش کارخانه استاتیک عمومی نمونه singleton را برمی‌گرداند. این موضوع انعطاف‌پذیری را برای تغییر پیاده‌سازی بدون تغییر API فراهم می‌کند. به‌عنوان مثال:

  • public static Elvis getInstance() { return INSTANCE; }

ملاحظات سریال‌سازی. برای حفظ ویژگی singleton در حین سریال‌سازی، باید یک روش readResolve ارائه شود تا نمونه موجود را برگرداند و از ایجاد نمونه‌های جدید در هنگام دسرالیزه کردن جلوگیری کند. این موضوع تضمین می‌کند که singleton حتی پس از سریال‌سازی و دسرالیزه کردن نیز منحصر به فرد باقی بماند.

3. کلاس‌های کاربردی: تحمیل عدم قابلیت نمونه‌سازی

چنین کلاس‌های کاربردی برای نمونه‌سازی طراحی نشده‌اند: یک نمونه بی‌معنا خواهد بود.

هدف کلاس‌های کاربردی. کلاس‌های کاربردی که متدها و فیلدهای استاتیک را گروه‌بندی می‌کنند، برای سازماندهی عملکردهای مرتبط بر روی مقادیر اولیه، آرایه‌ها یا اشیاءی که رابط‌های خاصی را پیاده‌سازی می‌کنند، خدمت می‌کنند. آن‌ها برای نمونه‌سازی طراحی نشده‌اند، زیرا نمونه‌ها بی‌معنا خواهند بود. نمونه‌هایی از این کلاس‌ها شامل java.lang.Math و java.util.Arrays هستند.

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

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

4. استفاده مجدد از اشیاء: کارایی و عدم تغییرپذیری

اغلب مناسب است که به جای ایجاد یک شیء جدید معادل عملکردی، از یک شیء واحد استفاده مجدد شود.

مزایای استفاده مجدد. استفاده مجدد از اشیاء، به‌ویژه اشیاء غیرقابل تغییر، کارآمدتر و شیک‌تر از ایجاد مکرر آن‌ها است. زیرا ایجاد اشیاء و جمع‌آوری زباله می‌تواند پرهزینه باشد، به‌ویژه برای اشیاء سنگین. به‌عنوان مثال، استفاده از String s = "silly"; بهتر از String s = new String("silly"); است.

اشیاء غیرقابل تغییر. اشیاء غیرقابل تغییر همیشه می‌توانند به‌طور ایمن استفاده مجدد شوند. به‌عنوان مثال، Boolean.valueOf(String) به Boolean(String) ترجیح داده می‌شود زیرا اولی ممکن است از نمونه‌های موجود استفاده مجدد کند.

اشیاء قابل تغییر. اشیاء قابل تغییر می‌توانند در صورتی که مشخص باشد تغییر نخواهند کرد، استفاده مجدد شوند. به‌عنوان مثال، استفاده از مقداردهی استاتیک برای ایجاد نمونه‌های Calendar و Date یک بار، به جای ایجاد آن‌ها هر بار که یک روش فراخوانی می‌شود، می‌تواند به‌طور قابل‌توجهی عملکرد را بهبود بخشد.

5. مدیریت حافظه: حذف ارجاعات منسوخ

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

نشت حافظه. نشت حافظه در زبان‌های جمع‌آوری زباله زمانی رخ می‌دهد که ارجاعات به اشیاء به‌طور غیرعمدی نگه‌داری شوند و از جمع‌آوری زباله جلوگیری کنند. این موضوع می‌تواند منجر به کاهش عملکرد، افزایش حجم حافظه و حتی OutOfMemoryError شود.

شناسایی نشت حافظه. یک منبع رایج نشت حافظه، کلاس‌هایی هستند که حافظه خود را مدیریت می‌کنند، مانند یک کلاس Stack. زمانی که یک عنصر آزاد می‌شود، هر ارجاع شیء موجود در عنصر باید به null تغییر یابد.

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

6. قرارداد Equals: بازتابی، تقارن و انتقال

متد equals یک رابطه معادل را پیاده‌سازی می‌کند.

رابطه معادل. هنگام بازنویسی متد equals، رعایت قرارداد عمومی آن که یک رابطه معادل را تعریف می‌کند، بسیار مهم است. این قرارداد شامل بازتابی (x.equals(x) باید true برگرداند)، تقارن (x.equals(y) باید true باشد اگر و تنها اگر y.equals(x) true باشد) و انتقال (اگر x.equals(y) و y.equals(z) true باشند، آنگاه x.equals(z) باید true باشد) است.

نقض تقارن. نقض تقارن می‌تواند منجر به رفتار غیرقابل پیش‌بینی شود زمانی که اشیاء در مجموعه‌ها استفاده می‌شوند. به‌عنوان مثال، یک کلاس CaseInsensitiveString که سعی در تعامل با رشته‌های عادی دارد، می‌تواند تقارن را نقض کند.

نقض انتقال. نقض انتقال می‌تواند زمانی رخ دهد که یک کلاس قابل نمونه‌سازی را گسترش داده و جنبه‌ای را اضافه کنید که بر مقایسه‌های equals تأثیر بگذارد. برای جلوگیری از این موضوع، ترکیب را به ارث‌بری ترجیح دهید.

عدم وجود null. متد equals باید برای هر مقدار مرجع غیر null x زمانی که x.equals(null) فراخوانی می‌شود، false برگرداند. عملگر instanceof این موضوع را به‌طور خودکار مدیریت می‌کند.

7. بازنویسی HashCode: سازگاری با Equals

شما باید hashCode را در هر کلاسی که equals را بازنویسی می‌کند، بازنویسی کنید.

اهمیت HashCode. بازنویسی hashCode زمانی که equals را بازنویسی می‌کنید، ضروری است تا اطمینان حاصل شود که اشیاء برابر دارای کدهای هش برابر هستند. عدم انجام این کار قرارداد عمومی Object.hashCode را نقض کرده و از عملکرد صحیح کلاس در مجموعه‌های مبتنی بر هش مانند HashMap و HashSet جلوگیری می‌کند.

تابع هش قانونی اما ضعیف. یک متد hashCode بی‌معنا که همیشه همان مقدار را برمی‌گرداند قانونی است اما منجر به عملکرد ضعیف برای جداول هش می‌شود، زیرا تمام اشیاء به همان سطل هش می‌شوند.

دستورالعملی برای یک تابع هش خوب. یک تابع هش خوب تمایل دارد کدهای هش نابرابر برای اشیاء نابرابر تولید کند. یک دستورالعمل ساده شامل:

  • مقداردهی اولیه یک متغیر int به نام result با یک مقدار ثابت غیر صفر (به‌عنوان مثال، 17).
  • برای هر فیلد مهم f در شیء، یک کد هش c محاسبه کرده و آن را با استفاده از result = 37 * result + c; به result ترکیب کنید.
  • result را برگردانید.

8. بازنویسی ToString: نمایش مختصر و اطلاعاتی

متد toString به‌طور خودکار زمانی که شیء شما به println، عملگر الحاق رشته (+) یا، از نسخه 1.4 به بعد، assert منتقل می‌شود، فراخوانی می‌شود.

اهمیت ToString. بازنویسی متد toString یک نمایش مختصر و اطلاعاتی از یک شیء فراهم می‌کند که استفاده از کلاس را دلپذیرتر می‌سازد. این موضوع به‌ویژه برای اشکال‌زدایی و ثبت وقایع مفید است.

محتوای ToString. زمانی که عملی باشد، متد toString باید تمام اطلاعات جالب موجود در شیء را برگرداند. اگر شیء بزرگ باشد یا حاوی حالتی باشد که برای نمایش رشته‌ای مناسب نیست، باید یک خلاصه برگردانده شود.

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

9. رابط Cloneable: با احتیاط پیاده‌سازی کنید

رابط Cloneable به‌عنوان یک رابط میکسین (ماده 16) برای اشیاء طراحی شده بود تا نشان دهد که آن‌ها اجازه کپی‌برداری را می‌دهند.

نقص‌های Cloneable. رابط Cloneable فاقد یک متد clone است و متد clone کلاس Object محافظت‌شده است. این موضوع فراخوانی متد clone بر روی یک شیء صرفاً به این دلیل که Cloneable را پیاده‌سازی می‌کند، دشوار می‌سازد.

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

پیاده‌سازی Cloneable. برای پیاده‌سازی صحیح Cloneable، یک کلاس باید متد clone را با یک متد عمومی که ابتدا super.clone را فراخوانی کرده و سپس هر فیلدی که نیاز به اصلاح دارد را اصلاح می‌کند، بازنویسی کند. این معمولاً به معنای کپی کردن هر شیء قابل تغییر است که ساختار داخلی "عمیق" شیء را تشکیل می‌دهد.

جایگزین‌های Cloneable. یک رویکرد خوب برای کپی‌برداری از اشیاء، ارائه یک سازنده کپی یا کارخانه استاتیک است. این رویکردها به مکانیزم ایجاد شیء پرخطر وابسته نیستند و با استفاده صحیح از فیلدهای نهایی تداخل ندارند.

10. رابط Comparable: ترتیب طبیعی

با پیاده‌سازی Comparable، یک کلاس نشان می‌دهد که نمونه‌های آن دارای یک ترتیب طبیعی هستند.

مزایای Comparable. پیاده‌سازی رابط Comparable به یک کلاس اجازه می‌دهد تا با الگوریتم‌های عمومی و پیاده‌سازی‌های مجموعه که به ترتیب وابسته هستند، مانند Arrays.sort و TreeSet، تعامل داشته باشد.

قرارداد CompareTo. قرارداد عمومی برای متد compareTo مشابه قرارداد متد equals است و نیاز به بازتابی، انتقال و تقارن دارد. به شدت توصیه می‌شود که (x.compareTo(y)==0) == (x.equals(y)) باشد.

نوشتن یک متد CompareTo. هنگام نوشتن یک متد compareTo، فیلدهای مرجع شیء را با فراخوانی متد compareTo به‌طور بازگشتی مقایسه کنید. فیلدهای اولیه را با استفاده از عملگرهای رابطه‌ای < و > مقایسه کنید. اگر یک کلاس چندین فیلد مهم داشته باشد، آن‌ها را به ترتیب اهمیت مقایسه کنید.

11. حداقل کردن دسترسی: پنهان‌سازی اطلاعات

مهم‌ترین عاملی که یک ماژول به‌خوبی طراحی‌شده را از یک ماژول به‌بدی طراحی‌شده متمایز می‌کند، درجه‌ای است که ماژول داده‌های داخلی و سایر جزئیات پیاده‌سازی خود را از سایر ماژول‌ها پنهان می‌کند.

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

سطوح دسترسی. زبان برنامه‌نویسی جاوا اصلاح‌کننده‌های دسترسی (private، package-private، protected و public) را برای کمک به پنهان‌سازی اطلاعات فراهم می‌کند. قاعده کلی این است که هر کلاس یا عضوی را تا حد ممکن غیرقابل دسترسی کنید.

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

12. ترجیح عدم تغییرپذیری: سادگی و ایمنی در برابر رشته‌ها

یک کلاس غیرقابل تغییر به سادگی کلاسی است که نمونه‌های آن نمی‌توانند تغییر کنند.

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

قوانین برای عدم تغییرپذیری. برای غیرقابل تغییر کردن یک کلاس:

  • هیچ متدی که شیء را تغییر دهد (متدهای تغییر دهنده) ارائه ندهید.
  • اطمینان حاصل کنید که هیچ متدی قابل بازنویسی نیست (کلاس را نهایی کنید یا از سازنده‌های خصوصی و کارخانه‌های استاتیک استفاده کنید).
  • تمام فیلدها را نهایی کنید.
  • تمام فیلدها را خصوصی کنید.
  • اطمینان حاصل کنید که دسترسی انحصاری به هر مؤلفه قابل تغییر وجود دارد (کپی‌های دفاعی ایجاد کنید).

معایب عدم تغییرپذیری. تنها عیب واقعی کلاس‌های غیرقابل تغییر این است که آن‌ها به یک شیء جداگانه برای هر مقدار متمایز نیاز دارند. برای مقابله با این موضوع، مقادیر پرکاربرد را به‌عنوان ثابت‌های عمومی استاتیک نهایی ارائه دهید و در نظر بگیرید که یک کلاس همراه قابل تغییر عمومی ارائه دهید.

آخرین به‌روزرسانی::

نقد و بررسی

4.51 از 5
میانگین از 7k+ امتیازات از Goodreads و Amazon.

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

درباره نویسنده

جاشوا بلاخ یک دانشمند کامپیوتر مشهور و نویسنده‌ای است که در زمینه‌ی برنامه‌نویسی جاوا تخصص دارد. او سهم قابل توجهی در زبان جاوا و کتابخانه‌های آن داشته و طراحی و پیاده‌سازی فریم‌ورک مجموعه‌های جاوا از جمله دستاوردهای اوست. تخصص بلاخ ناشی از تجربه‌ی گسترده‌اش در توسعه‌ی نرم‌افزار و نقش او در شکل‌دهی به ویژگی‌های مدرن جاوا است. سبک نوشتاری او به خاطر وضوح، دقت و جامعیتش مورد تحسین قرار گرفته و مفاهیم پیچیده را برای خوانندگان قابل فهم می‌سازد. کار بلاخ، به‌ویژه کتاب «جاوای مؤثر»، به مرجع اصلی برای توسعه‌دهندگان جاوا در سرتاسر جهان تبدیل شده و بینش‌های ارزشمندی در مورد بهترین شیوه‌ها و تکنیک‌های مؤثر برنامه‌نویسی ارائه می‌دهد.

0:00
-0:00
1x
Dan
Andrew
Michelle
Lauren
Select Speed
1.0×
+
200 words per minute
Create a free account to unlock:
Requests: Request new book summaries
Bookmarks: Save your favorite books
History: Revisit books later
Ratings: Rate books & see your ratings
Try Full Access for 7 Days
Listen, bookmark, and more
Compare Features Free Pro
📖 Read Summaries
All summaries are free to read in 40 languages
🎧 Listen to Summaries
Listen to unlimited summaries in 40 languages
❤️ Unlimited Bookmarks
Free users are limited to 10
📜 Unlimited History
Free users are limited to 10
Risk-Free Timeline
Today: Get Instant Access
Listen to full summaries of 73,530 books. That's 12,000+ hours of audio!
Day 4: Trial Reminder
We'll send you a notification that your trial is ending soon.
Day 7: Your subscription begins
You'll be charged on Mar 1,
cancel anytime before.
Consume 2.8x More Books
2.8x more books Listening Reading
Our users love us
50,000+ readers
"...I can 10x the number of books I can read..."
"...exceptionally accurate, engaging, and beautifully presented..."
"...better than any amazon review when I'm making a book-buying decision..."
Save 62%
Yearly
$119.88 $44.99/year
$3.75/mo
Monthly
$9.99/mo
Try Free & Unlock
7 days free, then $44.99/year. Cancel anytime.
Settings
Appearance
Black Friday Sale 🎉
$20 off Lifetime Access
$79.99 $59.99
Upgrade Now →