الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

الحلقة الرابع : Iterator Pattern

مغلق
بدأه الحسين في 3 فبراير 2005 · 0 رد · 1,163 مشاهدة · في منتدى تطوير المواقع بـ PHP
مشاركة: واتساب X فيسبوك تيليجرام
#1

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

الحلقة الرابع : Iterator Pattern

أو نمط الحلقات التكرارية أو نمط إعادة التكرار

تابع معي النقاط التالية

النقطة الأولي :

دائما ما نحتاج عمل حلقة تكرارية Looping باستخدام جمل ال for أو حلقات ال while أو do while

فلو طلبت منك مثلا أن تقوم بكتابة كود يقوم بطباعة مجموع الأعداد لمصفوفة ما

ربما لأسرعت وقمت باستخدام حلقة تكرارية من نوع for للقيام بذلك

ولكني أري علي الطرف الأخر مبرمج أخر قد قام بكتابة الكود مستخدما جملة while أو ربما جملة do while

وكلا له فكره الذي يوصله للنتيجة

دعني أعرض عليك أمر أخر , ماذا لو قلت لك أني أريدك أن تقوم بتصميم كود يقوم بسرد أسماء الملفات الموجودة بفهرس ما folder وليكن c:\\windows

ثم قلت لك أني أريدك أيضا أن تقوم بسرد أسماء الفهارس الموجودة بفهرس ما

فربما سنجد من يقوم بعمل حلقة تكرارية مستخدما جملة for والأغلبية سوف يستخدم جملة while

ثم هب أنني طلبت منك طلب أخر ( وأرجو أن تتحملني بصدر رحب )

أريدك أن تقوم بسرد محتويات جدول ما وليكن اسمه students مرة من قاعدة بيانات من نوع مزود الخدمة MySQL ومرة من

قاعدة بيانات Access ومرة من نوع SqlServer و كمان Oracle

ربما سوف تميل لإستخدام جملة while

بعد كل هذه الحالات السابقة , ربما يتبادر في أذهننا تسائل هل يوجد طريقة ما لتوحيد وسيلة إجراء هذه المهام ؟؟؟!!!

النقطة الثانية :

تخيل معي الحالة التالية , أنك تعمل كعضو في فريق عمل كبير ربما لا يري أو يعرف بعضهم بعض (وربما تتعرض لهذا يوما ما)

ولنقول أن هذا الفريق مقسم إلي قسمين مثلا هما قسم A وقسم B

وأعضاء الفريق بقسم A هم الأعضاء الأكثر خبرة والمسئولين عن تصميم البنية التحتية للمشروع اي هم المسئولين عن تصميم المكاتب البرمجية

التي سوف يستخدمها أعضاء الفريق B لإتمام مهامهم

فهب أنه قد طلب من العضو رقم 3 بالفريق B أن يقوم بتصميم صفحة تقوم بعرض الوظائف الجديدة من جدول باسم jobs

لذلك سوف يقوم هذا العضو بالبحث في وثائق مخطط الدوال والفئات التي قام بتصميمها الفريق A ,

عن دالة function تقوم بإرجاع مصفوفة تحمل الوظائف الجديدة , وفعلا نجده بعد وقت قليل قد عثر علي وظيفة باسم getNewJobs

تقوم بإرجاع مصفوفة تحمل الوظائف الجديدة , وقد تبقي له أن يقوم بإستدعاء هذه الدالة ثم يقوم بعمل حلقة تكرارية داخل هذه المصفوفة لعرضها

بمحتوي الصفحة بنسق html , مممممممم ولكن ماذا بعد

فلو تركتك وقت ما حتي تفكر مع نفسك لوجدت أن العضو الموجود بالفريق A الذي قام بتصميم وبرمجة الدالة getNewJobs

قد أدي لإيقاع العضو رقم 3 بالفريق B في ورطة , ما هي هذه الورطه ؟؟؟

تخيل معي أن الجدول المسمي jobs يحتوي علي 30 سجل للوظائف الجديدة

فكما نعلم أو نتوقع أن الكود الموجود بالدالة getNewJobs سوف يقوم بتعريف مصفوفة ما تكون المسئولة عن حمل محتوي الجدول السابق

