IoT
اینترنت چیزی بیش ازشبکه ای از کامپیوتر ها نیست, در واقع یک (Internet of things) است. منظور از thnigs در اینجا هر شی با یک ادرس ip و قابلیت ارسال خودکار داده بر روی شبکه است , برای مثال یک خودرو با قابلیت پرداخت خودکار عوارض یک دستگاه نظارت قلب در بیمارستان, برنامه های موبایل که مسیر و موقعیت شما را ردگیری میکنند , دما سنج های هوشمند که اقدام به تنظیم درجه حرارت اتاق بر پایه وضعیت جوی و فعالیت در خانه میکنند.
@this_java
اینترنت چیزی بیش ازشبکه ای از کامپیوتر ها نیست, در واقع یک (Internet of things) است. منظور از thnigs در اینجا هر شی با یک ادرس ip و قابلیت ارسال خودکار داده بر روی شبکه است , برای مثال یک خودرو با قابلیت پرداخت خودکار عوارض یک دستگاه نظارت قلب در بیمارستان, برنامه های موبایل که مسیر و موقعیت شما را ردگیری میکنند , دما سنج های هوشمند که اقدام به تنظیم درجه حرارت اتاق بر پایه وضعیت جوی و فعالیت در خانه میکنند.
@this_java
اسامی کلاس و شناسه ها در جاوا:
بطور قراردادی اسامی همه کلاس ها در جاوا با یک حرف بزرگ اغاز شده و حرف اول هر کلمه در ان نام نیز با حرف بزرگ اغار میگردد
نام یک کلاس جاوا بعنوان شناسه شناخته میشود و شامل مجموعه ای از کاراکتر های حروف, اعداد, نماد دلار و خط زیرین (_) است
شناسه ها نمیتوانند با یک رقم اغاز شده و حاوی فاصله باشند. برای مثال شناسه های زیر همگی معتبر هستند:
@this_java
بطور قراردادی اسامی همه کلاس ها در جاوا با یک حرف بزرگ اغاز شده و حرف اول هر کلمه در ان نام نیز با حرف بزرگ اغار میگردد
نام یک کلاس جاوا بعنوان شناسه شناخته میشود و شامل مجموعه ای از کاراکتر های حروف, اعداد, نماد دلار و خط زیرین (_) است
شناسه ها نمیتوانند با یک رقم اغاز شده و حاوی فاصله باشند. برای مثال شناسه های زیر همگی معتبر هستند:
Welcome1, m_inputField1,button7,_valueاما اسامی زیر شناسه معتبر نمیباشند چرا که حاوی رقم و فاصله هستند:
7button, input fieldمعمولا , شناسه ای که با یک حرف بزرگ شروع نمیشود نشاندهنده ی نام یک کلاس نمیباشد , جاوا به بزرگ یا کوچک بودن حروف حساس میباشد (case-senstive) به این معنی که حروف کوچک و بزرگ یکسان ارزیابی نمیشوند و به همین علت دو شناسه a1 و A1 بعنوان یک شناسه یکسان تفسیر نمیشوند (با اینکه هر دو معتبر هستند)
@this_java
white space چیست؟
برنامه نویسان برای اینکه کد خود را خوانا تر کنند از خطوط خالی , کاراکتر های فاصله (space) و تب (tab) استفاده میکنند .
به مجموعه این کاراکتر ها white space میگویند.
معمولا این کاراکتر ها توسط کامپایلر نادیده گرفته میشوند.
@this_java
برنامه نویسان برای اینکه کد خود را خوانا تر کنند از خطوط خالی , کاراکتر های فاصله (space) و تب (tab) استفاده میکنند .
به مجموعه این کاراکتر ها white space میگویند.
معمولا این کاراکتر ها توسط کامپایلر نادیده گرفته میشوند.
@this_java
خواندن و نوشتن متغیر های یک کلاس بدون setter and getter :
همونطوری که میدونید فیلد هایی با سطح دسترسی private رو بدون setter و getter نمیشه خوند یا نوشت..
اما با استفاده از reflection میشه اینکارو بدون ایجاد setterو getter انجام داد
ابتدا دو کلاس ایجاد کنید و نام انهارا به ترتیب A و B قرار دهید.. در کلاس A یک متغیر private قرار داده و کلاس B رو به شکل زیر بنویسید:
class A{
private int i = 220;
}
class B {
public static void main(String[] args) {
A name = new A();
Field f = A.class.getDeclaredField("i"); // variable name
f.setAccessible(true); // Abracadabra
System.out.println(f.get(name));
}
}
OUTPUT:
————————-> 220;
برای ست کردن هم به این روش عمل کنید:
class A{
private int i = 220;
}
class B {
public static void main(String[] args) {
A name = new A();
Field f2 = A.class.getDeclaredField("i");
f2.setAccessible(true);
f2.set(d, 20);
System.out.println(f2.get(name));
}
}
OUTPUT:
————————-> 20;
موفق باشید
@this_java
همونطوری که میدونید فیلد هایی با سطح دسترسی private رو بدون setter و getter نمیشه خوند یا نوشت..
اما با استفاده از reflection میشه اینکارو بدون ایجاد setterو getter انجام داد
ابتدا دو کلاس ایجاد کنید و نام انهارا به ترتیب A و B قرار دهید.. در کلاس A یک متغیر private قرار داده و کلاس B رو به شکل زیر بنویسید:
class A{
private int i = 220;
}
class B {
public static void main(String[] args) {
A name = new A();
Field f = A.class.getDeclaredField("i"); // variable name
f.setAccessible(true); // Abracadabra
System.out.println(f.get(name));
}
}
OUTPUT:
————————-> 220;
برای ست کردن هم به این روش عمل کنید:
class A{
private int i = 220;
}
class B {
public static void main(String[] args) {
A name = new A();
Field f2 = A.class.getDeclaredField("i");
f2.setAccessible(true);
f2.set(d, 20);
System.out.println(f2.get(name));
}
}
OUTPUT:
————————-> 20;
موفق باشید
@this_java
دوستان بالاخره Jdk 11 اومد
https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html
از لینک بالا میتونید اونو دانلود کنید
https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html
از لینک بالا میتونید اونو دانلود کنید
NetBeans 9 هم منتشر شد
https://netbeans.apache.org/download/nb90/nb90.html
از لینک بالا میتونید دانلودش کنید
https://netbeans.apache.org/download/nb90/nb90.html
از لینک بالا میتونید دانلودش کنید
نت بینز ده رو میتونید ازین لینک دانلود کنید :
https://netbeans.apache.org/download/nb100/nb100.html
https://netbeans.apache.org/download/nb100/nb100.html
Java_Dm.zip
48.7 KB
سورس کد اینترنت دانلود منیجر ساده به زبان جاوا
@this_java
@this_java
Design Pattern (الگوی طراحی) چیست؟
اگر با مفهوم Design Pattern (الگوی طراحی) آشنایی داشته باشید، به طور حتم میدانید که دیزاین پترنها به مجموعهای از راهکارها در صنعت توسعهٔ نرمافزار گفته میشوند که میتوانید از آنها در کدنویسی پروژهها، اعم از کوچک و بزرگ، استفاده نمایید و استفاده از این الگوها که توسط متخصصان باتجربه در زمینهٔ شییٔگرایی ابداع شدهاند کمک میکنند تا سورسکدی انعطافپذیرتر و تغییرپذیرتر داشته باشیم. چنانچه کماکان الگوهای طراحی را جزو چرخهٔ توسعه به حساب نمیآورید، در ادامه قصد داریم دلایلی را ذکر کنیم مبنی بر اینکه که چرا باید این سولوشنهای تستشده را در قالب یکسری به اصطلاح Best Practice در حین توسعهٔ نرمافزار به کار گیرید.
اولین کسی باشید که به این سؤال پاسخ میدهید
برنامه نویسی موازی با cuda در vs code
اگر با مفهوم Design Pattern (الگوی طراحی) آشنایی داشته باشید، به طور حتم میدانید که دیزاین پترنها به مجموعهای از راهکارها در صنعت توسعهٔ نرمافزار گفته میشوند که میتوانید از آنها در کدنویسی پروژهها، اعم از کوچک و بزرگ، استفاده نمایید و استفاده از این الگوها که توسط متخصصان باتجربه در زمینهٔ شییٔگرایی ابداع شدهاند کمک میکنند تا سورسکدی انعطافپذیرتر و تغییرپذیرتر داشته باشیم.
چنانچه کماکان الگوهای طراحی را جزو چرخهٔ توسعه به حساب نمیآورید، در ادامه قصد داریم دلایلی را ذکر کنیم مبنی بر اینکه که چرا باید این سولوشنهای تستشده را در قالب یکسری به اصطلاح Best Practice در حین توسعهٔ نرمافزار به کار گیرید.
عدم نیاز به اختراع مجدد چرخ
یک اصل ثابت در توسعهٔ نرمافزار وجود دارد و آن هم چیزی نیست جز اِعمال تغییرات در صورت نیاز. تغییرات هنگامی رخ میدهند که نیازمندیها عوض میشوند، سیستمها رشد میکنند، ویژگیهای جدید اضافه میشوند، کارایی باید بهبود یابد و موارد دیگری از این دست اما سؤال اینجا است که چگونه میتوان نرمافزاری تولید کرد به طوری که تأثیر این تغییرات در آن حداقلی باشد؟
نیاز به توضیح نیست که یکی از سختترین جنبههای توسعهٔ نرمافزاری چیزی نیست جز درک کدهای موجود، که احتمالاً توسط دولوپرهای دیگری نوشته شدهاند، و اصلاح این کدها به نحوی که نقصهای جدید یا نتایج ناخواسته بروز نکنند. با این توضیح، در پاسخ به سؤال فوق باید گفت که در واقع معجزهای در کار نیست ولی تکنیکهایی وجود دارند که میتوان از آنها در برنامهنویسی شییٔگرا استفاده کرد؛ تکنیکهایی که بر اثر تجربهٔ برنامهنویسان حرفهای در شرایط سخت ابداع شدهاند و برای استفادهٔ عموم به بازار عرضه شدهاند که این تکنیکها به Design Patterns معروف هستند و که نمایانگر سولوشنهایی هستند که برای حل مشکلات رایج در برنامهنویسی میتوان از آنها استفاده نمود.
آنچه در این خصوص لازم به یادآوری است اینکه الگوهای طراحی به عنوان بخشی از لایبرریها یا ماژولهای توسعهٔ نرمافزار نیستند بلکه راهبردهایی مرتبط با طراحی هستند که میتوانند در هستهٔ پروژههایتان گنجانده شده و باعث راحتی در ساخت سیستمهای شییٔگرا با قابلیت انعطاف و نگهداری بالا شده و از همین روی وقتی میتوان از تجربهٔ بهترین طراحان شییٔگرا استفاده کرد، چرا باید اقدام به اختراع مجدد چرخ نماییم؟
مهارتهای مربوط به شییٔگرایی خود را بهبود دهید
نیاز به توضیح نیست که سنگ بنای برنامهنویسی شییٔگرا چیزی نیست جز Abstraction ،Inheritance ،Polymorphism و Encapsulation که به ترتیب میتوان معادلهای «چندریختی»، «وراثت»، «انتزاع» و «کپسولهسازی» برای این اصطلاحات در نظر گرفت. با اینکه چنین چیزی کاملاً صحت دارد، اما طراحی سیستمهای شییٔگرا به همین جا ختم نمیشود زیرا همین قواعد پایهای میتوانند به سرعت باعث ایجاد مشکلاتی مثل تکرار کد، طراحی ضعیف و استفادهٔ بیش از حد از کلاسهای مختلف شود.
به طور کلی، در مجموعه الگوهای طراحی با گروهی از قواعد دیگر آشنا خواهید شد که بهتر از پایههای اولیهٔ شییٔگرایی به کار خواهند آمد و با شناخت این اصول و چگونگی ترکیب آنها در الگوهای طراحی، به طراح و معمار بهتری در زمینه شییٔگرایی بدل خواهید شد.
الگوها را در لایبرریها و زبانهای مختلف تشخیص دهید
دیزاین پترنها راهحلهای عمومی برای حل مشکلات رایج در برنامهنویسی شییٔگرا (OOP) هستند به این معنا که راهحلهایی هستند برای حل چالشهای طراحی نرمافزار و لازم به یادآوری است که شما نمیتوانید یک نمونه الگوی طراحی را برای افزودن به پروژهٔ خود دانلود و نصب نمایید بلکه باید الگوی طراحی را در داخل سیستمتان پیادهسازی کنید!
اگر با مفهوم Design Pattern (الگوی طراحی) آشنایی داشته باشید، به طور حتم میدانید که دیزاین پترنها به مجموعهای از راهکارها در صنعت توسعهٔ نرمافزار گفته میشوند که میتوانید از آنها در کدنویسی پروژهها، اعم از کوچک و بزرگ، استفاده نمایید و استفاده از این الگوها که توسط متخصصان باتجربه در زمینهٔ شییٔگرایی ابداع شدهاند کمک میکنند تا سورسکدی انعطافپذیرتر و تغییرپذیرتر داشته باشیم. چنانچه کماکان الگوهای طراحی را جزو چرخهٔ توسعه به حساب نمیآورید، در ادامه قصد داریم دلایلی را ذکر کنیم مبنی بر اینکه که چرا باید این سولوشنهای تستشده را در قالب یکسری به اصطلاح Best Practice در حین توسعهٔ نرمافزار به کار گیرید.
اولین کسی باشید که به این سؤال پاسخ میدهید
برنامه نویسی موازی با cuda در vs code
اگر با مفهوم Design Pattern (الگوی طراحی) آشنایی داشته باشید، به طور حتم میدانید که دیزاین پترنها به مجموعهای از راهکارها در صنعت توسعهٔ نرمافزار گفته میشوند که میتوانید از آنها در کدنویسی پروژهها، اعم از کوچک و بزرگ، استفاده نمایید و استفاده از این الگوها که توسط متخصصان باتجربه در زمینهٔ شییٔگرایی ابداع شدهاند کمک میکنند تا سورسکدی انعطافپذیرتر و تغییرپذیرتر داشته باشیم.
چنانچه کماکان الگوهای طراحی را جزو چرخهٔ توسعه به حساب نمیآورید، در ادامه قصد داریم دلایلی را ذکر کنیم مبنی بر اینکه که چرا باید این سولوشنهای تستشده را در قالب یکسری به اصطلاح Best Practice در حین توسعهٔ نرمافزار به کار گیرید.
عدم نیاز به اختراع مجدد چرخ
یک اصل ثابت در توسعهٔ نرمافزار وجود دارد و آن هم چیزی نیست جز اِعمال تغییرات در صورت نیاز. تغییرات هنگامی رخ میدهند که نیازمندیها عوض میشوند، سیستمها رشد میکنند، ویژگیهای جدید اضافه میشوند، کارایی باید بهبود یابد و موارد دیگری از این دست اما سؤال اینجا است که چگونه میتوان نرمافزاری تولید کرد به طوری که تأثیر این تغییرات در آن حداقلی باشد؟
نیاز به توضیح نیست که یکی از سختترین جنبههای توسعهٔ نرمافزاری چیزی نیست جز درک کدهای موجود، که احتمالاً توسط دولوپرهای دیگری نوشته شدهاند، و اصلاح این کدها به نحوی که نقصهای جدید یا نتایج ناخواسته بروز نکنند. با این توضیح، در پاسخ به سؤال فوق باید گفت که در واقع معجزهای در کار نیست ولی تکنیکهایی وجود دارند که میتوان از آنها در برنامهنویسی شییٔگرا استفاده کرد؛ تکنیکهایی که بر اثر تجربهٔ برنامهنویسان حرفهای در شرایط سخت ابداع شدهاند و برای استفادهٔ عموم به بازار عرضه شدهاند که این تکنیکها به Design Patterns معروف هستند و که نمایانگر سولوشنهایی هستند که برای حل مشکلات رایج در برنامهنویسی میتوان از آنها استفاده نمود.
آنچه در این خصوص لازم به یادآوری است اینکه الگوهای طراحی به عنوان بخشی از لایبرریها یا ماژولهای توسعهٔ نرمافزار نیستند بلکه راهبردهایی مرتبط با طراحی هستند که میتوانند در هستهٔ پروژههایتان گنجانده شده و باعث راحتی در ساخت سیستمهای شییٔگرا با قابلیت انعطاف و نگهداری بالا شده و از همین روی وقتی میتوان از تجربهٔ بهترین طراحان شییٔگرا استفاده کرد، چرا باید اقدام به اختراع مجدد چرخ نماییم؟
مهارتهای مربوط به شییٔگرایی خود را بهبود دهید
نیاز به توضیح نیست که سنگ بنای برنامهنویسی شییٔگرا چیزی نیست جز Abstraction ،Inheritance ،Polymorphism و Encapsulation که به ترتیب میتوان معادلهای «چندریختی»، «وراثت»، «انتزاع» و «کپسولهسازی» برای این اصطلاحات در نظر گرفت. با اینکه چنین چیزی کاملاً صحت دارد، اما طراحی سیستمهای شییٔگرا به همین جا ختم نمیشود زیرا همین قواعد پایهای میتوانند به سرعت باعث ایجاد مشکلاتی مثل تکرار کد، طراحی ضعیف و استفادهٔ بیش از حد از کلاسهای مختلف شود.
به طور کلی، در مجموعه الگوهای طراحی با گروهی از قواعد دیگر آشنا خواهید شد که بهتر از پایههای اولیهٔ شییٔگرایی به کار خواهند آمد و با شناخت این اصول و چگونگی ترکیب آنها در الگوهای طراحی، به طراح و معمار بهتری در زمینه شییٔگرایی بدل خواهید شد.
الگوها را در لایبرریها و زبانهای مختلف تشخیص دهید
دیزاین پترنها راهحلهای عمومی برای حل مشکلات رایج در برنامهنویسی شییٔگرا (OOP) هستند به این معنا که راهحلهایی هستند برای حل چالشهای طراحی نرمافزار و لازم به یادآوری است که شما نمیتوانید یک نمونه الگوی طراحی را برای افزودن به پروژهٔ خود دانلود و نصب نمایید بلکه باید الگوی طراحی را در داخل سیستمتان پیادهسازی کنید!
برنامهنویسان غالباً با الگوهایی در لایبرریها، پکیجها و ماژولهایی که استفاده میکنند مواجه میشوند که از آن جمله میتوان به پکیج I/O در جاوا اشاره کرد. زبان برنامهنویسی جاوا از الگوی Decorator استفاده میکند که اجازه میدهد تا یک آبجکت ورودی/خروجی از فایل اصلی گرفته و سپس آن را با امکانات جدیدی طبق نیاز خود ترکیب کنید که این روش بسیار خوبی برای طراحی یک سیستم ورودی/خروجی فایل است و اگر از قبل با الگوهای طراحی و به طور خاص الگوی دکوراتور آشنا باشید، به سادگی متوجه چگونگی طراحی این آبجکت و روش کار آن خواهید شد. در یک کلام، به کار بردن این دیزاین پترن باعث میشود سریعتر طراحی سیستم را درک کنید.
از زبانی مشترک با دیگر دولوپرها استفاده کنید
همانطور که در مورد بالا بیان شد، یکی از مزایای یادگیری دیزاین پترنها آشنایی با نوعی از معماری نرمافزار است که میان دولوپرهای حرفهای سراسر دنیا عمومیت دارد به طوری که اگر در تیم نرمافزاری خود قصد سرعت بخشیدن به کارتان را دارید، از طریق این الگوها نیروی جدیدی برای برقراری ارتباط دربارهٔ منظور خود در طرحهایتان با یکدیگر به دست خواهید آورد. به عنوان مثال، فرض کنید همگروهیتان میخواهد قسمت جدیدی از طراحیاش را برایتان شرح دهد. دو طرز بیان زیر برای این منظور امکانپذیر است:
من این کلاس برودکست رو ساختم که کارش پیدا کردن تمامی اشیائی هست که به آن گوش میدهند و هر وقت دیتای جدیدی برسه، اون پیام رو به تمامی گیرندهها میفرسته. جالب اینجاست که گیرندهها میتونن در هر زمانی به برودکست متصل شده یا خودشون رو حذف کنن و این روش کاملاً پویا و به اصطلاح Loosely Coupled هستش.
یا
من این کلاس برودکست را بر پایهٔ الگوی Observer ساختم.
در روش اول، باید مدت زیادی فکر کنید تا دقیقاً متوجه شوید که کلاس برودکست چه کاری انجام میدهد اما در روش دوم، طرز کار کلاس را از قبل میدانید و این قدرت بهکارگیری فهرست لغات مشترک برای الگوهای طراحی است. اگر به زبان الگوها ارتباط برقرار کنید، توسعهدهندگان دیگر فوراً و با جزئیات بیشتر متوجه طرحی که قصد بیان آن را دارید خواهند شد.
با اینکه در ترکیب و ساخت سیستمهای شییٔگرا به دست خودتان چیزهای زیادی برای یادگیری وجود دارد، اما میتوانید از مزایای شناخت و بینشی که از طریق مطالعه و استفاده از دیزاین پترنها به دست میآید، استفاده نمایید. همانطور که پیش از این گفتیم، الگوهای طراحی به یک باره ابداع نشدهاند بلکه در نتیجهٔ کار سخت و تجربهٔ عمیق از طریق ساخت تعداد زیادی سیستم مختلف به دست آمدهاند. در حین فرایند یادگیری الگوهای طراحی، شما به دیدگاه یک معمار باتجربه نرمافزاری دست یابید و در عین حال به سمت ساخت نرمافزارهای بهتر و ماندگارتر پیش خواهید رفت.
منبع :سکان اکادمی
@this_java
از زبانی مشترک با دیگر دولوپرها استفاده کنید
همانطور که در مورد بالا بیان شد، یکی از مزایای یادگیری دیزاین پترنها آشنایی با نوعی از معماری نرمافزار است که میان دولوپرهای حرفهای سراسر دنیا عمومیت دارد به طوری که اگر در تیم نرمافزاری خود قصد سرعت بخشیدن به کارتان را دارید، از طریق این الگوها نیروی جدیدی برای برقراری ارتباط دربارهٔ منظور خود در طرحهایتان با یکدیگر به دست خواهید آورد. به عنوان مثال، فرض کنید همگروهیتان میخواهد قسمت جدیدی از طراحیاش را برایتان شرح دهد. دو طرز بیان زیر برای این منظور امکانپذیر است:
من این کلاس برودکست رو ساختم که کارش پیدا کردن تمامی اشیائی هست که به آن گوش میدهند و هر وقت دیتای جدیدی برسه، اون پیام رو به تمامی گیرندهها میفرسته. جالب اینجاست که گیرندهها میتونن در هر زمانی به برودکست متصل شده یا خودشون رو حذف کنن و این روش کاملاً پویا و به اصطلاح Loosely Coupled هستش.
یا
من این کلاس برودکست را بر پایهٔ الگوی Observer ساختم.
در روش اول، باید مدت زیادی فکر کنید تا دقیقاً متوجه شوید که کلاس برودکست چه کاری انجام میدهد اما در روش دوم، طرز کار کلاس را از قبل میدانید و این قدرت بهکارگیری فهرست لغات مشترک برای الگوهای طراحی است. اگر به زبان الگوها ارتباط برقرار کنید، توسعهدهندگان دیگر فوراً و با جزئیات بیشتر متوجه طرحی که قصد بیان آن را دارید خواهند شد.
با اینکه در ترکیب و ساخت سیستمهای شییٔگرا به دست خودتان چیزهای زیادی برای یادگیری وجود دارد، اما میتوانید از مزایای شناخت و بینشی که از طریق مطالعه و استفاده از دیزاین پترنها به دست میآید، استفاده نمایید. همانطور که پیش از این گفتیم، الگوهای طراحی به یک باره ابداع نشدهاند بلکه در نتیجهٔ کار سخت و تجربهٔ عمیق از طریق ساخت تعداد زیادی سیستم مختلف به دست آمدهاند. در حین فرایند یادگیری الگوهای طراحی، شما به دیدگاه یک معمار باتجربه نرمافزاری دست یابید و در عین حال به سمت ساخت نرمافزارهای بهتر و ماندگارتر پیش خواهید رفت.
منبع :سکان اکادمی
@this_java
الگوی Factory
همونطور که تا حدودی از اسم این الگو پیداست، با ساختن یه به اصطلاح کارخونه، این امکان رو فراهم میکنیم که زمان تولید شئ، بجای اینکه خودمون تولیدش کنیم، به اون کارخونه بگیم چی میخوایم (ویژگی های شئ مورد نظر رو بهش میدیم) و اون کارخونه خودش شئ رو میسازه و میده بهمون.
مزیت های این الگو عبارتند از کاهش خطوط کد، سهولت توی تولید اشیاء، عدم نیاز به تغییر زیاد در صورت تغییر کلاس (کارخونه خودش تغییر لازمه رو اعمال میکنه) و ...
خب بریم مثالش رو ببینیم:
فرض کنیم یه اینترفیس وسیله ی نقلیه داریم:
public interface Vehicle { void showVehicleType();}
حالا دو تا کلاس دیگه داریم، یکی ماشین و یکی دیگه موتور که هردوتاشون نوعی وسیله ی نقلیه هستن:
public class Car implements Vehicle {
@Override
public void showVehicleType() {
System.out.println("Vehicle: Car");
}
}
public class MotorCycle implements Vehicle {
@Override
public void showVehicleType() {
System.out.println("Vehicle: MotorCycle"); }
}
برای پیاده سازی الگوی Factory، یه کلاس به اسم VehicleFactory میسازیم:
public class VehicleFactory {
public Vehicle createVehicle(String vehicleType){ if(vehicleType == null){
return null;
}
else if(vehicleType.equals("Car")){
return new Car();
}
else if(vehicleType.equals("MotorCycle")){
return new MotorCycle();
}
return null; }
}
و حالا فقط کافیه زمانی که میخوایم یه ماشین یا موتور بسازیم به شکل زیر عملی کنیم:
VehicleFactory vehicleFactory = new VehicleFactory();Vehicle car = vehicleFactory.createVehicle("Car");car.showVehicleType();
خروجی: Vehicle: Car
Vehicle motorCycle = vehicleFactory.createVehicle("MotorCycle"); motorCycle.showVehicleType();
:خروجی Vehicle: MotorCycle
به همین راحتی! ما توی این مثال از رشته برای تعیین نوع وسیله نقلیه استفاده کردیم. مشخصه که هر رشته ای بجز Car یا MotorCycle استفاده کنیم، null بر میگرده.
طبیعتاً میشه شیوه های دیگه ای هم برای نشان دادن نوع وسیله نقلیه استفاده کرد، برای مثل استفاده از رشته ی استاتیک:
public class VehicleFactory { public static final String TYPE_CAR = "Car"; public static final String TYPE_MOTORCYCLE = "MotorCycle"; public Vehicle createVehicle(String vehicleType){ if(vehicleType == null){ return null; } else if(vehicleType.equals(TYPE_CAR)){ return new Car(); } else if(vehicleType.equals(TYPE_MOTORCYCLE)){ return new MotorCycle(); } return null; } }
و برای تعریف شئ به شکل زیر عمل کنیم:
Vehicle motorCycle = vehicleFactory.createVehicle(VehicleFactory.TYPE_MOTORCYCLE);
یه روش دیگه استفاده از enum برای تعیین نوع کلاس درخواستی هست:
public class VehicleFactory {
public enum VehicleTypeEnum{
CAR, MOTOR_CYCLE
}
public Vehicle createVehicle(VehicleTypeEnum vehicleTypeEnum){
if(vehicleTypeEnum== null){ return null;
}
else if(vehicleTypeEnum.equals(VehicleTypeEnum.CAR)){
return new Car();
} else if(vehicleTypeEnum.equals(VehicleTypeEnum.MOTOR_CYCLE)){
return new MotorCycle(); } return null; }}
و زمان ساخت شئ به شکل زیر عمل کنیم:
Vehicle car = vehicleFactory.createVehicle(VehicleFactory.VehicleTypeEnum.CAR);
البته برای اینکه اصل open/close از اصول پنجگانه solid رو هم رعایت کرده باشیم میتونیم کلاس کارخونمون رو به شکل زیر پیاده سازی کنیم:
public class VehicleFactory {
public Vehicle createCar(){
return new Car();
}
public Vehicle createMotorCycle(){
return new MotorCycle();
}
}
و طبیعتاً برای ساخت شئ به شکل زیر عمل میکنیم:
Vehicle carObject = vehicleFactory.createCar();Vehicle motorCycleObject = vehicleFactory.createMotorCycle();
با کلیت این الگو آشنا شدیم. مثل هر الگوی دیگه ای با توجه به زمان، نوع و دلیل استفاده از این الگو میتونیم تغییرات لازمه ی خودمون را پیاده سازی کنیم. برای مثال تابع یا توابع سازنده ی اشیاء داخل کارخونه رو استاتیک تعریف کنیم که نیازی به تعریف شئ از کلاس کارخونه نداشته باشیم، یا در صورت نیاز از الگوی سینگلتون برای اشیاء ساخته شده استفاده کنیم، یا زمان ساخت اشیاء پارامترهایی هم پاس بدیم و با توجه به اون پارامترها تغییراتی روی شئ انجام بدیم، یا حتی بریم سراغ ارثبری ها چند سطحی و ...
@this_java
همونطور که تا حدودی از اسم این الگو پیداست، با ساختن یه به اصطلاح کارخونه، این امکان رو فراهم میکنیم که زمان تولید شئ، بجای اینکه خودمون تولیدش کنیم، به اون کارخونه بگیم چی میخوایم (ویژگی های شئ مورد نظر رو بهش میدیم) و اون کارخونه خودش شئ رو میسازه و میده بهمون.
مزیت های این الگو عبارتند از کاهش خطوط کد، سهولت توی تولید اشیاء، عدم نیاز به تغییر زیاد در صورت تغییر کلاس (کارخونه خودش تغییر لازمه رو اعمال میکنه) و ...
خب بریم مثالش رو ببینیم:
فرض کنیم یه اینترفیس وسیله ی نقلیه داریم:
public interface Vehicle { void showVehicleType();}
حالا دو تا کلاس دیگه داریم، یکی ماشین و یکی دیگه موتور که هردوتاشون نوعی وسیله ی نقلیه هستن:
public class Car implements Vehicle {
@Override
public void showVehicleType() {
System.out.println("Vehicle: Car");
}
}
public class MotorCycle implements Vehicle {
@Override
public void showVehicleType() {
System.out.println("Vehicle: MotorCycle"); }
}
برای پیاده سازی الگوی Factory، یه کلاس به اسم VehicleFactory میسازیم:
public class VehicleFactory {
public Vehicle createVehicle(String vehicleType){ if(vehicleType == null){
return null;
}
else if(vehicleType.equals("Car")){
return new Car();
}
else if(vehicleType.equals("MotorCycle")){
return new MotorCycle();
}
return null; }
}
و حالا فقط کافیه زمانی که میخوایم یه ماشین یا موتور بسازیم به شکل زیر عملی کنیم:
VehicleFactory vehicleFactory = new VehicleFactory();Vehicle car = vehicleFactory.createVehicle("Car");car.showVehicleType();
خروجی: Vehicle: Car
Vehicle motorCycle = vehicleFactory.createVehicle("MotorCycle"); motorCycle.showVehicleType();
:خروجی Vehicle: MotorCycle
به همین راحتی! ما توی این مثال از رشته برای تعیین نوع وسیله نقلیه استفاده کردیم. مشخصه که هر رشته ای بجز Car یا MotorCycle استفاده کنیم، null بر میگرده.
طبیعتاً میشه شیوه های دیگه ای هم برای نشان دادن نوع وسیله نقلیه استفاده کرد، برای مثل استفاده از رشته ی استاتیک:
public class VehicleFactory { public static final String TYPE_CAR = "Car"; public static final String TYPE_MOTORCYCLE = "MotorCycle"; public Vehicle createVehicle(String vehicleType){ if(vehicleType == null){ return null; } else if(vehicleType.equals(TYPE_CAR)){ return new Car(); } else if(vehicleType.equals(TYPE_MOTORCYCLE)){ return new MotorCycle(); } return null; } }
و برای تعریف شئ به شکل زیر عمل کنیم:
Vehicle motorCycle = vehicleFactory.createVehicle(VehicleFactory.TYPE_MOTORCYCLE);
یه روش دیگه استفاده از enum برای تعیین نوع کلاس درخواستی هست:
public class VehicleFactory {
public enum VehicleTypeEnum{
CAR, MOTOR_CYCLE
}
public Vehicle createVehicle(VehicleTypeEnum vehicleTypeEnum){
if(vehicleTypeEnum== null){ return null;
}
else if(vehicleTypeEnum.equals(VehicleTypeEnum.CAR)){
return new Car();
} else if(vehicleTypeEnum.equals(VehicleTypeEnum.MOTOR_CYCLE)){
return new MotorCycle(); } return null; }}
و زمان ساخت شئ به شکل زیر عمل کنیم:
Vehicle car = vehicleFactory.createVehicle(VehicleFactory.VehicleTypeEnum.CAR);
البته برای اینکه اصل open/close از اصول پنجگانه solid رو هم رعایت کرده باشیم میتونیم کلاس کارخونمون رو به شکل زیر پیاده سازی کنیم:
public class VehicleFactory {
public Vehicle createCar(){
return new Car();
}
public Vehicle createMotorCycle(){
return new MotorCycle();
}
}
و طبیعتاً برای ساخت شئ به شکل زیر عمل میکنیم:
Vehicle carObject = vehicleFactory.createCar();Vehicle motorCycleObject = vehicleFactory.createMotorCycle();
با کلیت این الگو آشنا شدیم. مثل هر الگوی دیگه ای با توجه به زمان، نوع و دلیل استفاده از این الگو میتونیم تغییرات لازمه ی خودمون را پیاده سازی کنیم. برای مثال تابع یا توابع سازنده ی اشیاء داخل کارخونه رو استاتیک تعریف کنیم که نیازی به تعریف شئ از کلاس کارخونه نداشته باشیم، یا در صورت نیاز از الگوی سینگلتون برای اشیاء ساخته شده استفاده کنیم، یا زمان ساخت اشیاء پارامترهایی هم پاس بدیم و با توجه به اون پارامترها تغییراتی روی شئ انجام بدیم، یا حتی بریم سراغ ارثبری ها چند سطحی و ...
@this_java
👍1
انواع دیزاین پترن
اکثرا دیزاین پترن ها به سه دسته ی زیر تقسیم میشن :
تکوینی (Creational): که بیشتر به اشیا و شیوه ی ایجادشون مرتبط هستن.
ساختاری (Structural): که بیشتر به ساختار کلاسها و ترکیب اشیاء میپردازن.
رفتاری (Behavioral): که بیشتر به ارتباط اشیاء در عین جداسازی عملکردشون تأکید دارن.
برای هر کدوم چند تا مثال میزنیم :
Creational
Singleton
Factory
Factory of Factory (Abstract Factory)
Prototype
Builder
Object Pool
Structure
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Behavioral
Command
Template
Memento
Observer
Mediator
Strategy
Iterator
@this_java
اکثرا دیزاین پترن ها به سه دسته ی زیر تقسیم میشن :
تکوینی (Creational): که بیشتر به اشیا و شیوه ی ایجادشون مرتبط هستن.
ساختاری (Structural): که بیشتر به ساختار کلاسها و ترکیب اشیاء میپردازن.
رفتاری (Behavioral): که بیشتر به ارتباط اشیاء در عین جداسازی عملکردشون تأکید دارن.
برای هر کدوم چند تا مثال میزنیم :
Creational
Singleton
Factory
Factory of Factory (Abstract Factory)
Prototype
Builder
Object Pool
Structure
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Behavioral
Command
Template
Memento
Observer
Mediator
Strategy
Iterator
@this_java
الگوی Singleton
سینگلتون شاید پایه ای ترین الگوی طراحی ای باشه که اکثر برنامه نویسا باهاش آشنا هستن و اغلب اینطور تعریف میشه که این الگو تضمین میکنه ما صرفاً یه شئ از روی یه کلاس خواهیم داشت و صرفاً یه راه برای دسترسی به اون شئ در سرتاسر نرمافزار وجود داره. اما اگه بخوایم یذره بهتر تعریف کنیم باید بگیم:
هدف اینه که نشه از کلاسی بیشتر از یک شی ساخت.
خیلیا (مثل خودِ من قبل از اینکه بیشتر با این الگو آشنا بشم) فکر میکنن مفهوم سینگلتون رو کاملاً درک کردن و کاری نداره پیاده سازیش. اما توی این مقاله میبینیم که اوضاع یذره پیچیده تر از چیزی میتونه باشه که توی نگاه اول و داخل یه خط تعریف ساده گنجونده بشه. (البته باید توجه کنیم که اغلب توی استفاده های عادی مشکلی وجود نداره و در ادامه متوجه میشیم منظور ما از پیچیده تر شدن، یسری زمان های خاصی هست که باهاشون آشنا خواهیم شد).
برای پیاده سازی این الگو راه های زیادی وجود داره که سعی میکنیم مهمتریناشون رو بررسی کنیم (یه نکته اینکه به شئ ای که قراره یکی بیشتر نشه ازش ساخت توی این الگو اصطلاحاً instance گفته میشه):
روش Eager initialization
توی این روش که ساده ترین نوع پیاده سازی الگوی سینگلتون هست، instance در زمان لود کلاس ساخته میشه. در حقیقت چه بخوایم از instance استفاده بکنیم چه نخوایم، در هر صورت ساخته میشه و زمان فراخوانی تابع شئ ای که از قبل ساخته شده برگردونده میشه. این روش بصورت زیر پیاده میشه:
public class EagerInitializedSingleton {
private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();
private EagerInitializedSingleton(){
}
public static EagerInitializedSingleton getInstance(){
return instance;
}
}
اگه کلاس سینگلتونمون ریسورس های زیادی نداره، این روش مناسبیه ولی خب متأسفانه خیلی وقتا هست که ما دسترسی به فایل ها، دیبتابیس و سایر موارد این چنینی رو توی کلاس سینگلتون میذاریم و ممکنه باعث بوجود اومدن مشکلاتی مثل کمبود حافظه یا الکی درگیر نگه داشتم کانکشن ها بشیم.
روش Static block
این روش خیلی شبیه روش قبلی هست با این تفاوت که instance داخل بلوک static ساخته میشه (که البته یکی از معایب روش قبل رو که عدم وجود امکان هندل کردن اکسپشن ها بود رو نداره، اصطلاحاً امکان exception handling رو محیا میکنه):
public class StaticBlockSingleton {
private static StaticBlockSingleton instance private StaticBlockSingleton(){
}
static{
try{
instance = new StaticBlockSingleton();
}catch(Exception e){
throw new RuntimeException("Exception occured in creating singleton instance");
}
} public static StaticBlockSingleton getInstance(){
return instance;
}
}
هردوی این روش و روش قبلی، حتی اگه از instance استفاده نشه، بازم اون رو میسازن و طبیعتاً میتونیم بگیم توی خیلی از شرایط نمیتونه بهترین انتخاب یا اصطلاحاً best practice باشه (گرچه خیلی اوقات هم از همین روش برای پیاده سازی بدون مشکل استفاده میشه).
روش Lazy Initialization
این روش برای ساخت instance زمانی که بهش نیاز داریم استفاده میشه و به این صورت قابل پیاده سازیه:
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){
}
public static LazyInitializedSingleton getInstance(){
if(instance == null){ instance = new LazyInitializedSingleton();
}
return instance;
}
}
در حقیقت با این روش (بر خلاف دو روش قبلی) instance از اول ساخته نمیشه که شاید ازش استفاده بشه شاید هم نیشه، و بجای اون زمانی که میخوایم ازش استفاده کنیم چک میکنیم اگه قبلاً ساخته نشده بود میسازیمش.
روش Thread Safe Singleton
خب قبل از گفتن این روش یه مقدمه بخونیم.
تا اینجا سه روش مرسوم توی حالت عادی رو دیدیم. اما یه سوال، اگه ما بخوایم نرم افزارمون چندنخی (یا اصطلاحاً multi thread) باشه چی؟ بازم میتونیم از این روش استفاده کنیم؟
جواب منفیه! توی نوشتن برنامه های چندنخی، هر نخ میتونه instance جدا داشته باشه.
این نکته رو هم بگم که توی سری مقالات دیزاین پترن ها، فقط این توی این الگو اونم بیشتر برای آشنایی بیشتر سراغ موارد خاص میریم. توی بقیه الگوها اغلب اگه موردش پیش اومد با توجه به نکات این مقاله یا سرچ، تغییرات لازمه رو اعمال کنین.
با توجه به چیزایی که گفتیم، برای اینکه جلوگیری کنیم از اینکه هر نخ instance خودش رو بسازه، میتونیم از synchronized استفاده بکنیم. بصورت زیر:
سینگلتون شاید پایه ای ترین الگوی طراحی ای باشه که اکثر برنامه نویسا باهاش آشنا هستن و اغلب اینطور تعریف میشه که این الگو تضمین میکنه ما صرفاً یه شئ از روی یه کلاس خواهیم داشت و صرفاً یه راه برای دسترسی به اون شئ در سرتاسر نرمافزار وجود داره. اما اگه بخوایم یذره بهتر تعریف کنیم باید بگیم:
هدف اینه که نشه از کلاسی بیشتر از یک شی ساخت.
خیلیا (مثل خودِ من قبل از اینکه بیشتر با این الگو آشنا بشم) فکر میکنن مفهوم سینگلتون رو کاملاً درک کردن و کاری نداره پیاده سازیش. اما توی این مقاله میبینیم که اوضاع یذره پیچیده تر از چیزی میتونه باشه که توی نگاه اول و داخل یه خط تعریف ساده گنجونده بشه. (البته باید توجه کنیم که اغلب توی استفاده های عادی مشکلی وجود نداره و در ادامه متوجه میشیم منظور ما از پیچیده تر شدن، یسری زمان های خاصی هست که باهاشون آشنا خواهیم شد).
برای پیاده سازی این الگو راه های زیادی وجود داره که سعی میکنیم مهمتریناشون رو بررسی کنیم (یه نکته اینکه به شئ ای که قراره یکی بیشتر نشه ازش ساخت توی این الگو اصطلاحاً instance گفته میشه):
روش Eager initialization
توی این روش که ساده ترین نوع پیاده سازی الگوی سینگلتون هست، instance در زمان لود کلاس ساخته میشه. در حقیقت چه بخوایم از instance استفاده بکنیم چه نخوایم، در هر صورت ساخته میشه و زمان فراخوانی تابع شئ ای که از قبل ساخته شده برگردونده میشه. این روش بصورت زیر پیاده میشه:
public class EagerInitializedSingleton {
private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();
private EagerInitializedSingleton(){
}
public static EagerInitializedSingleton getInstance(){
return instance;
}
}
اگه کلاس سینگلتونمون ریسورس های زیادی نداره، این روش مناسبیه ولی خب متأسفانه خیلی وقتا هست که ما دسترسی به فایل ها، دیبتابیس و سایر موارد این چنینی رو توی کلاس سینگلتون میذاریم و ممکنه باعث بوجود اومدن مشکلاتی مثل کمبود حافظه یا الکی درگیر نگه داشتم کانکشن ها بشیم.
روش Static block
این روش خیلی شبیه روش قبلی هست با این تفاوت که instance داخل بلوک static ساخته میشه (که البته یکی از معایب روش قبل رو که عدم وجود امکان هندل کردن اکسپشن ها بود رو نداره، اصطلاحاً امکان exception handling رو محیا میکنه):
public class StaticBlockSingleton {
private static StaticBlockSingleton instance private StaticBlockSingleton(){
}
static{
try{
instance = new StaticBlockSingleton();
}catch(Exception e){
throw new RuntimeException("Exception occured in creating singleton instance");
}
} public static StaticBlockSingleton getInstance(){
return instance;
}
}
هردوی این روش و روش قبلی، حتی اگه از instance استفاده نشه، بازم اون رو میسازن و طبیعتاً میتونیم بگیم توی خیلی از شرایط نمیتونه بهترین انتخاب یا اصطلاحاً best practice باشه (گرچه خیلی اوقات هم از همین روش برای پیاده سازی بدون مشکل استفاده میشه).
روش Lazy Initialization
این روش برای ساخت instance زمانی که بهش نیاز داریم استفاده میشه و به این صورت قابل پیاده سازیه:
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){
}
public static LazyInitializedSingleton getInstance(){
if(instance == null){ instance = new LazyInitializedSingleton();
}
return instance;
}
}
در حقیقت با این روش (بر خلاف دو روش قبلی) instance از اول ساخته نمیشه که شاید ازش استفاده بشه شاید هم نیشه، و بجای اون زمانی که میخوایم ازش استفاده کنیم چک میکنیم اگه قبلاً ساخته نشده بود میسازیمش.
روش Thread Safe Singleton
خب قبل از گفتن این روش یه مقدمه بخونیم.
تا اینجا سه روش مرسوم توی حالت عادی رو دیدیم. اما یه سوال، اگه ما بخوایم نرم افزارمون چندنخی (یا اصطلاحاً multi thread) باشه چی؟ بازم میتونیم از این روش استفاده کنیم؟
جواب منفیه! توی نوشتن برنامه های چندنخی، هر نخ میتونه instance جدا داشته باشه.
این نکته رو هم بگم که توی سری مقالات دیزاین پترن ها، فقط این توی این الگو اونم بیشتر برای آشنایی بیشتر سراغ موارد خاص میریم. توی بقیه الگوها اغلب اگه موردش پیش اومد با توجه به نکات این مقاله یا سرچ، تغییرات لازمه رو اعمال کنین.
با توجه به چیزایی که گفتیم، برای اینکه جلوگیری کنیم از اینکه هر نخ instance خودش رو بسازه، میتونیم از synchronized استفاده بکنیم. بصورت زیر:
public class ThreadSafeSingleton {
private static ThreadSafeSingleton instance;
private ThreadSafeSingleton(){
}
public static synchronized ThreadSafeSingleton getInstance(){ if(instance == null){
instance = new ThreadSafeSingleton();
}
return instance;
}
}
پیاده سازی بالا اصطلاحاً thread-safe هست (در برابر چند نخی مقاومت داره و اجازه نمیده چند نخی نتیجه ی متفاوتی از تک نخی داشته باشه) اما بخاطر استفاده از synchronized کارایی یا همون performance رو کاهش میده. برای اینکه هربار اصطلاحاً overhead نداشته باشیم از double checked locking استفاده میکنیم و کد بالا رو به شکل زیر تغییر میدیم:
public static ThreadSafeSingleton getInstanceUsingDoubleLocking(){
if(instance == null){
synchronized (ThreadSafeSingleton.class) {
if(instance == null){
instance = new ThreadSafeSingleton();
}
}
} return instance;
}
برای آشنایی بیشتر با اینکه چیکار کردیم میتونین نگاهی به این مقاله بندازین.
روش Bill Pugh Singleton
این روش بیشتر به نسخه های جاوا قبل از 5 مرتبط میشه که مشکلاتی در حافظه و چندنخی داشتن. به همین خاطر روش زیر مطرح شد:
public class BillPughSingleton {
private BillPughSingleton(){
}
private static class SingletonHelper{
private static final BillPughSingleton INSTANCE = new BillPughSingleton();
}
public static BillPughSingleton getInstance(){
return SingletonHelper.INSTANCE; }
}
دقت کنیم که instance داخل یک کلاس داخلی استاتیک (یا اصطلاحاً private inner static) قرار داره. بنابراین، زمانی که در کد بالا کلاس BillPughSingleton لود میشه، کلاس SingletonHelper توی مموری لود نمیشه (زمانی که تابع getInstance صدا زده بشه لود میشه)
این روش هم خیلی خوبه و نیازی به synchronization نداره، و البته فهم و پیاده سازیش راحته نسبتاً.
@this_java
private static ThreadSafeSingleton instance;
private ThreadSafeSingleton(){
}
public static synchronized ThreadSafeSingleton getInstance(){ if(instance == null){
instance = new ThreadSafeSingleton();
}
return instance;
}
}
پیاده سازی بالا اصطلاحاً thread-safe هست (در برابر چند نخی مقاومت داره و اجازه نمیده چند نخی نتیجه ی متفاوتی از تک نخی داشته باشه) اما بخاطر استفاده از synchronized کارایی یا همون performance رو کاهش میده. برای اینکه هربار اصطلاحاً overhead نداشته باشیم از double checked locking استفاده میکنیم و کد بالا رو به شکل زیر تغییر میدیم:
public static ThreadSafeSingleton getInstanceUsingDoubleLocking(){
if(instance == null){
synchronized (ThreadSafeSingleton.class) {
if(instance == null){
instance = new ThreadSafeSingleton();
}
}
} return instance;
}
برای آشنایی بیشتر با اینکه چیکار کردیم میتونین نگاهی به این مقاله بندازین.
روش Bill Pugh Singleton
این روش بیشتر به نسخه های جاوا قبل از 5 مرتبط میشه که مشکلاتی در حافظه و چندنخی داشتن. به همین خاطر روش زیر مطرح شد:
public class BillPughSingleton {
private BillPughSingleton(){
}
private static class SingletonHelper{
private static final BillPughSingleton INSTANCE = new BillPughSingleton();
}
public static BillPughSingleton getInstance(){
return SingletonHelper.INSTANCE; }
}
دقت کنیم که instance داخل یک کلاس داخلی استاتیک (یا اصطلاحاً private inner static) قرار داره. بنابراین، زمانی که در کد بالا کلاس BillPughSingleton لود میشه، کلاس SingletonHelper توی مموری لود نمیشه (زمانی که تابع getInstance صدا زده بشه لود میشه)
این روش هم خیلی خوبه و نیازی به synchronization نداره، و البته فهم و پیاده سازیش راحته نسبتاً.
@this_java
مثال برای foreach :
روش معمولی حلقه زدن در Map.
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);
for (Map.Entry<String, Integer> entry : items.entrySet()) {
System.out.println("Item : " + entry.getKey() + " Count : " + entry.getValue());
}
در جاوا 8، شما می توانید با استفاده از foreach به همراه lambda expression درون یک Map حلقه بزنید.
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);
items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));
items.forEach((k,v)->{
System.out.println("Item : " + k + " Count : " + v);
if("E".equals(k)){
System.out.println("Hello E");
}
});
@this_java
روش معمولی حلقه زدن در Map.
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);
for (Map.Entry<String, Integer> entry : items.entrySet()) {
System.out.println("Item : " + entry.getKey() + " Count : " + entry.getValue());
}
در جاوا 8، شما می توانید با استفاده از foreach به همراه lambda expression درون یک Map حلقه بزنید.
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);
items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));
items.forEach((k,v)->{
System.out.println("Item : " + k + " Count : " + v);
if("E".equals(k)){
System.out.println("Hello E");
}
});
@this_java
تفاوت object تغییرپذیر (mutable) و تغییرناپذیر (immutable) در جاوا
1. Mutable Objects: شما می توانید وضعیت و فیلدهای شیء یا object را بعد از ایجاد شدن تغییر دهید. برای مثال: StringBuilder ،java.util.Date و غیره.
2. Immutable Object: شما نمی توانید هیچ چیزی را بعد از ایجاد شدن object تغییر دهید. برای مثال: String ،Integer ،Long و غیره.
مثال Mutable جاوا
به طور معمول، متدی برای ویرایش مقدار فیلد در خود دارد، و object می تواند گسترش پیدا کند.
package org.oruji;
public class MutableExample {
private String name;
MutableClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
// this setter can modify the name
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
MutableExample obj = new MutableExample("oruji");
System.out.println(obj.getName());
// update the name, this object is mutable
obj.setName("new oruji");
System.out.println(obj.getName());
}
}
خروجی برنامه
oruji
new oruji
مثال Immutable جاوا
برای ایجاد یک object تغییر ناپدیر (immutable)، کلاس را به صورت final تعریف کرده، و هیچ متدی برای ویرایش فیلدها ایجاد نکنید.
package org.oruji;
// make this class final, no one can extend this class
public final class ImmutableExample {
private String name;
ImmutableExample (String name) {
this.name = name;
}
public String getName() {
return name;
}
//no setter
public static void main(String[] args) {
ImmutableExample obj = new ImmutableExample("oruji");
System.out.println(obj.getName());
// there is no way to update the name after the object is created.
// obj.setName("new oruji");
// System.out.println(obj.getName());
}
}
خروجی برنامه
oruji
@this_java
1. Mutable Objects: شما می توانید وضعیت و فیلدهای شیء یا object را بعد از ایجاد شدن تغییر دهید. برای مثال: StringBuilder ،java.util.Date و غیره.
2. Immutable Object: شما نمی توانید هیچ چیزی را بعد از ایجاد شدن object تغییر دهید. برای مثال: String ،Integer ،Long و غیره.
مثال Mutable جاوا
به طور معمول، متدی برای ویرایش مقدار فیلد در خود دارد، و object می تواند گسترش پیدا کند.
package org.oruji;
public class MutableExample {
private String name;
MutableClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
// this setter can modify the name
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
MutableExample obj = new MutableExample("oruji");
System.out.println(obj.getName());
// update the name, this object is mutable
obj.setName("new oruji");
System.out.println(obj.getName());
}
}
خروجی برنامه
oruji
new oruji
مثال Immutable جاوا
برای ایجاد یک object تغییر ناپدیر (immutable)، کلاس را به صورت final تعریف کرده، و هیچ متدی برای ویرایش فیلدها ایجاد نکنید.
package org.oruji;
// make this class final, no one can extend this class
public final class ImmutableExample {
private String name;
ImmutableExample (String name) {
this.name = name;
}
public String getName() {
return name;
}
//no setter
public static void main(String[] args) {
ImmutableExample obj = new ImmutableExample("oruji");
System.out.println(obj.getName());
// there is no way to update the name after the object is created.
// obj.setName("new oruji");
// System.out.println(obj.getName());
}
}
خروجی برنامه
oruji
@this_java
تبدیل به یک رشته:
String.ValueOf()
یا + ""
کدام یک؟
غالبا دو روش کلی برای تبدیل به رشته در جاوا وجود دارد یکی استفاده از کلاس String و دیگری جمع کردن ان با یک رشته ی دیگر ...
هدف تبدیل به یک رشته است و نه پیوند رشته!
String.valueOf به یک رشته تبدیل میکند در حالی + "" با یک رشته پیوند میدهد
String.ValueOf :
مستقیما به یک رشته تبدیل میکند
+"":
یک StringBuffer تولید میکنه و بعد به String تبدیل میکنه
پس String.ValueOf روند کمتری رو طی میکنه و مناسب تره...
@this_java
String.ValueOf()
یا + ""
کدام یک؟
غالبا دو روش کلی برای تبدیل به رشته در جاوا وجود دارد یکی استفاده از کلاس String و دیگری جمع کردن ان با یک رشته ی دیگر ...
هدف تبدیل به یک رشته است و نه پیوند رشته!
String.valueOf به یک رشته تبدیل میکند در حالی + "" با یک رشته پیوند میدهد
String.ValueOf :
مستقیما به یک رشته تبدیل میکند
+"":
یک StringBuffer تولید میکنه و بعد به String تبدیل میکنه
پس String.ValueOf روند کمتری رو طی میکنه و مناسب تره...
@this_java
بلوک استاتیک چیست؟
در کلاس های جاوا ما اجازه نداریم متغیر های ثابت استاتیک را (static final) داخل سازنده یا بلوک غیر استاتیک مقدار دهی اولیه کنیم و به ناچار باید داخل static block اونار مقدار دهی کنیم
//this is static block
static {
}
// this is non static block
{
}
اگر متغیر های static final داخل static block مقدار دهی نشه compilation error ارور میگیرید
نکته ی قابل توجه اینه که بلاک استاتیک، تنها یک بار در موقع load شدن کلاس (با اولین access به کلاس، کلاس load میشود) فراخوانی میشه
@this_java
در کلاس های جاوا ما اجازه نداریم متغیر های ثابت استاتیک را (static final) داخل سازنده یا بلوک غیر استاتیک مقدار دهی اولیه کنیم و به ناچار باید داخل static block اونار مقدار دهی کنیم
//this is static block
static {
}
// this is non static block
{
}
اگر متغیر های static final داخل static block مقدار دهی نشه compilation error ارور میگیرید
نکته ی قابل توجه اینه که بلاک استاتیک، تنها یک بار در موقع load شدن کلاس (با اولین access به کلاس، کلاس load میشود) فراخوانی میشه
@this_java