مرحباً. منذ زمن لم أكتب شيئاً تقنياً.

والآن جاء الوقت لكي أعطيكم جرعة قاتله من المواضيع التقنية ^^. سأبدأ بهذه الفكرة التي إكتشفتها اليوم. ربما تبدو غريبة لمبرمجي الجافا لكنها عملية جداً وتفيد لصنع كود قابل لإعادة الإستخدام وكي نطبق مبدأ (عدم إختراع العجلة!). بعد المقدمة، أبدأ بالزبدة.

الفكرة وما فيها هي وضع طريقة أفضل وأكثر عملية للبرمجة الكائنية وخصوصاً الـSetter والـGetter للفئات.
(تحتاج لفهم هذا دراسة أساسيات لغة الجافا أو أي لغة برمجة تدعم oop وكذلك دراسة البرمجة الكائنية OOP بها، إن لم تكن كذلك فلا تقرأ المقال!).

ربما كما درست فإن مبرمجي الجافا يفضلون وضع Setter وGetter لكل خاصية(Properties) في الصنف بدلاً من ترك الخاصية public للسيطرة عليها في حال طرأ تغيير عليها. وهي طريقة جداً جملية حيث بها تضمن قلة الأخطاء إلى أدنى حد ممكن. خصوصاً إذا كنت مطور مكتبات (Programming Libraries) أو مطور SDK ولو كانت صغيرة. سترى أن هذا الأمر مهم جداً للسيطرة على الكود وإدراته وإستخدام ميزات oop بأفضل وجه (تابع قراءة المقال).

لكن الطريقة العادية في وضع الـSetter, Getter طريقة سيئة برأيي. وندرسها نحن في مقرر الـJava-oop كطلاب علم الحاسوب.

مثلاً someDot هو كائن من الصنف Dot3D لديه ثلاث خواص هم x, y, z يمثلون موقع النقطة في مستوى الأحداثيات.
لو أردنا التحكم بالخواص من خلال وضع Setter, Getter لكل واحدة سنقوم بوضع الـMethods كما نعرف وكالمعتاد سنعرف الصنف وسينتج كائن someDot قابلاً للإستخدام كالتالي:

// Set values
someDot.setX(10);
someDot.setY(13);
someDot.setZ(48);

// Print them
System.out.println("X: " + someDot.getX()
+ ", Y: " + someDot.getY() + ", Z: " + someDot.getZ() );

ألا ترى ان هذه العملية مزعجة؟ أن تقوم بإسناد القيم لكل خاصية بواسطة Setter مستقل؟ ماذا لو كان هناك Setter يعمل بصورة متفاعلة بحيث تعطيه الخاصية وقيمتها أو الخواص وقيمهم، وبدون ترتيب إجباري؟ أو عدد معين من الخواص؟؟ هل تريد طريقة تختصر عليك الكتابة بأفضل وجه؟ وبكود مفهوم؟ هذا ما فعلته!

أنظر هذا الكود، وتعلم كيف ستستطيع وبكل سهولة الحصول على واحد مثله بيدك!، لاحظ الشرح بعد الكود:

someDot.x(10);
someDot.y(20);

هنا وضعنا قيمة لكل من x, y. بواسطة Setter سهل التذكر! وكذلك إملائياً سهل أن تفهم ماهو!

someDot.x(20).y(120);

هل رأيت هذا الكود! أليس أجمل؟ إسندنا القيم لكليهما في نفس الأمر!

someDot.z(10).x(24).y(10).x(20);

وهذا! بعد! هل رأيت تغيير أربع قيم! من ضمنها القيمة س مرتين، لا يوجد ترتيب إجباري ولا عدد معين من المرات للتغيير.

ربما تفكر الآن وكيف نأخذ القيم بواسطة Getter وبنفس السهولة؟؟ شاهد الأكواد التالية وأنظر الشرح بعد كل واحد:

int a = someDot.x();

الفرق بينهما أن عند إسناد قيمة يجب أن تمررها داخل الطريق (ميثود)ـ
أما عند طلب الحصول على القيمة ببساطة! لا تمرر وسيط (parameter) وتحصل على القيمة الحالية لها!

int num = someDot.x(20).y(50).z();

نستطيع المزج في الأمر الواحد بين عدة مسندات (setter) وفي النهاية محصل واحد (getter)
في هذه الحالة نحن نسند قيمة لكل من x، y وبعدها نأخذ قيمة z ونضعها في المتغير (num)