ثم سوف يتم عمل حلقة تكرارية وبالطبع سوف يتم ملء هذه المصفوفة داخل هذه الحلقة التي سوف تتكرر 30 مره , ثم بعد ذلك يتم إرجاع هذه المصفوفة

ثم يأتي العضو رقم 3 (المسكين) القاطن بالفريق B بإستدعاء هذه الدالة ثم يخزن القيمة العائده منها في مصفوفة جديدة

وحتي يتمكن من عرض هذه السجلات بشكل منسق يقوم بعمل حلقة تكرارية أخري تلف داخل المصفوفة السابقة

وكم لاحظنا أنه سوف يتم الدوران لعدد 30 مره جديدة لعرض المحتوي بالصفحة

لذلك قد تكلفنا في المحصله 60 دوره حتي نعرض 30 سجل فقط

وهذه الورطه ربما في بعض الأحيان تكون بسيطة ولكن دائما ما تكون ورطه غير هينه لما يترتب عليها من تكلفه في وقت تنفيذ الكود

ولكن ما هو الحل ؟؟؟

أنتهي .

نقطه جانبية فلسفية (شخصية)

دائما ما تكون الحلول وليدة المشاكل

فعندما تواجه في حياتك البرمجية أو حتي الشخصية مشكلة ما , فاعلم أن هذه المشكلة ستكون وليدة لشئ جديد في حياتك .

دعنا من الفلسفة الأن ولنعد سريعا إلي ما قد كنا بدئنا الحديث عنه

نمط Iterator Pattern أو نمط الحلقات التكرارية

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

تابع المخطط التالي

IteratorPatternDiagram.gif

الفئة الأم Iterator

يتم في هذا النمط تصميم فئة باسم Iterator تكون بمثابة الفئة الأم لكل الفئات التي نريد أن يتوفر بها هذا النمط

وتتميز هذه الفئة بالتالي :

- أنها فئة مجردة abstract class اي لا يمكن أن نقوم بتخليق كائنات منها (إن صح التعبير)

- تحتوي علي الوظائف التالية :

+ size : وتقوم هذه الوظيفة بإعلامنا بعدد العناصر للمصفوفة الهدف

+ reset : تقوم بإعادة موشر الإنتقال pointer إلي وضع الصفر اي وضع البداية

+ fetch : تقوم بإرجاع عنصر واحد فقط من المصفوفة الهدف , ثم تقوم بتحريك مؤشر القراءة إلي الأمام (اي حركه تزايدية بمقدار عنصر واحد)

وهي كما يلي

<?
class Iterator
{
    function Iterator() {
        die("Iterator is abstract class");
    }

    /**
     * Fetches an element from the collection and moves the internal
     * pointer forward one
     *
     * @return variant
     */
    function fetch() {
        die("fetch method must be implemented");
    }

    /**
     * Returns the number of elements in the collection
     *
     * @return int
     */
    function size() {
        die("size method must be implemented");
    }

    /**
     * Resets the collection pointer to the start
     *
     * @return void
     */
    function reset() {
        die("reset method must be implemented");
    }
}
?>

أما بالنسبة للإصدار الخامس php5 يفضل أن نقوم بتصميم الفئة الأم Iterator بحيث تكون عبارة عن واجهة interface كما يلي

<?
interface Iterator
{
    /**
     * Fetches an element from the collection and moves the internal
     * pointer forward one
     *
     * @return variant
     */
    public function fetch();

    /**
     * Returns the number of elements in the collection
     *
     * @return int
     */
    public function size();

    /**
     * Resets the collection pointer to the start
     *
     * @return void
     */
    public function reset();
}
?>

ملحوظة : توفر لنا اللغات الحالية مثل الجافا ولغات الدوت نت والإصدار الخامس لل php فئة داخلية تكون بمثابة الفئة الأم لنمط Iterator

بشكل مختلف قليلا ولكن بنفس الفكر , وربما أتطرق لشرح هذا الأمر لاحقا كتابع لهذا الدرس .

الفئات المشتقة inherited classes

- فئة ListIterator

وهي فئة خاصة للتعامل مع الحلقات التكرارية الخاصة بالمصفوفات العادية , وهي كما يلي

<?
class ListIterator extends Iterator
{
    var $arrayList;

    function ListIterator(&$array) {
        $this->arrayList = &$array;
    }

    function fetch() {
        $element = each($this->arrayList);
        return $element['value'];
    }

    function size() {
        return count($this->arrayList);
    }

    function reset() {
        reset($this->arrayList);
    }
}
?>

- فئة MysqlIterator

وهي فئة خاصة للتعامل مع الحلقات التكرارية الخاصة بقاعدة بيانات من نوع Mysql , وهي كما يلي

<?
class MysqlIterator extends Iterator
{
    var $result;

    function MysqlIterator( &$result ) {
        $this->result = &$result;
    }

    function fetch() {
        return mysql_fetch_array($this->result);
    }

    function size() {
        return mysql_num_rows($this->result);
    }

    function reset() {
        return mysql_data_seek($this->result,0);
    }
}
?>

- فئة FileIterator

وهي فئة خاصة للتعامل مع الحلقات التكرارية الخاصة بقراءة محتويات ملف ما , وهي كما يلي

<?
class FileIterator extends Iterator
{
    var $fp;

    function FileIterator( &$fp ) {
        $this->fp = &$fp;
    }

    function fetch() {
        if( !feof($this->fp) )
            return fgets($this->fp, 4096);
        else
            return false;
    }

    function size() {
        $i=0;

        $this->reset();
        while( $this->fetch() ) {
            $i++;
        }
        $this->reset();
        return $i;
    }

    function reset() {
        fseek ($this->fp, 0);
    }
}
?>

- فئة DirectoryIterator

وهي فئة خاصة للتعامل مع الحلقات التكرارية الخاصة بالفهارس directories , وهي كما يلي

<?
class DirectoryIterator extends Iterator
{
    var $dir;

    function DirectoryIterator( &$dir ) {
        $this->dir = &$dir;
    }

    function fetch() {
        return $this->dir->read();
    }

    function size() {
        $i=0;

        $this->reset();
        while( $this->fetch() ) {
            $i++;
        }
        $this->reset();
        return $i;
    }

    function reset() {
        $this->dir->rewind();
    }
}
?>

ويمكننا عمل فئات أخري حسب الحاجة لذلك ولكنني أكتفي بهذه الفئات المشتقة لأنها تكفي معظم حاجاتنا

مثال تطبيقي بسيط

نريد تصميم صفحة بسيطة جدا تقوم بسرد محتويات فهرس ما وليكن الفهرس الهدف هو c:\php

الحل إستناد علي الفئات السابقة يمكننا فعل التالي :

DirectoryTest.php

<?
require_once "lib/DirectoryIterator.php";

// Modify this to some directory
$dir = dir("c:\\php");
$iterator = new DirectoryIterator($dir);

echo ( "<b>Number of results:</b> ".$iterator->size()."<br />\n" );
while ( $element = $iterator->fetch() ) {
    echo( $element . "<br/>" );
}

$dir->close();
?>

مثال تطبيقي بسيط أخر

نريد تصميم صفحة بسيطة تقوم بسرد محتويات ملف ما وليكن الملف التالي c:\php\install.txt

الحل إستناد علي الفئات السابقة يمكننا فعل التالي :

FileIteratorTest.php

<?
require_once("lib/FileIterator.php");

// Modify this to point at a real file
$fp=fopen("c:\\php\\install.txt",'r');
$iterator = new FileIterator($fp);

echo ( "<b>Number of Lines:</b> ".$iterator->size()."<br />\n" );
while ( $element = $iterator->fetch() ) {
    echo($element . "<br/>");
}

fclose($fp);
?>

مثال تطبيقي بسيط أخر

نريد تصميم صفحة بسيطة تقوم بسرد محتويات جدول ما بقاعدة بيانات من نوع mysql

وليكن الجدول الهدف هو جدول user الموجود بقاعدة البيانات mysql

الحل إستناد علي الفئات السابقة يمكننا فعل التالي :

MysqlIteratorTest.php

<?
require_once("lib/MysqlIterator.php");

