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 كالتالي:
إلى هنا, هذا ما كان في الجعبة ووفق الله الجميع وصلى الله وسلم وبارك
المراجع:
- sourcemaking.com/design_patterns
- java design pattern , rohit joshi
- head first design pattern
التعليقات (0)
لايوجد لديك حساب في عالم البرمجة؟
تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !