انواع دیزاین پترن
اکثرا دیزاین پترن ها به سه دسته ی زیر تقسیم میشن :
تکوینی (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
چرا static block ها در جاوا قبل از constructor اجرا می شوند؟
بلاک استاتیک تنها یکبار و در اولین دسترسی به کلاس اجرا میشود.
درحالیکه constructor در هر زمان که از کلاس یک نمونه ساخته میشود یکبار اجرا میشود.پس لازم است ابتدا محتویات داخل استاتیک که مربوط به آماده سازی خود کلاس است ونه نمونه هاش اجرا شود و سپس یک نمونه از آن ساخته شود.
@this_java
بلاک استاتیک تنها یکبار و در اولین دسترسی به کلاس اجرا میشود.
درحالیکه constructor در هر زمان که از کلاس یک نمونه ساخته میشود یکبار اجرا میشود.پس لازم است ابتدا محتویات داخل استاتیک که مربوط به آماده سازی خود کلاس است ونه نمونه هاش اجرا شود و سپس یک نمونه از آن ساخته شود.
@this_java
دلیل استفاده نشدن کلمات this و super در متد هاس static چیست؟
this
اشاره به object ای دارد که از روی این کلاس «نمونه سازی» (instantiate) شده است. در حالی که متد های استاتیک، باید بتوانند بدون این که نمونه ای از کلاس ساخته شده باشد کار کنند.
@this_java
this
اشاره به object ای دارد که از روی این کلاس «نمونه سازی» (instantiate) شده است. در حالی که متد های استاتیک، باید بتوانند بدون این که نمونه ای از کلاس ساخته شده باشد کار کنند.
@this_java
آیا اینکه تمام متد های یک سیستم را به صورت static تعریف کنیم موجب بالا بردن performance در سیستم می گردد؟
اینکه از عضو های استاتیک یک کلاس شئ ساخته نمی شود اشتباه است بلکه از اعضای استاتیک یک کلاس در زمان اجرای JVM، اشیاء خاصی در حافظه heap ساخته می شود.
تنها تفاوت performance که می تواند وجود داشته باشد این است که برنامه ای که اعضای استاتیک زیادی دارد زمان شروع بکار (startup) آن بیشتر طول می کشد و در عوض پس از اجرا شدن سریعتر کار می کند.
اما این نکته را هم در نظر بگیرید که مبحث اعضای استاتیک و غیر استاتیک یک کلاس برای طراحی بهتر برنامه تعریف شده اند نه بحث performance و نمی توان بدلیل اینکه اعضای استاتیک، performance زمان اجرای برنامه را بالا می برند تمام اعضا را استاتیک تعریف کرد.
@this_java
اینکه از عضو های استاتیک یک کلاس شئ ساخته نمی شود اشتباه است بلکه از اعضای استاتیک یک کلاس در زمان اجرای JVM، اشیاء خاصی در حافظه heap ساخته می شود.
تنها تفاوت performance که می تواند وجود داشته باشد این است که برنامه ای که اعضای استاتیک زیادی دارد زمان شروع بکار (startup) آن بیشتر طول می کشد و در عوض پس از اجرا شدن سریعتر کار می کند.
اما این نکته را هم در نظر بگیرید که مبحث اعضای استاتیک و غیر استاتیک یک کلاس برای طراحی بهتر برنامه تعریف شده اند نه بحث performance و نمی توان بدلیل اینکه اعضای استاتیک، performance زمان اجرای برنامه را بالا می برند تمام اعضا را استاتیک تعریف کرد.
@this_java
چرا نباید در جاوا درون Constructor متد های کلاس را فراخوانی کرد؟
دایتل در آخرین کتاب خود بر خلاف قبل صحت پارامترهای سازنده را توسط فراخوانی متدهای setter در سازنده انجام نمی دهد بلکه شروط متد setter را مجددا در سازنده بازنویسی کرده آیا این کار تاثیری در performance دارد؟
جواب:
دلیل این کار وجود یک violation در مباحث کنترل کیفیت کد است که باعث می شود نتایجی برخلاف آن چیزی که ما توقع داریم اتفاق بیوفتد. در زبان برنامه نویسی جاوا نباید درون Constructor متد هایی که قابل override شدن هستند را فراخوانی کرد (متد های private, static, یا final قابل override شدن نیستند). به این قانون به زبان انگلیسی Ensure that constructors do not call overridable methods می گویند.
در زبان برنامه نویسی جاوا اگر متد یک کلاس در کلاس فرزندش override شده باشد و در Constructor کلاس پدر متد override شده فراخوانی شود، متد override شده در کلاس فرزند استفاده خواهد شد. به کد زیر توجه کنید:
class SuperClass {
public SuperClass () {
doLogic();
}
public void doLogic() {
System.out.println("This is superclass!");
}
}
class SubClass extends SuperClass {
private String color = null;
public SubClass() {
super();
color = "Red";
}
public void doLogic() {
System.out.println("This is subclass! The color is :" + color);
// ...
}
}
public class Overridable {
public static void main(String[] args) {
SuperClass bc = new SuperClass();
// Prints "This is superclass!"
SuperClass sc = new SubClass();
// Prints "This is subclass! The color is :null"
}
}
کد بالا بدون مشکل و خطا اجرا می شود ولی در زمانی که در Constructor کلاس SubClass با استفاده از super سازنده کلاس SuperClass فراخوانی می شود بجای فراخوانی متد doLogic در SuperClass متد doLogic در SubClass فراخوانی می شود.
راه حل:
یا باید متد doLogic را غیرقابل override کرد یا اینکه بدنه متد doLogic را در محل مشخص در Constructor کپی کرد و از متد doLogic صرف نظر کرد.
@this_java
دایتل در آخرین کتاب خود بر خلاف قبل صحت پارامترهای سازنده را توسط فراخوانی متدهای setter در سازنده انجام نمی دهد بلکه شروط متد setter را مجددا در سازنده بازنویسی کرده آیا این کار تاثیری در performance دارد؟
جواب:
دلیل این کار وجود یک violation در مباحث کنترل کیفیت کد است که باعث می شود نتایجی برخلاف آن چیزی که ما توقع داریم اتفاق بیوفتد. در زبان برنامه نویسی جاوا نباید درون Constructor متد هایی که قابل override شدن هستند را فراخوانی کرد (متد های private, static, یا final قابل override شدن نیستند). به این قانون به زبان انگلیسی Ensure that constructors do not call overridable methods می گویند.
در زبان برنامه نویسی جاوا اگر متد یک کلاس در کلاس فرزندش override شده باشد و در Constructor کلاس پدر متد override شده فراخوانی شود، متد override شده در کلاس فرزند استفاده خواهد شد. به کد زیر توجه کنید:
class SuperClass {
public SuperClass () {
doLogic();
}
public void doLogic() {
System.out.println("This is superclass!");
}
}
class SubClass extends SuperClass {
private String color = null;
public SubClass() {
super();
color = "Red";
}
public void doLogic() {
System.out.println("This is subclass! The color is :" + color);
// ...
}
}
public class Overridable {
public static void main(String[] args) {
SuperClass bc = new SuperClass();
// Prints "This is superclass!"
SuperClass sc = new SubClass();
// Prints "This is subclass! The color is :null"
}
}
کد بالا بدون مشکل و خطا اجرا می شود ولی در زمانی که در Constructor کلاس SubClass با استفاده از super سازنده کلاس SuperClass فراخوانی می شود بجای فراخوانی متد doLogic در SuperClass متد doLogic در SubClass فراخوانی می شود.
راه حل:
یا باید متد doLogic را غیرقابل override کرد یا اینکه بدنه متد doLogic را در محل مشخص در Constructor کپی کرد و از متد doLogic صرف نظر کرد.
@this_java
آیا می توان متد که private یا static است را در جاوا override کرد؟
متد های private اصلا در مکانیزم وراثت در جاوا به کلاس فرزند ارث نمی رسند چه برسد به اینکه بخواهیم آنها را override کنیم.
متد های استاتیک یک کلاس را نمی توان override کرد بلکه می توانیم متد های استاتیک یک کلاس را مخفی (hide) کنیم.
@this_java
متد های private اصلا در مکانیزم وراثت در جاوا به کلاس فرزند ارث نمی رسند چه برسد به اینکه بخواهیم آنها را override کنیم.
متد های استاتیک یک کلاس را نمی توان override کرد بلکه می توانیم متد های استاتیک یک کلاس را مخفی (hide) کنیم.
@this_java
چرا نمی توان در جاوا متد های استاتیک را override کرد اما در زبان هایی مانند Scala یا Objective-C این کار امکانپذیر است؟
بدلیل اینکه متد های استاتیک در جاوا به اشیاء ساخته شده از یک کلاس تعلق ندارند و اصطلاحا متد های در سطح کلاس هستند و نمی توان آنها را در کلاس فرزند override کرد و اگر یک متد استاتیک در کلاس فرزند دقیقا با همان امضای متد کلاس پدر وجود داشته باشد خطایی رخ نمی دهد و برنامه بدرستی کامپایل می شود.
در این موارد گفته می شود کد متد فرزند متد پدر را hide کرده است و به این کار override گفته نمی شود چون هنوز متد کلاس پدر در سطح همان کلاس قابل دسترسی است.
@this_java
بدلیل اینکه متد های استاتیک در جاوا به اشیاء ساخته شده از یک کلاس تعلق ندارند و اصطلاحا متد های در سطح کلاس هستند و نمی توان آنها را در کلاس فرزند override کرد و اگر یک متد استاتیک در کلاس فرزند دقیقا با همان امضای متد کلاس پدر وجود داشته باشد خطایی رخ نمی دهد و برنامه بدرستی کامپایل می شود.
در این موارد گفته می شود کد متد فرزند متد پدر را hide کرده است و به این کار override گفته نمی شود چون هنوز متد کلاس پدر در سطح همان کلاس قابل دسترسی است.
@this_java
اگر هنوز با Jlink کار نکرده اید، ببینید چه چیزی از ابزار خط فرمان Java 9 می تواند برای کمک به یک JRE سبک وزن، سفارشی ایجاد کند.
معمولا برنامه ما با استفاده از JRE پیش فرض اجرا می شود، اما در صورتی که می خواهید JRE خودتان را ایجاد کنید، می توانید با مفهوم jlink اشنا شوید.
چرا JRE خود را بسازید؟
فرض کنید ما یک برنامه ساده " Hello World !" داریم:
String.class
Test.class
System.class
Object.class
در اینجا، این 4 کلاس برای اجرای برنامه من کافی خواهد بود.
پیش فرض JRE توسط اوراکل شامل 4300 + فایل جاوا کلاس از پیش تعریف شده است .
اگر من درخواست hello world را با JRE پیش فرض اجرا کنم، سپس تمام فایل های کلاس class از پیش تعریف شده اجرا خواهند شد. اما اگر من فقط به فایل های 3-4 .class نیاز داشته باشم که برنامه Hello World را اجرا کنم، پس چرا باید فایل های بیرونی کلاس را حفظ کنم؟
بنابراین مشکل با JRE پیش فرض این است که تمام فایل های .class از پیش تعریف شده را اجرا می کند، آیا می خواهید یا نه.
و اگر شما همچنین به اندازه پیش فرض JRE نگاه کنید، خواهید دید که آن 203 مگابایت است. برای اجرای 1 کیلوبایت ساده من، باید 203 مگابایت JRE را در دستگاه خود نگهداری کنم. این یک اتلاف کامل از حافظه است.
بنابراین استفاده از JRE به طور پیش فرض به این معنی است:
بنابراین جاوا بهترین انتخاب برای سرویس های microservices و IoT نیست، اما این فقط یک مشکل با جاوا 1.8 بود. ولی حالا، جاوا 1.9 با jlink همراه است. با jlink ما می توانیم JRE کوچک خود را که شامل تنها کلاس های مرتبط است که می خواهیم ایجاد کنیم. و از هدر رفتن حافظه جلوگیری و عملکرد نیز افزایش خواهد یافت.
@this_java
معمولا برنامه ما با استفاده از JRE پیش فرض اجرا می شود، اما در صورتی که می خواهید JRE خودتان را ایجاد کنید، می توانید با مفهوم jlink اشنا شوید.
چرا JRE خود را بسازید؟
فرض کنید ما یک برنامه ساده " Hello World !" داریم:
class Test {
public static void main(String[]args) {
System.out.prinltn("Hello World");
}
}
برای اجرای این برنامه "hello world" کوچک، ما نیاز به کلاس فایل های زیر داریم :String.class
Test.class
System.class
Object.class
در اینجا، این 4 کلاس برای اجرای برنامه من کافی خواهد بود.
پیش فرض JRE توسط اوراکل شامل 4300 + فایل جاوا کلاس از پیش تعریف شده است .
اگر من درخواست hello world را با JRE پیش فرض اجرا کنم، سپس تمام فایل های کلاس class از پیش تعریف شده اجرا خواهند شد. اما اگر من فقط به فایل های 3-4 .class نیاز داشته باشم که برنامه Hello World را اجرا کنم، پس چرا باید فایل های بیرونی کلاس را حفظ کنم؟
بنابراین مشکل با JRE پیش فرض این است که تمام فایل های .class از پیش تعریف شده را اجرا می کند، آیا می خواهید یا نه.
و اگر شما همچنین به اندازه پیش فرض JRE نگاه کنید، خواهید دید که آن 203 مگابایت است. برای اجرای 1 کیلوبایت ساده من، باید 203 مگابایت JRE را در دستگاه خود نگهداری کنم. این یک اتلاف کامل از حافظه است.
بنابراین استفاده از JRE به طور پیش فرض به این معنی است:
بنابراین جاوا بهترین انتخاب برای سرویس های microservices و IoT نیست، اما این فقط یک مشکل با جاوا 1.8 بود. ولی حالا، جاوا 1.9 با jlink همراه است. با jlink ما می توانیم JRE کوچک خود را که شامل تنها کلاس های مرتبط است که می خواهیم ایجاد کنیم. و از هدر رفتن حافظه جلوگیری و عملکرد نیز افزایش خواهد یافت.
@this_java
همونطور که میدونید java fx از jdk 11 حذف شده ... اگه میخواید ازش استفاده کنید به صورت زیر عمل کنید:
https://dzone.com/articles/javafx-on-jdk-11
و اگر از maven همونطور که میدونید java fx از jdk 11 حذف شده ... اگه میخواید ازش استفاده کنید به صورت زیر عمل کنید:
https://dzone.com/articles/javafx-on-jdk-11
و اگر از maven استفاده میکنید :
<!-- https://mvnrepository.com/artifact/org.openjfx/javafx-controls -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
@this_java
https://dzone.com/articles/javafx-on-jdk-11
و اگر از maven همونطور که میدونید java fx از jdk 11 حذف شده ... اگه میخواید ازش استفاده کنید به صورت زیر عمل کنید:
https://dzone.com/articles/javafx-on-jdk-11
و اگر از maven استفاده میکنید :
<!-- https://mvnrepository.com/artifact/org.openjfx/javafx-controls -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
@this_java
dzone.com
How to Create a Project With JavaFX on JDK 11 - DZone Java
After the decoupling of JavaFX from JDK, this tutorial attempts to demonstrate how you can create a modularized project with Maven on JDK 11 with example code.
var چیست؟
نوعی متغیر جدید که در java 10 معرفی شد و میتونه هر نوع مقداری رو توی خودش نگه داره... map عدد رشته لیست url و...
var list = List.of("A", "B", "C");
var copy = List.copyOf(list);
System.out.println(list == copy); // true
در سایت زیر میتونید اطلاعات بیشتری کسب کنید:
https://winterbe.com/posts/2018/09/24/java-11-tutorial/
@this_java
نوعی متغیر جدید که در java 10 معرفی شد و میتونه هر نوع مقداری رو توی خودش نگه داره... map عدد رشته لیست url و...
var list = List.of("A", "B", "C");
var copy = List.copyOf(list);
System.out.println(list == copy); // true
در سایت زیر میتونید اطلاعات بیشتری کسب کنید:
https://winterbe.com/posts/2018/09/24/java-11-tutorial/
@this_java
Winterbe
Java 11 Tutorial
Learn what's new in Java 9 to 11: Local Variable Type Inference, HTTP-Client, Collections, Streams, Optionals, Strings, InputStreams and more.
چرا متد main() در جاوا static میباشد؟
زیرا متدهای استاتیک را می توان بدون نمونه سازی(شی ساختن) از یک کلاس صدا زد. و متد ()main قبل از نمونه (شی) ایجاد شده از یک کلاس توسط jvm صدا زده می شود.
خب چرا jvm شی نمیسازه از کلاس و ازون طریق متد main رو صدا نمیزنه؟
واقعیت این هست که ممکنه شما داخل سازنده ی کلاستون یک پارامتر برای ورودی بگیرید... jvm چه داده ای باید پاس کنه به شما؟
یا ممکنه طوری سازنده رو تعریف کنید که jvm قادر به فراخونیش نباشه...
@this_java
زیرا متدهای استاتیک را می توان بدون نمونه سازی(شی ساختن) از یک کلاس صدا زد. و متد ()main قبل از نمونه (شی) ایجاد شده از یک کلاس توسط jvm صدا زده می شود.
خب چرا jvm شی نمیسازه از کلاس و ازون طریق متد main رو صدا نمیزنه؟
واقعیت این هست که ممکنه شما داخل سازنده ی کلاستون یک پارامتر برای ورودی بگیرید... jvm چه داده ای باید پاس کنه به شما؟
یا ممکنه طوری سازنده رو تعریف کنید که jvm قادر به فراخونیش نباشه...
@this_java
مدیریت خطا در جاوا
یکی از مکانیزم های کارا جهت مدیریت خطاهای زمان اجرا است تا جریان
اجرای برنامه قطع نشده و روند عادی برنامه دچار اخلال نشود.
مفهوم Exception
این لغت در فرهنگ واژه به معنای شرایط غیرعادی می باشد.
در جاوا منظور از Exception رویدادی است که روند عادی اجرای برنامه را مختل میکند
شرح مفهوم Exception Handling
به مکانیزیمی که خطاهای رخ داده در زمان اجرای برنامه نظیر ClassNotFound, IO, SQL,Remove و.... را مدیریت میکند
مزایای Exception Handling
مزیت اصلی جلوگیری از قطع جریان و روند عادی برنامه است ...
Exception ها روند عادی برنامه را قطع میکنند به همین خاطر توسعه دهندگان از exception handling استفاده میکنند
انواع Exception ها:
در کل دو نوع وجود دارد: خطاهای زمان کامپایل (checked) و خطاهای زمان اجرا (unchecked)
شرکت sun microsystem خطا هارا به سه بخش تقسیم میکند:
Checked Exception
UnChecked Exception
Error
تفاوت ما بین Checked Exception و UnChecked Exception چیست؟
تمامی کلاس هایی که از Throwable ارث بری کنند Checked Exception هستند به استثنای Error و RunTime Exception
برای مثال : IOException
تمامی کلاس هایی که از Runtime Exception ارث بری دارند تحت عنوان UnChecked Exception خوانده میشوند
برای مثال : NullPointerException
Error:
غیر قابل مدیریت بوده و در صورت رخداد ان امکان بازیابی برنامه وجود ندارد
مثال:
OutOfMemoryError
@this_java
یکی از مکانیزم های کارا جهت مدیریت خطاهای زمان اجرا است تا جریان
اجرای برنامه قطع نشده و روند عادی برنامه دچار اخلال نشود.
مفهوم Exception
این لغت در فرهنگ واژه به معنای شرایط غیرعادی می باشد.
در جاوا منظور از Exception رویدادی است که روند عادی اجرای برنامه را مختل میکند
شرح مفهوم Exception Handling
به مکانیزیمی که خطاهای رخ داده در زمان اجرای برنامه نظیر ClassNotFound, IO, SQL,Remove و.... را مدیریت میکند
مزایای Exception Handling
مزیت اصلی جلوگیری از قطع جریان و روند عادی برنامه است ...
Exception ها روند عادی برنامه را قطع میکنند به همین خاطر توسعه دهندگان از exception handling استفاده میکنند
انواع Exception ها:
در کل دو نوع وجود دارد: خطاهای زمان کامپایل (checked) و خطاهای زمان اجرا (unchecked)
شرکت sun microsystem خطا هارا به سه بخش تقسیم میکند:
Checked Exception
UnChecked Exception
Error
تفاوت ما بین Checked Exception و UnChecked Exception چیست؟
تمامی کلاس هایی که از Throwable ارث بری کنند Checked Exception هستند به استثنای Error و RunTime Exception
برای مثال : IOException
تمامی کلاس هایی که از Runtime Exception ارث بری دارند تحت عنوان UnChecked Exception خوانده میشوند
برای مثال : NullPointerException
Error:
غیر قابل مدیریت بوده و در صورت رخداد ان امکان بازیابی برنامه وجود ندارد
مثال:
OutOfMemoryError
@this_java
📂 سورس كد اپلیکیشن"music player" به زبان #جاوا
💹 قيمت: رايگان
🛅 پسورد: www.sourcep.ir
🛄 سورس کدهای بیشتر در🔻
🆔 @this_java🎖🎖
#java
💹 قيمت: رايگان
🛅 پسورد: www.sourcep.ir
🛄 سورس کدهای بیشتر در🔻
🆔 @this_java🎖🎖
#java