هذه الفكرة لوجه الله أضعها لكم كي تستفيدوا منها :). وملاحظة، هذه الطريقة متبعة في بعض المكتبات مثل jQuery، مع أنها ليست في لغة جافا لكن لا بأس أن نتعلم منهم.

هل رأيت؟ ما رأيك بالفكرة؟؟ لدي لك مفاجأة .. الكود الكامل لكيفية عمل ذلك!
أنظر الصفحة التالية من هنا.

هذا الكود، المطلوب أن تفهمه أنني علمت نفس الطريق (Method) لكل خاصية بنفس الإسم. يعين الخاصية أسميها (pX) وإسم الطريقين (Method) هما x الأول وهو Getter ومن نوع القيمة التي يضعها مثل int, char, double أو أي كان!. والثاني وهو الـ Setter وهو من نوع الكائن نفسه حيث أنه يحتوي على جملة Return ترجع نفس الكائن بواسطة this. وكذلك يسند القيمة الممررة إليه إلى الخاصية (Properties) المطلوبة وفي هذه الحالة x.

في هذه الحالة يجب أن تعلم أنني عملت Overload لكل طريق (Method) مرتين الأول بشكل Setter والثاني Getter!

حمل الكود بملف جافا من هنا  BetterGetterAndSetter.java

(الكود هنا ملون لكن إن اردت الكود كاملاً بشكل ملف جافا حمله وإفتحه بمحررك المفضل مثل Eclipse, NetBeans, NotePadpp

/*
    Better OOP by making cleaner Setter, Getter!
    For eazier programming.

    Copyright (C) 2009  Omar Al-Dolaimy (http://www.omardo.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import java.util.*;

public class ReturnThis {
	public static void main (String args[]) {
		Scanner scan = new Scanner( System.in );
//		تعريف الكائن
		Dot3D someDot = new Dot3D();

//		SETTERS
//		 إسناد قيمة س، ص بالطريقة المختصرة
//c            وهي أشبه بالطريقة القديمة لحد الآن 		
		someDot.x(10);
		someDot.y(20);

//		أنظر هذا الإختصار أليس أفضل؟
		someDot.x(20).y(120);

//		أو هذا
		someDot.z(10).x(24).y(10).x(20);

//		وأنظر الآن جمال الفكرة! أن 
//		 Setter looks like getter!
//			GETTERS!
		int a = someDot.x();
/*
//		الفرق بينهما أن عند إسناد قيمة
يجب أن تمررها داخل الطريق (ميثود)ـ             //
 	أما عند طلب الحصول على القيمة ببساطة!       	//
لا تمرر وسيط (بارميتير) وتحصل على القيمة الحالية لها //

// 		Getters After Setter!
// 		تستطيع المزج في الأمر الواحد بين عدة
                مسندات (سيتير)
 وفي النهاية محصل واحد (كيتر) أنظر التالي:
*/
		int num = someDot.x(20).y(50).z();
//		في هذه الحالة نحن نسند قيمة لكل
من س، ص وبعدها نأخذ قيمة ع ونضعها في المتغير (نام)ـ            //

// 		هذا مثال لطباعة قيم س، ص، ع للكائن. الكود
// نظيف وبسيط وواضح!

		System.out.println("X: " + someDot.x() + ", Y: " 
      + someDot.y() + ", Z: " + someDot.z() );
	}
}

class Dot3D {
	// Properties || Dimentions
	private int pX=0, pY=0, pZ=0;

	// Setter's
	public Dot3D x(int val) {
		pX = val;
		return this;
	}

	public Dot3D y(int val) {
		pY = val;
		return this;
	}

	public Dot3D z(int val) {
		pZ = val;
		return this;
	}

	// Getter's
	public int x() {
		return pX;
	}

	public int y() {
		return pY;
	}

	public int z() {
		return pZ;
	}

}

/*
// OLD WAY TO SET, GET!
// Set values
someDot.setX(10);
someDot.setY(13);
someDot.setZ(48);

// Print them
System.out.println("X: " + someDot.getX() + ", Y: "
                    + someDot.getY() + ", Z: " + someDot.getZ() ); 

*/

------------------------------

أو حمل الكود بملف جافا من هنا  BetterGetterAndSetter.java