// Modift these and the query to some database / table of your own
mysql_connect('localhost', 'root', '') or die(mysql_error()); 
mysql_select_db('mysql') or die(mysql_error()); 

$sql = "SELECT * FROM user";
$result = mysql_query($sql);
$iterator = new MysqlIterator($result);

echo ( "<b>Number of results:</b> ".$iterator->size()."<br />\n" );
while ( $element = $iterator->fetch() ) {
    echo( $element["Host"] . "<br/>");
}

mysql_free_result($result);
?>

أعتقد أننا لاحظنا من الأمثلة السابقة أننا قد وحدنا فكرنا, والأن نقوم بعمل الحلقات التكرارية علي اي هدف بنفس الطريقة ,

دعنا الأن نعود لمثال الفريق A والفريق B حتي تزداد الصوره وضوح

مثال تطبيقي أخر

كما قد عرضنا سابقا حالة هذا المثال المتنقل بين الفريقيين A و B

وسوف يكون الجدول المراد التعامل معه هو جدول ال Jobs وهو كما يلي

#
# Table structure for table 'jobs'
#
CREATE TABLE jobs (
  JobID tinyint(3) unsigned zerofill NOT NULL auto_increment,
  JobTitle varchar(255) default NULL,
  IsNew tinyint(1) unsigned default NULL,
  PRIMARY KEY  (JobID),
  UNIQUE KEY JobID (JobID)
) TYPE=MyISAM;

#
# Dumping data for table 'jobs'
#
INSERT INTO jobs VALUES("001", "مطلوب مبرمج php", "1");
INSERT INTO jobs VALUES("002", "مطلوب مبرمج asp", "1");
INSERT INTO jobs VALUES("003", "مطلوب بائع لمحل مجوهرات", "0");
INSERT INTO jobs VALUES("004", "مطلوب مضيف ليس حسن المظهر", "1");

الحل بالنسبة للعضو بالفريق A

سوف يقوم بتصميم دالة باسم getNewJobs تقوم بإرجاع كائن من نوع الفئة Iterator

وفي مثالنا هذا سوف يكون الكائن من نوع الفئة MysqlIterator

وهي كما يلي

Jobs.php

<?
require_once("lib/MysqlIterator.php");

function getNewJobs() {
    // Modift these and the query to some database / table of your own
    mysql_connect('localhost', 'root', '') or die(mysql_error()); 
    mysql_select_db('test') or die(mysql_error()); 

    $sql = "SELECT * FROM jobs where IsNew=1";
    $result = mysql_query($sql);

    return new MysqlIterator($result);
}
?>

ثم يقوم العضو رقم 3 بالفريق B بتصميم الصفحة الخاصة بعرض أحدث الوظائف كما يلي

NewJobsView.php

<?
include_once "Jobs.php";

$iterator = getNewJobs();
while ( $element = $iterator->fetch() ) {
    echo( $element["JobTitle"] . "<br/>");
}
?>

وهكذا لا يتم عمل مضاعفة في عدد الدورات التي تم التنبيه عنها سابقا

إلي اللقاء بإذن الله مع نمط جديد

وبالله التوفيق

والسلام عليكم ورحمة الله وبركاته

Iterator Pattern Examples.rar

تم تعديل هذه المشاركة بواسطة الحسين في 3 فبراير 2005 في 21:42

29_5.gif

سورة العنكبوت

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

مشروع Arabic PHP.NET

حلم طالما كان يراودني حتي قهرته بحمد الله ليكون حقيقة

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

سلسلة أنماط التصاميم البرمجية Desgin Patterns

سلسلة أنماط التصاميم البرمجية Desgin Patterns | كتيب هذه الدروس (إعداد أحمد غريب)

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

كنترول ASP.NET DataGrid CheckBoxColumn

كنترول ProgressBar

كنترول UltraPanel

مشروع الكنترول الأنيق (إهداء للفريق العربي)

الورش الإلكترونية IT Workshops

تعقب الأخطاء error tracing

كنترول ColorPicker لمطوري الويب

RichTextBox Control لمطوري ال ASP.Net

حمل كتاب جافا سكربت عربي

هذا الموضوع مغلق.

مواضيع مشابهة