Adapter pattern


مستوى المقال: متوسط

بسم الله الرحمن الرحيم

كما ما بدأناه بالحديث عن أكثر  Design pattern استخداما في بيئة Android واليوم سنتحدث عن أحد أنواع Structural pattern , ألا وهو  Adapter  pattern ,قبل أن نبدأ, وبما أننا في أول pattern في هذه السلسة من نوع Structural فماذا نعني ب Structural pattern ؟

Structural pattern : هو تصميم للكود بطرق تسهل فهم العلاقة بين classes و objects والربط بينها.

جميل جدا, إذا ماهو Adapter  pattern ؟ من كتاب GoF

اقتباس

The adapter pattern is used to provide a link between two otherwise incompatible types by wrapping the "adaptee" with a class that supports the interface required by the client.

ولتبسيط الأمور, هذا 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 كالتالي:

Screenshot from 2016-12-31 16-23-00.png

 

إلى هنا, هذا ما كان في الجعبة ووفق الله الجميع وصلى الله وسلم وبارك

 

المراجع:

- sourcemaking.com/design_patterns

- java design pattern , rohit joshi

- head first design pattern

 

3zcs

1


اراء المستخدمين


لاتوجد تعليقات لعرضها .



انشئ حساب جديد او قم بتسجيل دخولك لتتمكن من اضافه تعليق جديد

يجب ان تكون عضوا لدينا لتتمكن من التعليق

انشئ حساب جديد

سجل حسابك الجديد لدينا في الموقع بمنتهي السهولة .


سجل حساب جديد

تسجيل الدخول

هل تمتلك حساب بالفعل ؟ سجل دخولك من هنا.


سجل دخولك الان

