3zcs

Members
  • عدد منشوراتي

    8
  • تاريخ الإنضمام

  • تاريخ اخر زياره

السمعه بالموقع

6 Neutral

عن العضو 3zcs

  • الرتبه
    مبدع جديد

اخر الزوار

328 زياره للملف الشخصي
  1. Facade Pattern

    بسم الله الرحمن الرحيم استكمالا للحديث عن أكثر Design pattern استخداما في بيئة Android, وبعد أن كنا قد بدأنا في الحديث عن أنواع Structural pattern, اليوم سيكون حديثنا عن Facade Pattern, فنبدأ بالسؤال المعتاد ماهو Facade Pattern؟ لنبدأ بتعريفه: إذا فهو Pattern يستخدم لتبسيط interfacees لأجزاء النظام, الصورة التالية ستكون شارحة جدا لوظيفة واّلية عمل هذا Pattern. جميل جدا, أعتقد أن المفهوم بات متضحاً جدا, فلندلف إلى تطبيقه بالمثال التالي. لتعلم أنه Pattern بسيط وواضح جدا, فلو فرضنا أن لدينا interface اسمه line, ولديه three claases قاموا بعمل implementation لهذا interface. وهم straight و curve و snaky. public interface Line { void draw(); } class straight public class Straight implements Line { @Override public void draw() { System.out.println("straight"); } } class curve public class Curve implements Line { @Override public void draw() { System.out.println("curve"); } } snaky class public class Snaky implements Line { @Override public void draw() { System.out.println("snaky"); } } أصبح لدينا مجموعة من classes, لو كان النظام الذي سنقوم ببنائه أكبر من ذلك سيكون من الصعب جدا تذكر هذه classes, لذلك سنقوم ببناء Facade class يحل هذه المشكلة ويبسط التعامل معها. public class LineMaker { private Line straight; private Line curve; private Line snaky; public LineMaker() { straight = new Straight(); curve = new Curve(); snaky = new Snaky(); } public void drawStraight(){ straight.draw(); } public void drawCurve(){ curve.draw(); } public void drawSnaky(){ snaky.draw(); } } أصبح التعامل هذه المجموعة من classes غاية في البساطة ويمكن التعامل معها في main كالتالي public static void main(String[] args) { LineMaker lineMaker = new LineMaker(); lineMaker.drawStraight(); lineMaker.drawCurve(); lineMaker.drawSnaky(); } } بينما لو لم نقم باستخدام facade class سيكون شكل main كالتالي: public static void main(String[] args) { private Line straight = new Straight(); private Line curve = new Curve(); private Line snaky = new Snaky(); straight.drawStraight(); curve.drawCurve(); snaky.drawSnaky(); } } طبعا هذا المثال يبسط المشكلة لكن في حال كان حجم النظام كبير ستواجه مشكلة في التعامل مع هذه الكمية من classes. وصلى الله وسلم وبارك على نبينا محمد وعلى اّله وصحبه أجمعين. المراجع: - sourcemaking.com/design_patterns - java design pattern , rohit joshi - head first design pattern - tutorialspoint.com
  2. Adapter pattern

    بسم الله الرحمن الرحيم كما ما بدأناه بالحديث عن أكثر Design pattern استخداما في بيئة Android واليوم سنتحدث عن أحد أنواع Structural pattern , ألا وهو Adapter pattern ,قبل أن نبدأ, وبما أننا في أول pattern في هذه السلسة من نوع Structural فماذا نعني ب Structural pattern ؟ Structural pattern : هو تصميم للكود بطرق تسهل فهم العلاقة بين classes و objects والربط بينها. جميل جدا, إذا ماهو Adapter pattern ؟ من كتاب GoF ولتبسيط الأمور, هذا pattern يستخدم لربط بين two classes لا يمكن الربط بينهما لعدم التوافق. كثيراً ما تكون التعريفات غير مفيدة, لنبدأ بكتابة بعض الأكواد تشرح هذا pattern. بداية دعنا نعرف المشكلة, لو فرضنا أن لديك class قديم قمت ببنائه, ومن ثم اردت الربط بينه وبين class جديد فلن تقوم بإعادة كتابته, وإنما تقوم ببناء interface يقوم بالربط بينهم كما سنقوم بذالك في المثال التالي. لنفترض أن لدينا نظام إدارة فصول إلكتروني, وأردنا ربطه مع نظام حضور وانصراف جديد,فكان شكل interface الخاص بنا كالتالي. public interface Xattendance { public String getStuedntName(); public long getStuedntId() ; public String getTime(); public void setStuedntName(String stuedntName); public void setStuedntId(long stuedntId); public void setTime(String time); } ثم قمنا بعمل implementation له داخل هذا class public class XattendanceImpl implements Xattendance{ String stuedntName; long stuedntId; String time; public String getStuedntName() { return stuedntName; } public void setStuedntName(String stuedntName) { this.stuedntName = stuedntName; } public long getStuedntId() { return stuedntId; } public void setStuedntId(long stuedntId) { this.stuedntId = stuedntId; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } } ولكن وقع الإشكال عندما أردنا ربط هذا class الخاص بنا نظام لتحضير والذي كان شكل interface الخاص به كالتالي: public interface XnewAttendaceSystem { public String getName() ; public void setName(String name); public String getId(); public void setId(String id); public String getMinute(); public void setMinute(String minute); public String getHour(); public void setHour(String hour); } وclass الذي سيقوم بعمل implementation له بهذا الشكل public class XnewAttendaceSystemImpl implements XnewAttendaceSystem{ String name; String id; String minute; String hour; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getMinute() { return minute; } public void setMinute(String minute) { this.minute = minute; } public String getHour() { return hour; } public void setHour(String hour) { this.hour = hour; } } فكما ترى لدينا two classes من نوعين مختلفين, فيلزمنا إنشاء class لنسميه المحول, حيث يمكننا عن طريقه ربط two classes مع بعضهما. وهو يقوم بعمل implementation ل XnewAttendaceSystem وفي constructor يستقبل object من نوع Xattendance ويقوم بالتحويل public class fromOldClassToNewSystem implements XnewAttendaceSystem{ String name; String id; String minute; String hour; final Xattendance xattendance; public fromOldClassToNewSystem(Xattendance xattendance) { this.xattendance = xattendance; adapt(); } @Override public String getName() { return this.name; } @Override public void setName(String name) { this.name = name; } @Override public String getId() { return this.id; } @Override public void setId(String id) { this.id = id; } @Override public String getMinute() { return this.minute; } @Override public void setMinute(String minute) { this.minute = minute; } @Override public String getHour() { return this.hour; } @Override public void setHour(String hour) { this.hour = hour; } public void adapt(){ setName(xattendance.getStuedntName()); setId(xattendance.getStuedntName()); setHour(xattendance.getTime().substring(0, 1)); setMinute(xattendance.getTime().substring(3, 4)); } } فكما ترى تم تحويل object من نوع إلى أخر, فدعنا نلقي نظرة عن طريقة استخدم هذا pattern. سنقوم بإنشاء بيانات نقوم نحن بكتابتها- من الممكن أن تكون البيانات قادمة من API أو من Database, ولكن هنا لتبسيط المقالة ستكون مكتوبة يدوياً- ومن ثم نحولها من النظام الخاص فينا, إلى النظام الذي قمنا بالربط معه. public static void main(String[] args) { Xattendance x = new XattendanceImpl(); x.setStuedntId(10110101); x.setStuedntName("ameen"); x.setTime("12:30"); XnewAttendaceSystem obj = new fromOldClassToNewSystem(x); //test System.out.println(obj.getName()); System.out.println(obj.getHour()); } وبهذا نلاحظ أنه تم إرسال البيانات من نظام إلى أخر باستخدام adapter pattern. ختاما لتعلم أن لدينا نوعان من adapter الأول هو object adapter وهو الذي تعاملنا معه في المثال اّنف الذكر, والذي استخدمنا في بنائه مبدأ composition, والأخر هو adapter class والذي يعتمد في بنائه على multiple inheritance وهو غير مدعوم في java تجنباً لمشكلة DDD (deadly diamond of death), ولكن يمكنك تطبيقها باستخدام لغات تدعم multiple inheritance كلغة C++ ويكون شكل Digram كالتالي: إلى هنا, هذا ما كان في الجعبة ووفق الله الجميع وصلى الله وسلم وبارك المراجع: - sourcemaking.com/design_patterns - java design pattern , rohit joshi - head first design pattern
  3. بسم الله الرحمن الرحيم استكمالا للحديث عن أكثر Design pattern استخداما في بيئة Android, وبعد أن كنا قد بدأنا في الحديث عن أنواع Structural pattern, اليوم سيكون حديثنا عن Facade Pattern, فنبدأ بالسؤال المعتاد ماهو Facade Pattern؟ لنبدأ بتعريفه: إذا فهو Pattern يستخدم لتبسيط interfacees لأجزاء النظام, الصورة التالية ستكون شارحة جدا لوظيفة واّلية عمل هذا Pattern. جميل جدا, أعتقد أن المفهوم بات متضحاً جدا, فلندلف إلى تطبيقه بالمثال التالي. لتعلم أنه Pattern بسيط وواضح جدا, فلو فرضنا أن لدينا interface اسمه line, ولديه three claases قاموا بعمل implementation لهذا interface. وهم straight و curve و snaky. public interface Line { void draw(); } class straight public class Straight implements Line { @Override public void draw() { System.out.println("straight"); } } class curve public class Curve implements Line { @Override public void draw() { System.out.println("curve"); } } snaky class public class Snaky implements Line { @Override public void draw() { System.out.println("snaky"); } } أصبح لدينا مجموعة من classes, لو كان النظام الذي سنقوم ببنائه أكبر من ذلك سيكون من الصعب جدا تذكر هذه classes, لذلك سنقوم ببناء Facade class يحل هذه المشكلة ويبسط التعامل معها. public class LineMaker { private Line straight; private Line curve; private Line snaky; public LineMaker() { straight = new Straight(); curve = new Curve(); snaky = new Snaky(); } public void drawStraight(){ straight.draw(); } public void drawCurve(){ curve.draw(); } public void drawSnaky(){ snaky.draw(); } } أصبح التعامل هذه المجموعة من classes غاية في البساطة ويمكن التعامل معها في main كالتالي public static void main(String[] args) { LineMaker lineMaker = new LineMaker(); lineMaker.drawStraight(); lineMaker.drawCurve(); lineMaker.drawSnaky(); } } بينما لو لم نقم باستخدام facade class سيكون شكل main كالتالي: public static void main(String[] args) { private Line straight = new Straight(); private Line curve = new Curve(); private Line snaky = new Snaky(); straight.drawStraight(); curve.drawCurve(); snaky.drawSnaky(); } } طبعا هذا المثال يبسط المشكلة لكن في حال كان حجم النظام كبير ستواجه مشكلة في التعامل مع هذه الكمية من classes. وصلى الله وسلم وبارك على نبينا محمد وعلى اّله وصحبه أجمعين. المراجع: - sourcemaking.com/design_patterns - java design pattern , rohit joshi - head first design pattern - tutorialspoint.com
  4. بسم الله الرحمن الرحيم كما ما بدأناه بالحديث عن أكثر Design pattern استخداما في بيئة Android واليوم سنتحدث عن أحد أنواع Structural pattern , ألا وهو Adapter pattern ,قبل أن نبدأ, وبما أننا في أول pattern في هذه السلسة من نوع Structural فماذا نعني ب Structural pattern ؟ Structural pattern : هو تصميم للكود بطرق تسهل فهم العلاقة بين classes و objects والربط بينها. جميل جدا, إذا ماهو Adapter pattern ؟ من كتاب GoF ولتبسيط الأمور, هذا pattern يستخدم لربط بين two classes لا يمكن الربط بينهما لعدم التوافق. كثيراً ما تكون التعريفات غير مفيدة, لنبدأ بكتابة بعض الأكواد تشرح هذا pattern. بداية دعنا نعرف المشكلة, لو فرضنا أن لديك class قديم قمت ببنائه, ومن ثم اردت الربط بينه وبين class جديد فلن تقوم بإعادة كتابته, وإنما تقوم ببناء interface يقوم بالربط بينهم كما سنقوم بذالك في المثال التالي. لنفترض أن لدينا نظام إدارة فصول إلكتروني, وأردنا ربطه مع نظام حضور وانصراف جديد,فكان شكل interface الخاص بنا كالتالي. public interface Xattendance { public String getStuedntName(); public long getStuedntId() ; public String getTime(); public void setStuedntName(String stuedntName); public void setStuedntId(long stuedntId); public void setTime(String time); } ثم قمنا بعمل implementation له داخل هذا class public class XattendanceImpl implements Xattendance{ String stuedntName; long stuedntId; String time; public String getStuedntName() { return stuedntName; } public void setStuedntName(String stuedntName) { this.stuedntName = stuedntName; } public long getStuedntId() { return stuedntId; } public void setStuedntId(long stuedntId) { this.stuedntId = stuedntId; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } } ولكن وقع الإشكال عندما أردنا ربط هذا class الخاص بنا نظام لتحضير والذي كان شكل interface الخاص به كالتالي: public interface XnewAttendaceSystem { public String getName() ; public void setName(String name); public String getId(); public void setId(String id); public String getMinute(); public void setMinute(String minute); public String getHour(); public void setHour(String hour); } وclass الذي سيقوم بعمل implementation له بهذا الشكل public class XnewAttendaceSystemImpl implements XnewAttendaceSystem{ String name; String id; String minute; String hour; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getMinute() { return minute; } public void setMinute(String minute) { this.minute = minute; } public String getHour() { return hour; } public void setHour(String hour) { this.hour = hour; } } فكما ترى لدينا two classes من نوعين مختلفين, فيلزمنا إنشاء class لنسميه المحول, حيث يمكننا عن طريقه ربط two classes مع بعضهما. وهو يقوم بعمل implementation ل XnewAttendaceSystem وفي constructor يستقبل object من نوع Xattendance ويقوم بالتحويل public class fromOldClassToNewSystem implements XnewAttendaceSystem{ String name; String id; String minute; String hour; final Xattendance xattendance; public fromOldClassToNewSystem(Xattendance xattendance) { this.xattendance = xattendance; adapt(); } @Override public String getName() { return this.name; } @Override public void setName(String name) { this.name = name; } @Override public String getId() { return this.id; } @Override public void setId(String id) { this.id = id; } @Override public String getMinute() { return this.minute; } @Override public void setMinute(String minute) { this.minute = minute; } @Override public String getHour() { return this.hour; } @Override public void setHour(String hour) { this.hour = hour; } public void adapt(){ setName(xattendance.getStuedntName()); setId(xattendance.getStuedntName()); setHour(xattendance.getTime().substring(0, 1)); setMinute(xattendance.getTime().substring(3, 4)); } } فكما ترى تم تحويل object من نوع إلى أخر, فدعنا نلقي نظرة عن طريقة استخدم هذا pattern. سنقوم بإنشاء بيانات نقوم نحن بكتابتها- من الممكن أن تكون البيانات قادمة من API أو من Database, ولكن هنا لتبسيط المقالة ستكون مكتوبة يدوياً- ومن ثم نحولها من النظام الخاص فينا, إلى النظام الذي قمنا بالربط معه. public static void main(String[] args) { Xattendance x = new XattendanceImpl(); x.setStuedntId(10110101); x.setStuedntName("ameen"); x.setTime("12:30"); XnewAttendaceSystem obj = new fromOldClassToNewSystem(x); //test System.out.println(obj.getName()); System.out.println(obj.getHour()); } وبهذا نلاحظ أنه تم إرسال البيانات من نظام إلى أخر باستخدام adapter pattern. ختاما لتعلم أن لدينا نوعان من adapter الأول هو object adapter وهو الذي تعاملنا معه في المثال اّنف الذكر, والذي استخدمنا في بنائه مبدأ composition, والأخر هو adapter class والذي يعتمد في بنائه على multiple inheritance وهو غير مدعوم في java تجنباً لمشكلة DDD (deadly diamond of death), ولكن يمكنك تطبيقها باستخدام لغات تدعم multiple inheritance كلغة C++ ويكون شكل Digram كالتالي: إلى هنا, هذا ما كان في الجعبة ووفق الله الجميع وصلى الله وسلم وبارك المراجع: - sourcemaking.com/design_patterns - java design pattern , rohit joshi - head first design pattern
  5. Builder Design pattern

    بسم الله الرحمن الرحيم نكمل ما بدأناه بالحديث عن أكثر Design pattern استخداما في بيئة Android واليوم نتم الحديث عن Creational patterns بعد تكلمنا عن Singleton و dependency injection اليوم سكون حديثنا عن Builder Design patterns نقتبس التعريف من كتاب GoF جميل جداً كما ذكر في التعريف إذ أننا سنقوم بتقسيم بناء Object إلى عدة method نبدء بالأساسية التي لا يمكن التعامل مع Object بدونها, ثم ننتقل إلى الاختيارية حتى نتم بناء Object على الوجه الذي نريد. لنبدأ بمثال يوضح المشكلة . لنفترض أننا نريد إنشاء class لفريق معين كالتالي : public class Player { private String name ; private String team ; private double height ; private int salary ; private String phone ; private String twitterAccount ; public Player(String name, String team, double height, int salary, String phone, String twitterAccount) { this.name = name; this.team = team; this.height = height; this.salary = salary; this.phone = phone; this.twitterAccount = twitterAccount; } } نحن هنا نتعامل مع six class data member فقط فلو فرضنا أن لدينا 10 فسيكون شكل constructor رهيب جدا وفي هذا عدة مشاكل منها أنك لن تستطيع تذكر أماكن data member في constructor مما يسبب في وضع البيانات في غير مكانها وستحصل على نتائج غريبة قد لا يصنفها compiler ك Error ولتلافي هذه المشكلة سنستعرض أحد الحلول وهو Telescopin Design Pattern حيث سنقوم بكتابة شكل constructor فقط public Player(String name, String team) { this(name, team,0.0); } public Player(String name, String team, double height) { this(name, team,height,0); } public Player(String name, String team, double height, int salary) { this(name, team,height,salary,""); } public Player(String name, String team, double height, int salary, String phone) { this(name, team,height,salary,phone,""); } public Player(String name, String team, double height, int salary, String phone, String twitterAccount) { this.name = name; this.team = team; this.height = height; this.salary = salary; this.phone = phone; this.twitterAccount = twitterAccount; } كما تلاحظ نبدأ بالمعلومات الأساسية التي لا يمكن الاستمرار بدونها ثم بعد ذلك نبدأ بتوفير البيانات في حال كانت لدينا أو نسند قيم افتراضية. ولهذه الطريقة عيوبها أولا صعوبة قراءة code وأيضا صعوبة في كتابة client code (إنشاء object ), بالإضافة إلى أنك قد تجبر على كتابة parameters التي لا تريد كتابتها. لهذه قد يكون استخدام Telescopin ليس الحل المناسب, لكن يوجد حل أخر لنأخذ فرصة في تجربته ألا وهو javaBeans Pattern , لنطبقه على نفس المثال السابق. public Player() {} public void setName(String name) { this.name = name; } public void setTeam(String team) { this.team = team; } public void setHeight(double height) { this.height = height; } public void setSalary(int salary) { this.salary = salary; } public void setPhone(String phone) { this.phone = phone; } public void setTwitterAccount(String twitterAccount) { this.twitterAccount = twitterAccount; } فكما ترى نبدأ ب constructor وبعد ذلك setters بعدد data members , وهذا الحل يحل بعض الإشكالات السابقة ويخلق إشكالات جديدة, فأولا سيكون إنشاء Object مرتبط بعدد كبير من method التي يجب استدعاؤها وتذكرها بالإضافة إلى أنه لا يمكنك جعل class immutable, وليس thread safe, فتجازونا بعض إشكالات Telescopin ووقعنا في إشكالات أخرى ,فسنجمع بينهم في Patterm وهو Builder Design Pattern. لنعيد كتابة constructor بإستخدام نفس المثال public class Player { private String name ; private String team ; private double height ; private int salary ; private String phone ; private String twitterAccount ; public static class Builder { private final String name ; private final String team ; private double height = 0; private int salary = 0; private String phone = ""; private String twitterAccount = ""; public Builder(String name, String team) { this.name = name; this.team = team; } public Builder height(double height) { this.height = height; return this ; } public Builder salary(int salary) { this.salary = salary; return this ; } public Builder phone(String phone) { this.phone = phone; return this ; } public Builder twitterAccount(String twitterAccount) { this.twitterAccount = twitterAccount; return this ; } public Player build(){ return new Player(this); } } public Player(Builder builder) { name = builder.name; team = builder.team; height = builder.height; salary = builder.salary;; phone = builder.phone;; twitterAccount = builder.twitterAccount; } } في البداية قمنا ببناء inner class سميناه Builder حيث سنقوم بداخله ببناء Object الخاص بنا وبعد ذلك نرجعه عن طريق دالة build التي تقوم بعمل return ل object الذي قمنا ببناءه, نبدأ بالمتغيرات الأساسية في Object وهي التي كانت final ولا تأخذ قيم افتراضية, ثم الاختيارية التي قد نستخدمها فنستدعي method الخاصة بها, أو لا نستخدمها فنسند فيه القيم الافتراضية, فيكون شكل client كالتالي Player player = new Player.Builder("Aziz", "Android") .height(10.2) .phone("0555555555") .salary(100) .build(); كما نلاحظ قمنا بكتابة client سهل القراءة وحتى الكتابة, ومرن وبسيط جدا. اذا ف Builder Pattern خيار جيد جداً حينما يكون عدد Parameters ليس بالقليل ويكون فيه عدد من Parameters اختيارية المراجع ومصادر : Effective Java (2nd Edition) https://sourcemaking.com/design_patterns/builder http://www.blackwasp.co.uk/gofpatterns.aspx
  6. بسم الله الرحمن الرحيم نكمل ما بدأناه بالحديث عن أكثر Design Batterns استخداما في بيئة Android واليوم نتم الحديث عن Creational patterns بعد تكلمنا عن Singleton و dependency injection اليوم سكون حديثنا عن Builder Design Battern نقتبس التعريف من كتاب GoF جميل جداً كما ذكر في التعريف إذ أننا سنقوم بتقسيم بناء Object إلى عدة method نبدء بالأساسية التي لا يمكن التعامل مع Object بدونها, ثم ننتقل إلى الاختيارية حتى نتم بناء Object على الوجه الذي نريد. لنبدأ بمثال يوضح المشكلة . لنفترض أننا نريد إنشاء class لفريق معين كالتالي : public class Player { private String name ; private String team ; private double height ; private int salary ; private String phone ; private String twitterAccount ; public Player(String name, String team, double height, int salary, String phone, String twitterAccount) { this.name = name; this.team = team; this.height = height; this.salary = salary; this.phone = phone; this.twitterAccount = twitterAccount; } } نحن هنا نتعامل مع six class data member فقط فلو فرضنا أن لدينا 10 فسيكون شكل constructor رهيب جدا وفي هذا عدة مشاكل منها أنك لن تستطيع تذكر أماكن data member في constructor مما يسبب في وضع البيانات في غير مكانها وستحصل على نتائج غريبة قد لا يصنفها compiler ك Error ولتلافي هذه المشكلة سنستعرض أحد الحلول وهو Telescopin Design Pattern حيث سنقوم بكتابة شكل constructor فقط public Player(String name, String team) { this(name, team,0.0); } public Player(String name, String team, double height) { this(name, team,height,0); } public Player(String name, String team, double height, int salary) { this(name, team,height,salary,""); } public Player(String name, String team, double height, int salary, String phone) { this(name, team,height,salary,phone,""); } public Player(String name, String team, double height, int salary, String phone, String twitterAccount) { this.name = name; this.team = team; this.height = height; this.salary = salary; this.phone = phone; this.twitterAccount = twitterAccount; } كما تلاحظ نبدأ بالمعلومات الأساسية التي لا يمكن الاستمرار بدونها ثم بعد ذلك نبدأ بتوفير البيانات في حال كانت لدينا أو نسند قيم افتراضية. ولهذه الطريقة عيوبها أولا صعوبة قراءة code وأيضا صعوبة في كتابة client code (إنشاء object ), بالإضافة إلى أنك قد تجبر على كتابة parameters التي لا تريد كتابتها. لهذه قد يكون استخدام Telescopin ليس الحل المناسب, لكن يوجد حل أخر لنأخذ فرصة في تجربته ألا وهو javaBeans Pattern , لنطبقه على نفس المثال السابق. public Player() {} public void setName(String name) { this.name = name; } public void setTeam(String team) { this.team = team; } public void setHeight(double height) { this.height = height; } public void setSalary(int salary) { this.salary = salary; } public void setPhone(String phone) { this.phone = phone; } public void setTwitterAccount(String twitterAccount) { this.twitterAccount = twitterAccount; } فكما ترى نبدأ ب constructor وبعد ذلك setters بعدد data members , وهذا الحل يحل بعض الإشكالات السابقة ويخلق إشكالات جديدة, فأولا سيكون إنشاء Object مرتبط بعدد كبير من method التي يجب استدعاؤها وتذكرها بالإضافة إلى أنه لا يمكنك جعل class immutable, وليس thread safe, فتجازونا بعض إشكالات Telescopin ووقعنا في إشكالات أخرى ,فسنجمع بينهم في Patterm وهو Builder Design Pattern. لنعيد كتابة constructor بإستخدام نفس المثال public class Player { private String name ; private String team ; private double height ; private int salary ; private String phone ; private String twitterAccount ; public static class Builder { private final String name ; private final String team ; private double height = 0; private int salary = 0; private String phone = ""; private String twitterAccount = ""; public Builder(String name, String team) { this.name = name; this.team = team; } public Builder height(double height) { this.height = height; return this ; } public Builder salary(int salary) { this.salary = salary; return this ; } public Builder phone(String phone) { this.phone = phone; return this ; } public Builder twitterAccount(String twitterAccount) { this.twitterAccount = twitterAccount; return this ; } public Player build(){ return new Player(this); } } public Player(Builder builder) { name = builder.name; team = builder.team; height = builder.height; salary = builder.salary;; phone = builder.phone;; twitterAccount = builder.twitterAccount; } } في البداية قمنا ببناء inner class سميناه Builder حيث سنقوم بداخله ببناء Object الخاص بنا وبعد ذلك نرجعه عن طريق دالة build التي تقوم بعمل return ل object الذي قمنا ببناءه, نبدأ بالمتغيرات الأساسية في Object وهي التي كانت final ولا تأخذ قيم افتراضية, ثم الاختيارية التي قد نستخدمها فنستدعي method الخاصة بها, أو لا نستخدمها فنسند فيه القيم الافتراضية, فيكون شكل client كالتالي Player player = new Player.Builder("Aziz", "Android") .height(10.2) .phone("0555555555") .salary(100) .build(); كما نلاحظ قمنا بكتابة client سهل القراءة وحتى الكتابة, ومرن وبسيط جدا. اذا ف Builder Pattern خيار جيد جداً حينما يكون عدد Parameters ليس بالقليل ويكون فيه عدد من Parameters اختيارية المراجع ومصادر : Effective Java (2nd Edition) https://sourcemaking.com/design_patterns/builder http://www.blackwasp.co.uk/gofpatterns.aspx تم ترقية هذا الطرح المميز الى صفحة المقالات
  7. Dependency Injection Design Pattern

    بسم الله الرحمن الرحيم نكمل ما بدأنا به في شرح design pattern الأكثر استخداما في بيئة Android اليوم بإذن الله سيكون حديثنا عن مفهوم Dependency Injection. تعريف wikipedia فما هو Inversion of Control ؟ التعريف من wikipedia أيضا قد تكون عملية الترجمة غير مجدية أو أن التعريفات ليست واضحة عموما بإذن الله سنفصل الموضوع تفصيلا بسيطاً يجعله واضحا بإذن الله. ببساطة مفهوما Dependency Injection و Inversion of Control (IoC) بدون الخوض في التفاصيل تعنى بحذف dependencies من code ماذا نعني ب dependencies (الاعتمادية) ؟ خذ هذا المثال public class MSWord { private ErrorCorrection corrector; public MSWord() { this.corrector = new ErrorCorrection(); } } نلاحظ أنه لكي أقوم بإنشاء Object من class MSWrod فأنا مضطر لإنشاء Object من class ErrorCorrection ونقطة الاعتمادية هنا هي إنشاء Object لكي تقوم بتنفيذ Dependency Injection لابد أن تعمل Inject (حقن) object بحيث يأتي إلى class ك parameter مبني, فتتم عملية الإسناد فقط بالمثال يتضح المقال, فهذه مثال ننفذ فيه Dependency Injection على نفس code السابق public class MSWord { private ErrorCorrection corrector; public MSWord(ErrorCorrection corrector) { this.corrector = corrector; } } ففي Main أو مكان تنفيذ code ستقوم بالتالي public static void main(String[] args) { ErrorCorrection corrector = new ErrorCorrection() MSWord word = new MSWord(corrector); } جميل جدا, الأمر نفسه بتمرير dependencies ك parameter سواء كان في constructor أو method, يأتي السؤال الأهم لماذا أستخدم هذا pattern ؟ لنفترض أن لدينا class A ولديه subclass B ويحتاج object من class C public class C { String s ; C(String s){ this.s = s ; } } public class A { private C c ; A(String s){ this.c = new C(s); } } public class B extends A{ B(String s){ super(s); } } جميل, في حال تم تغيير constructor في class C فأنت مضطر لتغيير constructor في class A وجميع من يرث منه, فلو قلنا فرضاً أننا قررنا إضافة Strimg أخر لدى C public class C { String s ,s1; C(String s ,String s1 ){ this.s = s ; this.s1 = s1 ; } } public class A { private C c ; A(String s,String s1){ this.c = new C(s,s1); } } public class B extends A{ B(String s,String s1){ super(s,s1); } } فكما ترى اضطررنا لتغيير جميع classes نظرا لأننا غيرنا في class يعتمدون عليه, لكن ماذا لو طبقنا Dependency Injection على هؤلاء classes public class C { String s ; C(String s){ this.s = s ; } } public class A { private C c ; A(C c){ this.c = c ; } } public class B extends A{ B(C c){ super(c); } } لنغير في C و constructor الخاص بها ونرى ماذا يحدث. public class C { String s ,s1; C(String s,String s1){ this.s = s ; this.s1 = s1 ; } } public class A { private C c ; A(C c){ this.c = c ; } } public class B extends A{ B(C c){ super(c); } } نلاحظ الفائدة Dependency Injection حيث أن التغيير تم في مكان واحد فقط. من فوائد Dependency Injection له فوائد جدا كثيرة ستلاحظها أثناء الكتابة أو حين تقرأ عنه ومنها - قابلية التعديل - maintainability - قابلية الاختبار - testability - قابلية الاستفادة من نفس code عوضاً عن إعادة كتابته - reusability - بالإضافة إلى أنه يقلل من coupling في code للاستزادة هنا بعض المراجع التي قرأت منها وفيها الكثير من المعلومات التي فضلت عدم إيرادها لجعل الموضوع أكثر بساطة https://en.wikipedia.org/wiki/Dependency_injection http://frogermcs.github.io/dependency-injection-with-dagger-2-introdution-to-di/ http://stackoverflow.com/questions/3058/what-is-inversion-of-control
  8. بسم الله الرحمن الرحيم نكمل ما بدأنا به في شرح design pattern الأكثر استخداما في بيئة Android اليوم بإذن الله سيكون حديثنا عن مفهوم Dependency Injection. تعريف wikipedia فما هو Inversion of Control ؟ التعريف من wikipedia أيضا قد تكون عملية الترجمة غير مجدية أو أن التعريفات ليست واضحة عموما بإذن الله سنفصل الموضوع تفصيلا بسيطاً يجعله واضحا بإذن الله. ببساطة مفهوما Dependency Injection و Inversion of Control (IoC) بدون الخوض في التفاصيل تعنى بحذف dependencies من code ماذا نعني ب dependencies (الاعتمادية) ؟ خذ هذا المثال public class MSWord { private ErrorCorrection corrector; public MSWord() { this.corrector = new ErrorCorrection(); } } نلاحظ أنه لكي أقوم بإنشاء Object من class MSWrod فأنا مضطر لإنشاء Object من class ErrorCorrection ونقطة الاعتمادية هنا هي إنشاء Object لكي تقوم بتنفيذ Dependency Injection لابد أن تعمل Inject (حقن) object بحيث يأتي إلى class ك parameter مبني, فتتم عملية الإسناد فقط بالمثال يتضح المقال, فهذه مثال ننفذ فيه Dependency Injection على نفس code السابق public class MSWord { private ErrorCorrection corrector; public MSWord(ErrorCorrection corrector) { this.corrector = corrector; } } ففي Main أو مكان تنفيذ code ستقوم بالتالي public static void main(String[] args) { ErrorCorrection corrector = new ErrorCorrection() MSWord word = new MSWord(corrector); } جميل جدا, الأمر نفسه بتمرير dependencies ك parameter سواء كان في constructor أو method, يأتي السؤال الأهم لماذا أستخدم هذا pattern ؟ لنفترض أن لدينا class A ولديه subclass B ويحتاج object من class C public class C { String s ; C(String s){ this.s = s ; } } public class A { private C c ; A(String s){ this.c = new C(s); } } public class B extends A{ B(String s){ super(s); } } جميل, في حال تم تغيير constructor في class C فأنت مضطر لتغيير constructor في class A وجميع من يرث منه, فلو قلنا فرضاً أننا قررنا إضافة Strimg أخر لدى C public class C { String s ,s1; C(String s ,String s1 ){ this.s = s ; this.s1 = s1 ; } } public class A { private C c ; A(String s,String s1){ this.c = new C(s,s1); } } public class B extends A{ B(String s,String s1){ super(s,s1); } } فكما ترى اضطررنا لتغيير جميع classes نظرا لأننا غيرنا في class يعتمدون عليه, لكن ماذا لو طبقنا Dependency Injection على هؤلاء classes public class C { String s ; C(String s){ this.s = s ; } } public class A { private C c ; A(C c){ this.c = c ; } } public class B extends A{ B(C c){ super(c); } } لنغير في C و constructor الخاص بها ونرى ماذا يحدث. public class C { String s ,s1; C(String s,String s1){ this.s = s ; this.s1 = s1 ; } } public class A { private C c ; A(C c){ this.c = c ; } } public class B extends A{ B(C c){ super(c); } } نلاحظ الفائدة Dependency Injection حيث أن التغيير تم في مكان واحد فقط. من فوائد Dependency Injection له فوائد جدا كثيرة ستلاحظها أثناء الكتابة أو حين تقرأ عنه ومنها - قابلية التعديل - maintainability - قابلية الاختبار - testability - قابلية الاستفادة من نفس code عوضاً عن إعادة كتابته - reusability - بالإضافة إلى أنه يقلل من coupling في code للاستزادة هنا بعض المراجع التي قرأت منها وفيها الكثير من المعلومات التي فضلت عدم إيرادها لجعل الموضوع أكثر بساطة https://en.wikipedia.org/wiki/Dependency_injection http://frogermcs.github.io/dependency-injection-with-dagger-2-introdution-to-di/ http://stackoverflow.com/questions/3058/what-is-inversion-of-control تم ترقية هذا الطرح المميز الى صفحة المقالات
  9. Observer Design Pattern - ماهو

    بسم الله الرحمن الرحيم بإذن الله ستكون هذه المقالة بداية لسلسلة من المقالات المتعلقة ب Design Patterns الأكثر أستخداما في بيئة Android. ونستهل هذه السلسلة ب Observer Design Pattern أو ما يسمى ب Publish-Subscribe (Pub-Sub) Pattern. في تعريف هذا Pattern في كتاب GoF : ولتبسيط التعريف نقول : عندما تريد تنبيه أو تحديث مجموعة objects عن حدوث تغيير في object أخر جميل جداً, دعنا نضرب مثالاً قبل أن نبدأ. - لدينا مدونة تنشر مقالات. - قمت أنت بالأشتراك في قائمة تقوم بتنبيهك في حال صدرت أي مقالة. - لم تعد مهتما بالمجال الذي تكتب هذه المدونة عنه, قمت بإلغاء الإشتراك منها. - قام مجموعة من أصدقائك بالإشتراك وإلغاء الإشتراك. المثال السابق هو ملخص لما للكود الذي سنقوم بكتابته في حال فهمك إياه فأنت قطعت شوط كبير في فهم هذا Design Pattern . بداية هذا هو UML الخاص بالكود الذي سنكتبه الان, سيتضح أكثر بعد كتابه الكود. جميل الان لنبدأ في كتابة الكود في البداية لدينا two interfaces الأول هو subjuct أو يمكنك أن تسميه puplisher والثاني observer أو يمكنك أن تسميه subscriber - إذا لم تكن تستخدم intrtfaces أثناء كتابتك لبرامجك فقد وضعت مرجع قد يفيدك في نهاية المقالة لمعرفة أهمية وأليه استخدام interfaces- public interface Subject { void addObserver(Observer o); void removeObserver(Observer o); void notifyObservers(); public void setUpdate(String article); public String getUpdate(); } public interface Observer { void Update (); } ليس هناك الكثير من التفاصيل في إنشاء هذين interfaces لكن سنبدأ في التعليق عند مرحلة implementation دعنا نبدأ ب subjuct ونسوي له implementation في class Publisher public class Publisher implements Subject{ private List <Observer> observers ; String article; public Publisher() { observers = new ArrayList<>(); } @Override public void addObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { observers.remove(o); } @Override public void notifyObservers() { for(Observer ob : observers) ob.Update(); } @Override public String getUpdate() { return article; } @Override public void setUpdate(String article) { this.article = article ; notifyObservers(); } } في البداية قمنا بإنشاء List نستطيع أن نسميها قائمة المشتركين في هذا class الذي أفترضنا أنه مدونة لنشر المقالات, ومتغير String والذي هو عبارة عن المقالة التي نريد تنبيه متابعينا حال صدورها. لدينا ثلاث functions رئيسية لا يكاد يخلو Observer Design Pattern منها وهي : addObserver : ﻷضافة متابع جديد لهذا class أو كما يحلو لنا أن نسميه المدون removeObserver : لحذف متابع notifyObservers : لتنبيه المتابعين ونشر المقالة لهم ,وقد تختلف تصرفاتهم عندما يأتيهم التنبيه منهم يبدأ بقر ائتها أو إهمالهما أو حفظها لديه لغرض معين أو غير ذلك. لننتقل الان ل classes التي قامت بعمل implementation ل Observer وهم لا يختلفون كثيرا في implementation public class Reader implements Observer{ private String article ; private Subject sub ; public Reader(Subject blog) { article = "" ; sub = blog ; sub.addObserver(this); } @Override public void Update() { article = sub.getUpdate(); System.out.println("You :"+article); } } public class Reader implements Observer{ private String article ; private Subject sub ; public Reader(Subject blog) { article = "" ; sub = blog ; sub.addObserver(this); } @Override public void Update() { article = sub.getUpdate(); System.out.println("You :"+article); } } class reader والذي افترضت حين بدأت بكتابة المقالة أنه أنت , وclass الأخر هو Friend والذي افترضت أنه صديقك كما تلاحظون في كلا classes قمنا بعمل Override ل update تحضر المقالة و تقرأها, وفي داخل Constructor قمنا بإنشاء المتغيرات الخاصة بنا والانضمام إلى List المتابعين الخاصين بالمدونة public class PupSub { public static void main(String[] args) { // TODO code application logic here Publisher pup = new Publisher(); new Reader(pup); new Friend(pup); pup.setUpdate("Art1"); pup.setUpdate("Art2"); pup.setUpdate("Art3"); } } في البداية قمنا بإنشاء قائمة المتابعين الخاصة بالمدونة وكانت فارغة قم أنشأنا متابع من Reader class والذي سبق وافترضنا أنه أنت, ثم Friend class والذي هو صديقك. كلاكما متابع لهذه المدونة والمدون قد وضعكما في قائمته ويقوم بإخباركم عن كل جديد في هذه المدونة فور وصوله وأنتما تقومان بقراءة ما يأتيكما فور ما يأتي. ثم نشر المدون ثلاث تدوينات عبر setUpdate التي تستدعي notifyObservers ثم تقوم هذه function باستدعاء Update الخاصة بكل class من المتابعين ويقومون بدورهم بتحديث التدوينات التي لديهم عن طريق استداعاء getUpdate الخاصة بالمدون. قد تجد صعوبة في فهم هذا Pattern وغيره في المرة الأولى وهذا طبيعي. عليك تطبيقة وفهم أجزاءه وبعد ذلك سيتضح لك. وأخيرا, لماذا أستخدم Observer Design Pattern ؟ Observer Design Pattern يقلل من التداخل في الكود-Low Coupling- وهذا سيسهل عليك في حال رغبت في إضافة classes أو إزالتها, فجميع classes تعمل بشكل مستقل عن بعضها . المراجع: - http://informatic-ar.com/ال-coupling-وال-cohesion-في-تصميم-البرمجيات/ - https://sourcemaking.com/design_patterns/observer - Head First Design Patterns - البرمجة باستخدام Interfaces
  10. Singleton pattern في java و android

    بسم الله الرحمن الرحيم نكمل ما بدأناه في الحديث عن design pattern التي يكثر استخدامها في بيئة android اليوم سيكون حديثنا عن Singleton هذا pattern يصنف ضمن Creational Patterns والتي تهتم بطرق إنشاء objct أو مجموعة objects والعلاقات التي بينها في حال كان لدينا أكثر من object. ونبدأ بتعريف هذا Pattern من كتاب GoF : إذا في Singleton يجعلك متأكدا من أن class الذي بنيته باستخدام هذا pattern انشأ منه object اوحد فقط . وأول ما يخطر في بالك في حال كنت جديدا على هذا النمط, لماذا object اوحد فقط ؟ سيكون الجواب في نهاية المقالة بإذن الله بداية سنبدأ بكتابة مثال بسيط على Singleton pattern بلغة java public class Singleton { private static Singleton singleton = null ; private Singleton() {} public static Singleton getSingleton() { if (singleton == null) singleton = new Singleton(); return singleton; } } يبدو واضحا من الوهلة الأولى أن class انف الذكر لا يمكن إنشاء أكثر من object منه. في private Constructor لا تقوم بإنشاء أي object كما أن data member التي لديك static لكنها private بمعنى لديك static data member لا تستطيع الوصول إليه إلا عن طريق method داخل class وهذه method تقوم بالتأكد فيما إذا كان لديك object تم إنشاؤه, والذي لن ينشأ غيره. لكن في الحقيقة لو استخدمنا نفس هذا implementation في multithreading فقد ينشأ أكثر من object, فلمنع هذا حدوث هذه المشكلة لدينا أكثر من حل,فمثلا نستخدم synchronized keyword والتي ستعمل فقط مع thread واحده في نفس الوقت, لتفادي إنشاء أكثر من instance - وقد لا يكون أفضل حل- قدد تتعدد طرق implementation ولكن تشترك في شيء واحد وهو أنه لا يمكن أنشاء أكثر من object من هذا class طيب جميل جداً لان لنطبق هذا pattern على Android سنقوم بالتالي بناء دالة تتأكد من حالة network وترجع true في حال كان هناك اتصال وError في حال لم يكن. ConnectivityManager cm = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); if(info != null && info.isConnectedOrConnecting() && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting()){ //your code } ستكرر هذه code في كل مكان تنوي فيه التحقق من حالة الشبكة,, وعندما تكرر code فيعتبر إشكال في تصميمه. إذا ماذا سنفعل ؟ سنقوم بالتالي بناء App class , وهو class على مستوى التطبيق بمعنى يمكن لأي جزء من تطبيق أن يصل إليه, كيف ؟ يكون لدينا class فيه static method لكل object لا نحتاج لتكراره في code ومن ثم نستدعيه عن طريق class . مثال public static boolean NetworkState(Context context){ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); return info != null && info.isConnectedOrConnecting() && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting(); } في هذه الحالة يمكننا التحقق من حالة network بهذه الطريقة if(Application.NetworkState(Context context)){ //your code } وهذا يمنحنا ميزة سهولة التعديل maintainable في حال أردنا تغيير طريقة عمل function كإظهار تنبيه معين. وقس على ذلك من المزايا , كما أن هذا المثال يمكن استخدامه مع عدد كبير من الحالات كإنشاء object من مكتبة retrofit والوصول له من أي مكان على مسوى التطبيق. لا ينبغي عمل subclass ل Singleton class حيث سيتوجب عليك جعل Constructor public وبعد هذا التغيير لم يعد class يسمى Singleton حيث يمكن إنشاء instance منه. بالإضافة إلى أنك قد تكون جعلت static data member مما يعني أن subclass سيكون مشترك مع superclass في نفس data member وقد يؤدي إلى نتائج غير مرغوب فيها غالبا. نجيب على التساؤل الذي طرحناه في بداية المقالة لماذا object اوحد فقط ؟ أتضح ولو بشكل جزئي من الأمثلة التي ذكرناها في بداية المقالة بعض فوائد Singleton, وهو أنه ستمر بك بعض الحالات لا تريد فيها أكثر من object وحيد تتعامل معه ومن هذه الحالات Toast كما ذكرنا ,و thread pools و caches و logging والقائمة تطول, فمتى ما رأيت أن class فيه static class or data member هي التي تحتاجها فقط فسيكون Singleton حل مناسب لك. المراجع: Head First Design Patterns http://www.javaworld.com/article/2073352/core-java/simply-singleton.html http://www.blackwasp.co.uk/gofpatterns.aspx http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples
  11. بسم الله الرحمن الرحيم نكمل ما بدأناه في الحديث عن design pattern التي يكثر استخدامها في بيئة android اليوم سيكون حديثنا عن Singleton هذا pattern يصنف ضمن Creational Patterns والتي تهتم بطرق إنشاء objct أو مجموعة objects والعلاقات التي بينها في حال كان لدينا أكثر من object. ونبدأ بتعريف هذا Pattern من كتاب GoF : إذا في Singleton يجعلك متأكدا من أن class الذي بنيته باستخدام هذا pattern انشأ منه object اوحد فقط . وأول ما يخطر في بالك في حال كنت جديدا على هذا النمط, لماذا object اوحد فقط ؟ سيكون الجواب في نهاية المقالة بإذن الله بداية سنبدأ بكتابة مثال بسيط على Singleton pattern بلغة java public class Singleton { private static Singleton singleton = null ; private Singleton() {} public static Singleton getSingleton() { if (singleton == null) singleton = new Singleton(); return singleton; } } يبدو واضحا من الوهلة الأولى أن class انف الذكر لا يمكن إنشاء أكثر من object منه. في private Constructor لا تقوم بإنشاء أي object كما أن data member التي لديك static لكنها private بمعنى لديك static data member لا تستطيع الوصول إليه إلا عن طريق method داخل class وهذه method تقوم بالتأكد فيما إذا كان لديك object تم إنشاؤه, والذي لن ينشأ غيره. لكن في الحقيقة لو استخدمنا نفس هذا implementation في multithreading فقد ينشأ أكثر من object, فلمنع هذا حدوث هذه المشكلة لدينا أكثر من حل,فمثلا نستخدم synchronized keyword والتي ستعمل فقط مع thread واحده في نفس الوقت, لتفادي إنشاء أكثر من instance - وقد لا يكون أفضل حل- قدد تتعدد طرق implementation ولكن تشترك في شيء واحد وهو أنه لا يمكن أنشاء أكثر من object من هذا class طيب جميل جداً لان لنطبق هذا pattern على Android سنقوم بالتالي بناء دالة تتأكد من حالة network وترجع true في حال كان هناك اتصال وError في حال لم يكن. ConnectivityManager cm = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); if(info != null && info.isConnectedOrConnecting() && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting()){ //your code } ستكرر هذه code في كل مكان تنوي فيه التحقق من حالة الشبكة,, وعندما تكرر code فيعتبر إشكال في تصميمه. إذا ماذا سنفعل ؟ سنقوم بالتالي بناء App class , وهو class على مستوى التطبيق بمعنى يمكن لأي جزء من تطبيق أن يصل إليه, كيف ؟ يكون لدينا class فيه static method لكل object لا نحتاج لتكراره في code ومن ثم نستدعيه عن طريق class . مثال public static boolean NetworkState(Context context){ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); return info != null && info.isConnectedOrConnecting() && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting(); } في هذه الحالة يمكننا التحقق من حالة network بهذه الطريقة if(Application.NetworkState(Context context)){ //your code } وهذا يمنحنا ميزة سهولة التعديل maintainable في حال أردنا تغيير طريقة عمل function كإظهار تنبيه معين. وقس على ذلك من المزايا , كما أن هذا المثال يمكن استخدامه مع عدد كبير من الحالات كإنشاء object من مكتبة retrofit والوصول له من أي مكان على مسوى التطبيق. لا ينبغي عمل subclass ل Singleton class حيث سيتوجب عليك جعل Constructor public وبعد هذا التغيير لم يعد class يسمى Singleton حيث يمكن إنشاء instance منه. بالإضافة إلى أنك قد تكون جعلت static data member مما يعني أن subclass سيكون مشترك مع superclass في نفس data member وقد يؤدي إلى نتائج غير مرغوب فيها غالبا. نجيب على التساؤل الذي طرحناه في بداية المقالة لماذا object اوحد فقط ؟ أتضح ولو بشكل جزئي من الأمثلة التي ذكرناها في بداية المقالة بعض فوائد Singleton, وهو أنه ستمر بك بعض الحالات لا تريد فيها أكثر من object وحيد تتعامل معه ومن هذه الحالات Toast كما ذكرنا ,و thread pools و caches و logging والقائمة تطول, فمتى ما رأيت أن class فيه static class or data member هي التي تحتاجها فقط فسيكون Singleton حل مناسب لك. المراجع: Head First Design Patterns http://www.javaworld.com/article/2073352/core-java/simply-singleton.html http://www.blackwasp.co.uk/gofpatterns.aspx http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples تم ترقية هذا الطرح المميز الى صفحة المقالات
  12. بسم الله الرحمن الرحيم بإذن الله ستكون هذه المقالة بداية لسلسلة من المقالات المتعلقة ب Design Patterns الأكثر أستخداما في بيئة Android. ونستهل هذه السلسلة ب Observer Design Pattern أو ما يسمى ب Publish-Subscribe (Pub-Sub) Pattern. في تعريف هذا Pattern في كتاب GoF : ولتبسيط التعريف نقول : عندما تريد تنبيه أو تحديث مجموعة objects عن حدوث تغيير في object أخر جميل جداً, دعنا نضرب مثالاً قبل أن نبدأ. - لدينا مدونة تنشر مقالات. - قمت أنت بالأشتراك في قائمة تقوم بتنبيهك في حال صدرت أي مقالة. - لم تعد مهتما بالمجال الذي تكتب هذه المدونة عنه, قمت بإلغاء الإشتراك منها. - قام مجموعة من أصدقائك بالإشتراك وإلغاء الإشتراك. المثال السابق هو ملخص لما للكود الذي سنقوم بكتابته في حال فهمك إياه فأنت قطعت شوط كبير في فهم هذا Design Pattern . بداية هذا هو UML الخاص بالكود الذي سنكتبه الان, سيتضح أكثر بعد كتابه الكود. جميل الان لنبدأ في كتابة الكود في البداية لدينا two interfaces الأول هو subjuct أو يمكنك أن تسميه puplisher والثاني observer أو يمكنك أن تسميه subscriber - إذا لم تكن تستخدم intrtfaces أثناء كتابتك لبرامجك فقد وضعت مرجع قد يفيدك في نهاية المقالة لمعرفة أهمية وأليه استخدام interfaces- public interface Subject { void addObserver(Observer o); void removeObserver(Observer o); void notifyObservers(); public void setUpdate(String article); public String getUpdate(); } public interface Observer { void Update (); } ليس هناك الكثير من التفاصيل في إنشاء هذين interfaces لكن سنبدأ في التعليق عند مرحلة implementation دعنا نبدأ ب subjuct ونسوي له implementation في class Publisher public class Publisher implements Subject{ private List <Observer> observers ; String article; public Publisher() { observers = new ArrayList<>(); } @Override public void addObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { observers.remove(o); } @Override public void notifyObservers() { for(Observer ob : observers) ob.Update(); } @Override public String getUpdate() { return article; } @Override public void setUpdate(String article) { this.article = article ; notifyObservers(); } } في البداية قمنا بإنشاء List نستطيع أن نسميها قائمة المشتركين في هذا class الذي أفترضنا أنه مدونة لنشر المقالات, ومتغير String والذي هو عبارة عن المقالة التي نريد تنبيه متابعينا حال صدورها. لدينا ثلاث functions رئيسية لا يكاد يخلو Observer Design Pattern منها وهي : addObserver : ﻷضافة متابع جديد لهذا class أو كما يحلو لنا أن نسميه المدون removeObserver : لحذف متابع notifyObservers : لتنبيه المتابعين ونشر المقالة لهم ,وقد تختلف تصرفاتهم عندما يأتيهم التنبيه منهم يبدأ بقر ائتها أو إهمالهما أو حفظها لديه لغرض معين أو غير ذلك. لننتقل الان ل classes التي قامت بعمل implementation ل Observer وهم لا يختلفون كثيرا في implementation public class Reader implements Observer{ private String article ; private Subject sub ; public Reader(Subject blog) { article = "" ; sub = blog ; sub.addObserver(this); } @Override public void Update() { article = sub.getUpdate(); System.out.println("You :"+article); } } public class Reader implements Observer{ private String article ; private Subject sub ; public Reader(Subject blog) { article = "" ; sub = blog ; sub.addObserver(this); } @Override public void Update() { article = sub.getUpdate(); System.out.println("You :"+article); } } class reader والذي افترضت حين بدأت بكتابة المقالة أنه أنت , وclass الأخر هو Friend والذي افترضت أنه صديقك كما تلاحظون في كلا classes قمنا بعمل Override ل update تحضر المقالة و تقرأها, وفي داخل Constructor قمنا بإنشاء المتغيرات الخاصة بنا والانضمام إلى List المتابعين الخاصين بالمدونة public class PupSub { public static void main(String[] args) { // TODO code application logic here Publisher pup = new Publisher(); new Reader(pup); new Friend(pup); pup.setUpdate("Art1"); pup.setUpdate("Art2"); pup.setUpdate("Art3"); } } في البداية قمنا بإنشاء قائمة المتابعين الخاصة بالمدونة وكانت فارغة قم أنشأنا متابع من Reader class والذي سبق وافترضنا أنه أنت, ثم Friend class والذي هو صديقك. كلاكما متابع لهذه المدونة والمدون قد وضعكما في قائمته ويقوم بإخباركم عن كل جديد في هذه المدونة فور وصوله وأنتما تقومان بقراءة ما يأتيكما فور ما يأتي. ثم نشر المدون ثلاث تدوينات عبر setUpdate التي تستدعي notifyObservers ثم تقوم هذه function باستدعاء Update الخاصة بكل class من المتابعين ويقومون بدورهم بتحديث التدوينات التي لديهم عن طريق استداعاء getUpdate الخاصة بالمدون. قد تجد صعوبة في فهم هذا Pattern وغيره في المرة الأولى وهذا طبيعي. عليك تطبيقة وفهم أجزاءه وبعد ذلك سيتضح لك. وأخيرا, لماذا أستخدم Observer Design Pattern ؟ Observer Design Pattern يقلل من التداخل في الكود-Low Coupling- وهذا سيسهل عليك في حال رغبت في إضافة classes أو إزالتها, فجميع classes تعمل بشكل مستقل عن بعضها . المراجع: - http://informatic-ar.com/ال-coupling-وال-cohesion-في-تصميم-البرمجيات/ - https://sourcemaking.com/design_patterns/observer - Head First Design Patterns - البرمجة باستخدام Interfaces تم ترقية هذا الطرح المميز الى صفحة المقالات
  13. بسم الله الرحمن الرحيم في java لدينا Throwable class لديه Error و Exception ك subclass . Error class لا تستطيع معالجة أخطائه أو على الأقل أثناء Runtime لذلك سيكون حديثنا عن Exception class ماهو Exception ؟ هو خطأ-يقال في بعض الأحيان حدث ويقال استثناء- يحدث أثناء تشغيل البرنامج يقطع عملية تنفيذ الأوامر الخاصة بالبرنامج. الان لنتطرق لعملية التحكم في الخطأ ومعالجته -catch and handle exceptions- بداية نبدأ مع مفهوم try-catch وكالعادة نشوف المفهوم بعدين نشرحه public static void main(String[] args) { int a = 5 ; int b = 0 ; System.out.println(a/b); } نلاحظ أن عندنا عملية قسمة لكن على صفر بمعنى أن الناتج راح يكون عدد لا نهائي -infinity- وهذا يعطيني exception من نوع ArithmeticException ليتوقف البرنامج عن العمل -crash-و الحل طبعا أنك ما تقسم على صفر لكن سنحاول أن لا يحدث crash للبرنامج باستخدام try-catch block public static void main(String[] args) { int a = 5 ; int b = 0 ; try{ System.out.println(a/b); }catch(ArithmeticException e){ System.out.println("divid by zero!"); } } نلاحظ أن لدينا two blocks الأول try والثاني catch يبدأ البرنامج في تنفيذ مابداخل try في حال نجح في تنفيذه بدون exception فأنه يتجاوز catch بدون تنفيذها وفي حال ظهر exception فأنه يتوقف عن أكمل تنفيذ try وينتقل إلى catch . جميل جدا لكن ماذا لو كان هناك احتمالية وجود أكثر من exception داخل try block أو كان لدي خطأ لا أعرف لأي نوع من exceptions ينتمي -في حال وضعت catch ل ArithmeticException ثم ظهر لك NullPointerException فإن catch block لن يستطيع التعامل معه- ففي هذه الحالة أستخدم try مع أكثر من catch block كما في المثال public static void main (String args[]){ int x = 0 ; Integer y = null ; try { System.out.println(5/x); x = y ; }catch(ArithmeticException e){ System.out.println("catch "+e.getMessage()); }catch (NullPointerException e) { System.out.println("catch "+e.getMessage()); } } أما في حال لم تعرف هذا خطأ لأي نوع من exceptions ينتمي فتستخدم catch block مع Exception ك parameter لأن جميع ال Exceptions هم subclass من Exception وهذا أحد تطبيقات مبدأ polymorphism , فعلى سبيل المثل سنكرر المثال سابق ولكن نستبدل NullPointerException ب Exception public static void main (String args[]){ int x = 0 ; Integer y = null ; try { System.out.println(5/x); x = y ; }catch(ArithmeticException e){ System.out.println("catch "+e.getMessage()); }catch (Exception e) { System.out.println("catch "+e.getMessage()); } } في هذه الحالة في حال ظهور أي خطأ غير ArithmeticException سوف يقوم Exception بتنفيذ catch الخاصة به وهنا يأتي سىؤال لماذا لا أكتفي ب Exception ؟ إذا كنت تريد أن تعامل كل خطأ بطريقة معينة-كإظهار رسالة معينة أو تنبيه وما إلى ذلك- فيفضل استخدام أكثر من catch block لكل catch ال Exception الخاص بها , أما في حال كان يهمك أن لا يحدث crash لتطبيق فسيكون حل مناسب لك . جميل الآن نحن إما أن ننفذ try أو catch لكن ماذا لو كان لدينا أمر ما نريد أن ننفذه في حال تم تنفيذ try أو catch؟ الطريقة الصحيحة ليس أن تكتبه في كلا blocks لكن أن تستخدم جملة finally كما في المثال tring args[]){ int x = 0 ; Integer y = null ; try { System.out.println(5/x); x = y ; }catch(ArithmeticException e){ System.out.println("catch "+e.getMessage()); }catch (Exception e) { System.out.println("catch "+e.getMessage()); }finally { System.out.println("I will show up anyway"); } } ف finally block سوف يظهر على كل حال , في حال تنفيذ أي من try أو catch . إذا لنلخص قسم try & catch & finally نستخدم try و catch واحده في حال كان هناك خطأ واحد نستخدم try وأكثر من catch في حال كان هناك أحتمالية وجود أكثر من خطأ نستخدم finally في حال أردنا تنفيذ أمر معين في كل الحالات . نستخدم Exception ك نوع ل exception في حال كنا فقط نريد أن لا يحدث crash أو كانت جميع الأخطاء لها نفس التعامل -كأن تظهر جميع الأخطاء رسالة Error- طيب ماذا لو أردت أن تضع exception في حال قام أحدهم بخطأ ما , وليكن قام مدخل البيانات بإدخال راتب أحد الموظفين صفر فيكون ال exception بهذه الطريقة public static void main (String args[]) throws Exception{ int Salary = 0 ; try{ if(Salary<= 0 ){ throw new ArithmeticException(); } }catch(ArithmeticException e){ System.out.println("R U serious!"); } } قد تكون لاحظت أننا طوال هذه المقالة نستخدم exception الخاصة بنفس اللغة , لكن ماذا لو أردنا بناء exception الخاص بنا بحيث عندما يدخل مدخل البيانات راتب خاطئ يكون هنا SalaryException الأمر بسيط كل ما تحتاجه هو بناء class يعمل extends ل Exception وتضع الرسالة المراد إخراجها حال ظهور exception public class SalaryException extends Exception { public SalaryException() { super("Salary not valid"); } } public class Salary { public static void main (String args[]) throws Exception{ int Salary = 0 ; try{ if(Salary<= 0 ){ throw new SalaryException(); } }catch(SalaryException e){ System.out.println(e); } } } في هذه الحالة سوف يظهر لك Salary not valid . Exception class لديه تصنيفين رئيسيين Checked Exception و Unchecked Exception - Checked Exception هي Exception يشير لها Compiler أثناء وقت تنفيذ الكود -Compile time- ويجبر المبرمج على معالجتها ,مثل IOException SQLException DataAccessException ClassNotFoundException InvocationTargetException MalformedURLException - Unchecked Exception على العكس فهذه Exception تكتشف أثناء عمل البرنامج -RuntimeException- مثل NullPointerException ArrayIndexOutOfBound IllegalArgumentException IllegalStateException فحين تقوم بكتابة function وتضع داخلها throw لأحد أنواع Checked Exception فسيجبرك Compiler إما على declared exceptions باستخدام throws keyword أو استخدام try-catch كما في المثال class Test { static void Nmae (String name) throws IOException{ if (name == "") throw new IOException("Empty name"); } public static void main(String[] args) throws IOException { Nmae (""); } } نلاحظ أنك ستضع أيضا throws داخل أي function تستدعي فيها function التي بداخلها exceptions كم يحدث هنا في main بالمناسبة Error class الذي تحدثنا عنه بداية المقالة جميع أخطائه تصنف Unchecked Exception هذا وصلى الله وسلم وبارك على نبينا محمد مراجع : https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html https://crunchify.com/better-understanding-on-checked-vs-unchecked-exceptions-how-to-handle-exception-better-way-in-java/ http://beginnersbook.com/2013/12/throws-keyword-example-in-java/
  14. بسم الله الرحمن الرحيم في java لدينا Throwable class لديه Error و Exception ك subclass . Error class لا تستطيع معالجة أخطائه أو على الأقل أثناء Runtime لذلك سيكون حديثنا عن Exception class ماهو Exception ؟ هو خطأ-يقال في بعض الأحيان حدث ويقال استثناء- يحدث أثناء تشغيل البرنامج يقطع عملية تنفيذ الأوامر الخاصة بالبرنامج. الان لنتطرق لعملية التحكم في الخطأ ومعالجته -catch and handle exceptions- بداية نبدأ مع مفهوم try-catch وكالعادة نشوف المفهوم بعدين نشرحه public static void main(String[] args) { int a = 5 ; int b = 0 ; System.out.println(a/b); } نلاحظ أن عندنا عملية قسمة لكن على صفر بمعنى أن الناتج راح يكون عدد لا نهائي -infinity- وهذا يعطيني exception من نوع ArithmeticException ليتوقف البرنامج عن العمل -crash- طيب الحل طبعا أنك ما تقسم على صفر لكن سنحاول أن لا يحدث crash للبرنامج باستخدام try-catch block public static void main(String[] args) { int a = 5 ; int b = 0 ; try{ System.out.println(a/b); }catch(ArithmeticException e){ System.out.println("divid by zero!"); } } نلاحظ أن لدينا two blocks الأول try والثاني catch يبدأ البرنامج في تنفيذ مابداخل try في حال نجح في تنفيذه بدون exception فأنه يتجاوز catch بدون تنفيذها وفي حال ظهر exception فأنه يتوقف عن أكمل تنفيذ try وينتقل إلى catch . جميل جدا لكن ماذا لو كان هناك احتمالية وجود أكثر من exception داخل try block أو كان لدي خطأ لا أعرف لأي نوع من exceptions ينتمي -في حال وضعت catch ل ArithmeticException ثم ظهر لك NullPointerException فإن catch block لن يستطيع التعامل معه- ففي هذه الحالة أستخدم try مع أكثر من catch block كما في المثال public static void main (String args[]){ int x = 0 ; Integer y = null ; try { System.out.println(5/x); x = y ; }catch(ArithmeticException e){ System.out.println("catch "+e.getMessage()); }catch (NullPointerException e) { System.out.println("catch "+e.getMessage()); } } أما في حال لم تعرف هذا خطأ لأي نوع من exceptions ينتمي فتستخدم catch block مع Exception ك parameter لأن جميع ال Exceptions هم subclass من Exception وهذا أحد تطبيقات مبدأ polymorphism , فعلى سبيل المثل سنكرر المثال سابق ولكن نستبدل NullPointerException ب Exception public static void main (String args[]){ int x = 0 ; Integer y = null ; try { System.out.println(5/x); x = y ; }catch(ArithmeticException e){ System.out.println("catch "+e.getMessage()); }catch (Exception e) { System.out.println("catch "+e.getMessage()); } } في هذه الحالة في حال ظهور أي خطأ غير ArithmeticException سوف يقوم Exception بتنفيذ catch الخاصة به وهنا يأتي سىؤال لماذا لا أكتفي ب Exception ؟ إذا كنت تريد أن تعامل كل خطأ بطريقة معينة-كإظهار رسالة معينة أو تنبيه وما إلى ذلك- فيفضل استخدام أكثر من catch block لكل catch ال Exception الخاص بها , أما في حال كان يهمك أن لا يحدث crash لتطبيق فسيكون حل مناسب لك . جميل الآن نحن إما أن ننفذ try أو catch لكن ماذا لو كان لدينا أمر ما نريد أن ننفذه في حال تم تنفيذ try أو catch؟ الطريقة الصحيحة ليس أن تكتبه في كلا blocks لكن أن تستخدم جملة finally كما في المثال tring args[]){ int x = 0 ; Integer y = null ; try { System.out.println(5/x); x = y ; }catch(ArithmeticException e){ System.out.println("catch "+e.getMessage()); }catch (Exception e) { System.out.println("catch "+e.getMessage()); }finally { System.out.println("I will show up anyway"); } } ف finally block سوف يظهر على كل حال , في حال تنفيذ أي من try أو catch . إذا لنلخص قسم try & catch & finally نستخدم try و catch واحده في حال كان هناك خطأ واحد نستخدم try وأكثر من catch في حال كان هناك أحتمالية وجود أكثر من خطأ نستخدم finally في حال أردنا تنفيذ أمر معين في كل الحالات . نستخدم Exception ك نوع ل exception في حال كنا فقط نريد أن لا يحدث crash أو كانت جميع الأخطاء لها نفس التعامل -كأن تظهر جميع الأخطاء رسالة Error- طيب ماذا لو أردت أن تضع exception في حال قام أحدهم بخطأ ما , وليكن قام مدخل البيانات بإدخال راتب أحد الموظفين صفر فيكون ال exception بهذه الطريقة public static void main (String args[]) throws Exception{ int Salary = 0 ; try{ if(Salary<= 0 ){ throw new ArithmeticException(); } }catch(ArithmeticException e){ System.out.println("R U serious!"); } } قد تكون لاحظت أننا طوال هذه المقالة نستخدم exception الخاصة بنفس اللغة , لكن ماذا لو أردنا بناء exception الخاص بنا بحيث عندما يدخل مدخل البيانات راتب خاطئ يكون هنا SalaryException الأمر بسيط كل ما تحتاجه هو بناء class يعمل extends ل Exception وتضع الرسالة المراد إخراجها حال ظهور exception public class SalaryException extends Exception { public SalaryException() { super("Salary not valid"); } } public class Salary { public static void main (String args[]) throws Exception{ int Salary = 0 ; try{ if(Salary<= 0 ){ throw new SalaryException(); } }catch(SalaryException e){ System.out.println(e); } } } في هذه الحالة سوف يظهر لك Salary not valid . Exception class لديه تصنيفين رئيسيين Checked Exception و Unchecked Exception - Checked Exception هي Exception يشير لها Compiler أثناء وقت تنفيذ الكود -Compile time- ويجبر المبرمج على معالجتها ,مثل IOException SQLException DataAccessException ClassNotFoundException InvocationTargetException MalformedURLException - Unchecked Exception على العكس فهذه Exception تكتشف أثناء عمل البرنامج -RuntimeException- مثل NullPointerException ArrayIndexOutOfBound IllegalArgumentException IllegalStateException فحين تقوم بكتابة function وتضع داخلها throw لأحد أنواع Checked Exception فسيجبرك Compiler إما على declared exceptions باستخدام throws keyword أو استخدام try-catch كما في المثال class Test { static void Nmae (String name) throws IOException{ if (name == "") throw new IOException("Empty name"); } public static void main(String[] args) throws IOException { Nmae (""); } } نلاحظ أنك ستضع أيضا throws داخل أي function تستدعي فيها function التي بداخلها exceptions كم يحدث هنا في main بالمناسبة Error class الذي تحدثنا عنه بداية المقالة جميع أخطائه تصنف Unchecked Exception هذا وصلى الله وسلم وبارك على نبينا محمد مراجع : https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html https://crunchify.com/better-understanding-on-checked-vs-unchecked-exceptions-how-to-handle-exception-better-way-in-java/ http://beginnersbook.com/2013/12/throws-keyword-example-in-java/ تم ترقية هذا الطرح المميز الى صفحة المقالات
  15. بسم الله الرحمن الرحيم اختبار المساواة والذي نطبقه غالبا باستخدام "== " لتأكد من تساوي البيانات التي نود التحقق منها غير أن هذه المقارنة لا تتم دائما كما نتوقع ولنبدأ بالتجربة والتأكد والتعليل في البداية لدينا هذا الكود int a = 5 ; int b = 5 ; System.out.print(a==b); ونتيجة هذه المقارنة تبدو واضحة جدا حيث يقوم compiler بالقيام بعملية المقارنة وإرجاع true or false حسب النتيجة لكن هذا لا يكون إلا في حال كان نوع البيانات التي نتعامل معها هو primitive data types بمعنى أن المقارنة بهذه الطريقة مع object type ستكون نتيجتها مختلفة تمام عن المتوقع ولنأخذ هذا المثال Integer a = new Integer(5); Integer b = new Integer(5); System.out.println(a == b); قد تفاجأ حين تظهر لك نتيجة هذه المقارنة false ولكن يعود السبب في هذه النتيجة أنه عندما تنشئ متغير من نوع object فأنت لا تسند له القيمة و إنما المرجع (reference) ففي المثال السابق لا تتم المقارنة بهذه الصورة (5 ==5 ) و إنما نقول تجوزا بهذه الصورة (0x24 == 0x33) فالمقارنة على تتم علىobject reference و ليست على قيمة object إذا مالحل ؟ الحل هو استخدام equals method كما في المثال التالي Integer a = new Integer(5); Integer b = new Integer(5); System.out.println(a.equals(b)); فنتيجة هذه المقارنة ستكون true حيث أن equals method ستقوم بمقارنة القيم وتعطي نتائج سليمة إذا هل استخدم equals method مع جميع المتغيرات من نوع object ؟ الجواب لا , ف equals method هي من class object وهذا class هو superclass لجميع classes في java إذا ف equals method ستورث لأي class ينشأ, لكن في حال لم يتم عمل override لها داخل class فلن تعطيك نتائج سليمة ولنأخذ هذا المثال String a = new String ("test"); String b = new String ("test"); StringBuilder c = new StringBuilder("test"); StringBuilder d = new StringBuilder("test"); System.out.println("String: "+a.equals(b)); System.out.println("StringBuilder: "+c.equals(d)); فسيكون output كالتالي String: true StringBuilder: false و السبب يعود كما أسلفت لأنه في class String تم عمل override ل equals method وهذا لم يتم في StringBuilder class ويمكنك التأكد من هنا String : https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#equals(java.lang.Object) StringBuilder : https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html جميل جداً وهذا يقودنا إلى تساؤل , كيف يمكن أن أعمل override ل equals method داخل class الذي أنشأته ؟ لنأخذ هذا المثال لنفرض أن لدينا class اسمه Student وفيه two data member وهما name & address public class Student { String name ; String address ; //constructor Student (){ name = "abdulaziz" ; address = "riyadh" ; } //override of equals method in our class public boolean equals (Object other){ boolean result = false ; if(other instanceof Student){ Student S2 = (Student)other ; result = S2.name.equals(this.name) && S2.address.equals(this.address) ; } return result ; } public static void main(String[] args) { Student a =new Student() ; Student b =new Student(); System.out.println(a.equals(b)); } } فكما نشاهد في هذا المثال فقد تم عمل override ل equals method واستخدامها داخل class الذي قمنا بإنشائه نقطة أخيره أختم بها هذه المقالة لا يمكن استخدام equals method مع null object وإلا ستحصل على java.lang.NullPointerException كما في هذا المثال Student a =null ; Student b =null; System.out.println(a.equals(b)); وختاما إن وفقت في الطرح والمعلومات فمن الله وإن أخطأت فمن نفسي والشيطان والسلام عليكم ورحمة الله وبركاته المصادر: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html https://docs.oracle.com/javase/8/docs/api/java/lang/String.html https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html

عالم البرمجة

عالم البرمجة مقالات برمجة و دورات مجانية لإحتراف البرمجة هدفنا تبسيط البرمجة ونشرها بيد الكل بشكل ممتع ومتطور ومحدث بإستمرار لمواكبة جديد تطورات البرمجة الحديثة و المتقدمة بدون مقابل