Ads Belongs To This website

  • السلام عليكم ورحمة الله وبركاته 
    طرحنا مسابقة عالم البرمجة للنقاش الهادف ، و هدفنا إثراء المحتوى العربي في مجال البرمجة ، فاز معنا الطرح المتميز و المفيد حيث قام بتقييم المقالات وترقيتها من قبل فريق عالم البرمجة سنذكر بهذه المقالة الفائزين معنا ، و مقالاتهم ، و نشكرهم على ماقدموا من فائدة للجميع ، و إثراء المحتوى العربي في البرمجة.
    الفائزون في شهر Januray-2017
    @3zcs المقال الفائز:
    @3zcs المقال الفائز:
    @AMR0T  المقال الفائز:
    @وضاح العوني المقال الفائز:
    @يعرب المصطفى المقال الفائز:
    @Abdulrahman Hasan Agha المقال الفائز:
    @Omnyyah المقال الفائز:
    في الختام:
    هدفنا في موقع عالم البرمجة إثراء المحتوى العربي في مجال البرمجة ، و تعزيز حب المساعدة بين المبرمجين تستطيع كتابة ماتحب في ساحات النقاش ، و يمكن تكون احد الفائزين معنا  بمسابقة عالم البرمجة للنقاش الهادف فهي مازالت مستمره ايضا تستطيع مساعدة المبرمجين بالإجابة عن أسئلتهم ، و حل المشاكل التي تواجههم بقسم سؤال وجواب ؛ لتكون مرجع لبقية المبرمجين شعارنا في عالم البرمجة "إن في قضاء حوائج الناس لذة لا يَعرفها إلا من جربها، فافعل الخير مهما استصغرته فإنك لا تدري أي حسنة تدخلك الجنة." -ابن القيم-  وممكن تستفيد من
    حبيبي القارئ اعلم ان فريق عالم البرمجة يصب كل جهودة لمساعدة المبرمجين الذين يخصصون من وقتهم لنشر العلم المفيد ويساعدون الغير ويارب يقدرنا نوقف معكم ونساعدكم قد مانقدر.
    مستوى المقال: مبتدئ

    بواسطه Ali Majrashi , في

  • في هذه السلسلة – ان شاء الله – سأشرح أهم المواضيع في منهج نظرية الحوسبة  في أكثر من مقالة ولمن أراد الاطلاع أكثر فمرجعي الرئيسي هو كتاب
    An Introduction to FORMAL LANGUAGES and AUTOMATA
    للكاتب
    PETER LINZ
     
    المنهج مهم جداً لطلاب علوم الحاسب فهو يناقش مجموعة من المفاهيم النظرية البحتة والتي ساعدت في انشاء علوم الحاسب والخوارزميات وعلم المنطق والتي يجب على كل طالب استيعابها وفهمها .
    هناك ٣ محاور رئيسية لا بد من التحدث عنها قبل أن نسترسل في شرح أنواع القواعد والآلات الموجودة .
     
     
    أولاً : اللغات : 
     
    أغلب القواميس في جميع اللغات تعرف لنا اللغة بأنها نظام من التعبيرات لمجموعة من الأفكار والمفاهيم والحقائق وتضم عدداً من الرموز والقواعد لإنشاء الجمل والكلمات بشكل صحيح تحت هذه اللغة .
    نبدأها بمجموعة منتهية غير فارغة نسميها آلفابت Alphabet ويرمز لها برمز سيجما ∑ ومن خلال رمز واحد من الآلفابت يمكننا تكوين كلمة String والكلمة عبارة عن سلسلة منتهية من الرموز في الآلفابت .
     
    مثال : لدينا الآلفابت التالية
    ∑ = {a, b}
     
    فيمكننا انشاء كلمة ( نرمز لها بالرمز w ) تسمى abba أو a أو ba لأنها كلمات ضمن الألفابت الموجودة ، اذاً يمكننا عمل مجموعة لانهائية من الكلمات تحت آلفابت معينة .
    طول الكلمة يرمز له بالرمز |w| وهو رقم يساوي عدد الحروف في تلك الكلمة واذا كان طول الكلمة يساوي الصفر فيعني ذلك أن تلك الكلمة تسمى (ايبسلون أو لمدا ) ونرمز لها بالرمز  λ .
    λ|=0| .
     
     
    ثانياً : القواعد :
     
    تُعرَف القاعدة Rule عن طريق الرموز التالية
    G =(V, T, S, P)
     
    1- V : مجموعة من المتغيرات .
    2- T : مجموعة من الرموز المنتهية التي ننهي بها الكلمة .
    3- S : رمز البداية وهو ضمن T .
    4- P : القواعد التي نتبعها في صنع أي كلمة ضمن آلفابت معينة وهي قلب وأساس أي قاعدة .
     
     
    نفرض أن كل القواعد تأتي بهذا الشكل
    x -> y
    بحيث أن x تعني جميع المتغيرات والرموز المنتهية و y تحتوي على الرموز المنتهية والمتغيرات + الكلمة الفارغة λ .
     
     
    مثال توضيحي :
    G = { {S},{a,b},S,P}
    و القواعد في هذه اللغة P
    S -> aSb
    S -> λ
    أمثلة على الكلمات التي يمكننا اشتقاقها من هذه القاعدة
    ab , aabb , aaabbb وهكذا ، اذاً اللغة الخاصة بهذا القاعدة عباره عن مجموعة من a تتبعها مجموعة من b بنفس العدد .
     
    يمكننا كتابة اللغة بهذه الصيغة :

     
     
     ثالثاً : الآلات :
     
     الآلات Automata هي عبارة عن نموذج نظري للكمبيوترات الرقمية ، كل آلة لها ميكانيكا خاصة لقراءة المدخلات لكن لا تغيرها ويمكنها أيضاً تحديد نهاية وبداية كل كلمة أو مُدخل ويمكن أن يكون لها أجهزة تخزين وتحتوي على مجموعة من وحدات التحكم التي تتغير حالتها ومجموعة من دوال التغير المرتبطة بالمدخل والحالة الحالية للمدخل .
    بإذن الله في المقالات التالية سوف نناقش ٤ أنواع من الآلات وطريقة عملها والقواعد التي تقبلها ومايخصها بشكل مخصص .
    مستوى المقال: متوسط

    بواسطه Omnyyah , في

  • اللغة المستخدمة : swift 3
    البرنامج المستخدم : xcode 8
     
    في هذا الدرس سوف نتعلم طريقة تطبيق الsingleton design pattern في برنامج الxcode و في لغة برمجة swift 
    لكن في البداية لمأخذ مقدمة بسيطة عن الdesign pattern ، إذا ما هو الdesign pattern ؟
    الdesign pattern هي طريقة معينة أو نمط معين يستخدمه المبرمج لكتابة الكود البرمجي. لكن لماذا يستخدم هذه الطرق عوضا عن أي طريقة أخرى؟
    -في البرمجة وارد جدا أن تتعرض للمشكلات و أنا لا أتحدث هنا عن مشكلات الoutput فقط و إنما قد تواجه مشاكل معينة متعلقة بالطريقة التي قمت ببناء الكود عليها و هذه المشكلات غالبا ما تتواجد فيها خاصيتين رئيسيتين : 
     أن هذه المشكلات تحدث مع المبرمجين بشكل متكرر .  غالبا عند التعرض لأحد هذه المشكلات فإن إصلاحها سيكون مكلفا بمعنى أن المبرمج سيحتاج إلى إعادة كتابة كمية ليست بالقليلة من الأكواد لإصلاح المشكلة و الوصول إلى حل.  
    و لذلك يتم اسخدام طرق معينة لبناء الكود البرمجي تسمى design patterns.
    لنفرض أنك تعمل على تطبيق آيفون خاص بإدارة حسابات بنكية و لديك class باسم bankManager حيث يستخدم هذا الكلاس لإدارة كل العمليات المتعلقة بالبنك فعلى سبيل المثال يوجد به function خاصة بإيداع الأموال في حساب ما.. التي تتلقى باراميتر للid الخاص بالحساب و تتلقى بارامتر آخر لكمية المبلغ الذي سيتم إيداعه كذلك يحوي هذا الحساب function لسحب المبلغ و أخرى لتحويل المبلغ لحساب آخر.. الخ و بالتالي فإن هذا الclass سيحوي كل هذه الأوامر المهة التي ستستخدم في التطبيق.
    و هذه الأوامر سستستخدمها في كل الclasses التي ستقوم بإنشائها في تطبيقك بمعنى آخر.. ستحتاج لأن يكون لديك object من الكلاس bankManager في كل الclasses لديك في التطبيق لأنك ستحتاج حتما لاستخدام الأوامر المهمة في يحويها هذا الclass في أغلب الclasses في تطبيقك.
    لكن هل إنشاء object من الbankManager في كل الكلاسات التي لديك هي طريقة جيدة للعمل مع هذا الكلاس ؟
    بمعنى آخر هل من المناسب إنشاء عدد من الobjects من كلاس الbankManager أم يجب أن يكون لدينا فقط object واحد مشترك بين كل الكلاسات ؟
    الحقيقة أن إنشاء object واحد فقط مشترك بين كل الكلاسات هي الطريقة المثلى للتعامل مع ال objects من هذا الكلاس و لذلك فإنك بطريقة ما تحتاج لأن تجبر الكلاس على إنشاء object واحد فقط و إرجاع نفس الobject في كل مرة يتم فيها محاولة عمل object جديد من هذا الكلاس. لكن كيف يتم ذلك ؟ ذلك يتم من خلال ما يعرف بالsingleton object أو الsingleton design pattern
    إذا لنبدأ تطبيق ذلك عمليا :
    -في البداية افتح الxcode  قم بإنشاء مشروع جديد (create new xcode project > single view application )   و قم بتسميته Singleton.

     
    - الآن قم بعمل كلاس جديد و قم بتسميته bankManager.
    - في البداية و كما تعلم نحن بحاجة إلى استخدام object مشترك بين كل الكلاسات و لعل كلمة مشترك ستقودك الى التفكير ب static variable، بالفعل سنحتاج إلى عمل static variable لذلك توجه إلى الbankManager و قم بإضافة object من نوع الكلاس نفسه و هو الbankManager و قم بجعله static و لأن هذا الobject سيبدأ بقيمة nil ثم سيكون ذا قيمة من نوعBankManager عندما يتم استدعاؤه لذلك يجب أن يكون هذا الobject من نوع optional لذلك لا تنس إضافة ( ؟ ) في نهاية تعريفه.

     

    - الآن أصبح لدينا أوبجكت مشترك أو يمكن أن يكون مشتركا بين كل الكلاسات لأنه من نوع static. هل هذا يكفي ؟ بالطبع لا.
    من الذي سيحدد فيما إذا كان الobject قد تم إنشاؤه و بالتالي إعادته نفسه أو إنشاء object جديد في حال أن قيمة الobject في الحقيقة تساوي nil لذا هل يمكنك التفكير بالخطوة القادمة ؟ 
    - الحل هو عمل function تقوم بالمطلوب حيث ستقوم هذه الfunction بالتأكد أن الobject قد تم إنشاؤه و في حال كان الobject قد تم إنشاؤه بالفعل فإنها ستعيد هذا الobject bankManager الذي قمنا بإنشائه في الأعلى و إلا فإنها ستقوم بإنشائه إولا ثم إرجاعه بعد إنشائه. ولأن هذه الfunction سوف تقوم باستخدام object من نوع static إذا هي بحاجة أن تكون static كذلك و بالتالي ستكون الfunction كالتالي :
    -ملاحظة: من الشائع في برمجة - بعض الأحيان -  الآيفون تسمية هذه الfunction اسم مشابه لsharedObject أو sharedManager 

     
    - قد يرد إلى ذهنك الآن أننا سنستخدم هذه الfunction دائما إذا ما أردنا الوصول إلى الobject مما يعني أننا لن نصل إلى الobject مباشرة عن طريق استدعائه بشكل مباشر باستخدام BankManager.bankManager و الحقيقة أن استدعاءه بهذه الطريقة قد يسبب بعض المشاكل، مثلا: قد تقوم باستدعائه في أحد الكلاسات بهذه الطريقة و قيمته في ذلك التوقيت تساوي nil و فور محاولتك استخدام اي متغير أو function بداخل الكلاس BankManager فأن البرنامج سيتوقف لمحاولتك استدعاء function لعنصر قيمته في الحقيقة تساوي nil و لحل هذه المشكلة و حتى تقطع أي مجال لاستدعاء الobject بهذه الطريقة المباشرة قم بعمل الstatic object ليكون private و بالتالي سيظهر الكود بهذه الطريقة 

     
    - هل انتهى الأمر تماما؟ في الحقيقة ليس بعد. ماذا إن قمت خطأً بعمل object من كلاس الBankManager بالطريقة العادية لأنشاء Object من الكلاسات في سويفت ؟ أو افرض أنك تعمل في فريق من المبرمجين و قام مبرمج آخر باستكمال العمل من بعدك حينها ستحتاج إلى منعه من عمل object بالطريقة العادية حتى لا تسبب مشاكل أثناء العمل؟ لكن كيف يتم ذلك ؟ كل ما عليك فعله هو أن تجعل الfunction التي تثوم بعمل الobject بطريقة عادية لتكون من نوع private و بالتالي لن يكون بالإمكان استدعاءها خارج الكلاس و سيكون المبرمج مجبرا على استخدام الfunction المسماة sharedObject 
     
    و الآن هل انتهى الأمر ؟ 
    نعم انتهى الأمر هنا و أصبح الsingleton object جاهزا للاستخدام أخيرا.
    بقي الإشارة إلى نقطة مهمة، إن كنت من مبرمجيswift المتمرسين، فلعلك لاحظت أن بعض الclasses التي تقوم باستخدامها هي في الحقيقة تطبق الsingleton pattern و من هذه الكلاسات : 
    NSUserDefaults ---->  var userDefaults = NSUserDefaults.standardUserDefaults()
    UIScreen ----> var mainSecreen = UIScreen.mainScreen
    UIApplication ----> var application = UIApplication.sharedApplication
    -- لاحظ أن الوصول للshared object يمكن أن يكون عن طريق static method كما شرحنا في هذا الدرس و قد يكون عن طريق static variable 
     
    ختاما.. أتمنى أن أكون وفقت في الشرح و إيصال الفكرة و أسأل الله أن يجعله من العلم الذي يُنتفع به  .

    مستوى المقال: متوسط

    بواسطه يعرب المصطفى , في

  • بسم الله الرحمن الرحيم
    السلام عليكم ورحمة الله وبركاته
     
    Hashing
     
    الكثير من الـ algorithms تستخدم في عملية البحث البسيطة عن Record معين أو Data معينة وسط الآلاف وأحيانا مئات الالاف من الملفات المخزنة في الذاكرة.
    العامل المهم في عملية اختيار الطريقة الممتازة تعتمد على الوقت وفعالية الجهاز المستخدم في عملية البحث ومدى كفائته. وواحدة من أفضل الطرق المستخدمة حالياً هي الـ Hashing .
    سنتعرف معاً في هذا المقال على :
    -          تعريف بسيط عن الـ Hashing.
    -          بعض الطرق المستخدمة في التعامل مع الـ Data في حالة التكرار في طريقة الـ Hashing.
    -          طريقة التطبيق في لغة برمجة Java.
     
    تعريف بسيط عن الـ Hashing:
    هي طريقة تستخدم لحفظ الملفات وتخزينها ومن ثم البحث عنها بأسرع طريقة ممكنة. تتميز هذه الطريقة عن غيرها بأنها قادرة على جلب الـ Data بوقت سريع جدا وسط ملفات ومعلومات كبيرة نوعاً ما مقارنة بغيرها من الطرق.
    هذه الطريقة تتميز بحفظ الـ Data في جدول بحيث يتم إعطاء كل معلومة رقم مميز يتم حفظه داخل جدول من البيانات ومن ثم يتم الوصول إليه مباشرة في حال الحاجة إلى البحث عنه. هذه الطريقة تتميز بقلة الوقت اللازم للقيام بهذه العملية بحيث يمكنك مباشرة معرفة ما إذا كان الملف الجاري البحث عنه موجود أو غير موجود دون الحاجة للبحث عنه داخل الذاكرة بأكملها.
    مثال :
    لنفرض بأن لدينا الأرقام التالية : 1-7-4-8-9-5 .
    إذا قمنا بحفظ هذه الأرقام داخل Array بشكل عشوائي مباشر على سبيل المثال فعند البحث عن رقم 9 ستضطر إلى البحث داخل الـ Array بالكامل لمعرفة ما اذا كان الرقم 9 موجود أو لا. تخيل بأن لديك أكثر من الف رقم او أكثر!! يمكنك تخيل الوقت الطويل الذي ستحتاجه للقيام بعملية البحث هذه.
    لكن باستخدام Hashing يمكننا مثلا تخزين هذه الأرقام داخل Array ولكن ليس بشكل عشوائي كما في السابق وإنما بالنسبة لباقي قسمة العدد على حجم الـ Array على سبيل المثال. لنتفرض بأننا انشأنا Array بحجم 9 خلايا، الصف الأول يوضح الـ index والصف الثاني يوضح العدد الموجود داخل هذا الـ index
    8 7 6 5 4 3 2 1 0 index                   value عند تعبئة هذه الـ Array سنستخدم العلاقة التالية : index = number % arrayLength. بمعنى آخر سيتم وضع الرقم داخل الخانة المعبرة عن باقي قسمة العدد على حجم الـ Array.
    فيكون الجدول بعد التعبئة بهذا الشكل
    8 7 6 5 4 3 2 1 0 index 8 7   5 4     1 9 value لاحظ بأن الرقم 9 وضع بخانة رقم 0 لان باقي قسمة 9 على حجم الـ Array سيعطيك صفر.
    الآن بامكانك مباشرة الذهاب حين البحث عن رقم 9 إلى الرقم المستخرج من الدالة index = number % arrayLength وهو صفر لتعرف ما اذا كان الرقم 9 موجود أو لا وبالتالي توفير الكثير من الوقت.
     
    بعض الطرق المستخدمة في التعامل مع الـ Data في حالة التكرار في طريقة الـ Hashing:
    في المثال السابق لم نصادف أي تكرار في قيمة باقي قسمة الارقام على حجم الـ array ولكن كيف من الممكن حل مشكلة تكرار القيم في حال وقوعها ؟
    هناك الكثير من الحلول التي من الممكن استخدامها لحل هذه المشكلة ولكن سيتم ذكر حل واحد في هذا المقال وسيتم الحديث عن باقي الحلول في مقالات قادمة إن شاء الله.
    1 - Separate Chaining : هذه الطريقة تعتمد على بناء ArrayList بشكل خاص أو أي Structure آخر بشكل عام داخل كل خلية في الـ Hash Table الموضح في الأمثلة السابقة.
    لنأخذ هذه الأعداد على سبيل المثال : 12 – 17 – 29 – 6 – 30 – 31 – 4 – 8 ولنقم بتوزيعها علىHash Table  بحجم 4 خلايا.

     
    في هذه الحالة يتم أولا معرفة الـ index المراد البحث داخله ومن ثم البحث داخل الـ ArrayList لمعرفة ما اذا كان الـ record المراد البحث عنه موجود أو غير موجود.
     
    طريقة التطبيق في لغة برمجة Java:
    هناك الكثير من الطرق لتطبيق فكرة الـ Hashing بواسطة الجافا ولكن سنقوم باتباع الطريقة الأسهل والأقل تعقيداً. سنحتاج إلى إنشاء كلاس List :
    List Class  : عبارة عن كلاس سيتم عمل objects منه  ويحتوي على الـ ArrayList المراد تخزين الـ Data فيها بالإضافة إلى Constructor.
    import java.util.ArrayList; public class List { private ArrayList<Integer> list = new ArrayList<Integer>(); //Constructor public List(){ } public ArrayList<Integer> getList(){ return list ; } }  
    نحتاج أيضاً لإنشاء test class للتأكد من صحة الـ HashTable 
    Test Class : في التيست كلاس سنقوم بإنشاء Array من كلاس List. لاحظ بأنه يجب عليك تعريف كل عناصر هذه الـ Array وبدون هذا التعريف سيظهر لك NullPointerException.
    //hash table List [] hashTable4 = new List [4] ; for (int i = 0 ; i<hashTable4.length ; i++) hashTable4[i] = new List();  
    ميثود print لطباعة الجدول 
    public static void print(List [] array){ for (int i = 0 ; i<array.length ; i++) System.out.println("index "+i+" : "+array[i].getList().toString()); }  
    ميثود getHashCode لمعرفة الـ index المناسب 
    public static int getHashCode(int num){ return num%4 ; }  
    نقوم بتخزين الأرقام في array لتسهيل عملية التصنيف والإدخال ومن ثم نقوم بإدخالها في object hashTable4
    //numbers we want to add int [] listOfNumbers = {12,17,29,30,6,31,4,8}; //add Numbers to the hash table for (int i = 0 ; i<listOfNumbers.length ; i++){ int index = getHashCode(listOfNumbers[i]); hashTable4[index].getList().add(listOfNumbers[i]); }  
    المخرج النهائي 

     
    مستوى المقال: متوسط

    بواسطه Abdulrahman Hasan Agha , في

  • السلام عليكم ورحمة الله وبركاته 
     
    اسأل الله ان يجعل اجازتكم سعيدة
     
    الدرس الثاني عشر : التغريد بواسطة الاردوينو .

     
    نبذة عن الدرس :
    في هذا الدرس سوف نقوم بعمل اتصال بين الاردوينو و تويتر وذلك لنستطيع إرسال تغريدات إلى تويتر
    من خلال الاردوينو وذلك بإستخدام مكتبة تسمح لاردوينو بالاتصال بتويتر وايضا نحتاج إن نستخدم  درع الواي فاي .
     
    متطلبات المشروع :

    أردوينو أونو

    درع الواي فاي (Wifi shield )
     
     
     
    التوكن (Token) :
    هو مجموعة من الرموز تمكن المكتبة من إستخدام حسابك بتويتر وذلك بعد الحصول على الصلاحيات منك .
     
    الحصول على التوكن :
    1-  قم بزيارة هذا الموقع.
    2- سجل الدخول إلى حسابك بتويتر.

    3- اضغط على زر إعطاء الصلاحيات لتطبيق.4- في نفس النافذة سوف يظهر التوكن الخاص بك. 

     
     
    الكود البرمجي :
    #include <SPI.h> #include <WiFi.h> #include <Twitter.h> //استدعاء المكتبة char ssid[] = ""; // اسم الشبكة المراد الاتصال بها char pass[] = ""; // كلمة السر الخاصة بالشبكة Twitter twitter(""); // التوكن الخاص بك char msg[] = ""; // هنا تقوم بكتابة التغريدة void setup() { delay(1000); WiFi.begin(ssid, pass); delay(10000); Serial.begin(9600); Serial.println("connect"); if (twitter.post(msg)) { int status = twitter.wait(&Serial); if (status == 200) { Serial.println("OK."); // عند ظهور هذه الرسالة تفيد بإن تم نشر التغريدة } else { Serial.print("failed : code "); // عند ظهور هذه الرسالة تفيد بحدوث خطا Serial.println(status); } } else { Serial.println("connection failed."); // هذه الرسالة تدل على حدوث خطا في الاتصال بالشكبة } } void loop() { }  
    رابط تحميل المكتبة Twitter.rar
    لمعرفة كيفية إضافة المكتبة للكود راجع هذا الدرس 
     
    تحدي :
    أجعل الاردوينو تتصل بـ ليد و عندما يتم إرسال التغريدة يضيء الليد .
     
     
    وإلى هنا نصل إلى ختام هذا الدرس 
    أتمنى إني أوضحت المعلومة بشكل المطلوب
    ونراكم إن شاء الله في دروس قادمة .
    مستوى المقال: مبتدئ

    بواسطه وضاح العوني , في

  • Ads Belongs To This website

    عالم البرمجة

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