יום ראשון, 12 במאי 2013

Transforming message to xml in Camel

Using the XStream jar

 

In Xml

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<dataFormats>
<xstream id="XstreamTransformator"/>
</dataFormats>
<route>
<from uri="direct:messageSource"/>
<marshal ref="XstreamTransformator"/>
<to uri="activemq:queue:myQueue"/>
</route>
<route>
<from uri="activemq:queue:myQueue"/>
<unmarshal ref="XstreamTransformator"/>
<to uri="direct:messageDest"/>
</route>
</camelContext>

In code

from("uri:activemq:queue: myQueue").unmarshal().xstream().to("direct: messageDest");


Switch case in Groovy

Example for switch case in Groovy

myValue = 40
switch (myValue) {
case 'Zvika':
println "you choose Zvika"
break
case 0..44:
println "This is a number between 0..44"
break
case 55:
println "The number is 55"
break
case ~/Zw?+a/:
println "your name starts with Z and ends in a!"
break
case Date:
println 'got a Date instance'
break
case ['God', 'Satan', 'Lotsipar', 'sun']:
println "Got one of the names above"
break
default:
println "Non of the case options "
}

יום שבת, 11 במאי 2013

python has no switch or case or select

 

from Replacements for switch statement in python?

def f(x):
return {
'a': 1,
'b': 2,
}.get(x, 9) # 9 is default if x not found
or 

result = {
'a': lambda x: x * 5,
'b': lambda x: x + 7,
'c': lambda x: x - 2
}[value](x)
example of using the last code receipt:  
theSwitchArray = {
'a': lambda x: x * 5,
'b': lambda x: x + 7,
'c': lambda x: x - 2
}

result = theSwitchArray['b'](3)

print ( result )





Ruby case when


a = 4

case a

when 1..2
puts "It's between 1 and 2"
when 1..5
puts "It's between 1 and 5"
when 6
puts "It's 6"
when String
puts "You passed a string"
else
puts "You gave me #{a} -- I have no idea what to do with that."
end
prints "It's between 1 and 5"
need to override the ===
for an example :
class MyCls2
def initialize (pParam)
  @myValue = pParam
end
 
def GetMyValue
  @myValue
end
 
def === (other_object)
  if  other_object.GetMyValue == @myValue
   true
  else
   false
  end
end
end 
a = MyCls2.new ( 2 )
b = MyCls2.new ( 2 )
case a
when b
  puts " - 1- "
else
  puts "You gave me #{a} -- I have no idea what to do with that."
end
 
 


Linux Kernel kobject and kset

Like IUnknown in com
kobject  has:Parent , Name , Reference count 
A ktype is the type of object that embeds a kobject
A kset is a group of kobjects.
struct uio_mem {
struct kobject kobj;
unsigned long addr;
unsigned long size;
int memtype;
void __iomem *internal_addr;
};
struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj);
 
Init:
 
void kobject_init(struct kobject *kobj, struct kobj_type *ktype);



Associate with the parent  
 
int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...);
 
Get the name :
 
const char *kobject_name(const struct kobject * kobj);
 

Uevents:

 
Notify the word about the new kobject 
 
int kobject_uevent(struct kobject *kobj, enum kobject_action action);
 
KOBJ_ADD or 
KOBJ_REMOVE 
 
 

Reference count:

 

Dec ref count :

void kobject_put(struct kobject *kobj);

 

Inc ref count

struct kobject *kobject_get(struct kobject *kobj);
 
 
Wrap function for creating kobjects 
 
struct kobject *kobject_create_and_add(char *name, struct kobject *parent);
 
a structure protected by a kobject cannot be freed
before its reference count goes to zero
 

Releasing kobject

 

 void learn_object_release(struct kobject *kobj)
{
struct learn_object * thelearnobject = container_of(kobj, struct learn_object kobj);

//Concrate cleaning procedurs

kfree(thelearnobject );
}
 
 
  struct kobj_type {
void (*release)(struct kobject *);
struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
};
 
 

kset

associated kobject sets.

 

subdirectory in sysfs

 

create and delete a kset

 

 struct kset *kset_create_and_add(const char *name,
struct kset_uevent_ops *u,
struct kobject *parent);

void kset_unregister(struct kset *kset);

 

 

In order to assoiate the kobject with a kset

set the kobject kset member before creating the kobject

 

sample source

 

static struct foo_obj *create_foo_obj(const char *name)
0191 {
0192 struct foo_obj *foo;
0193 int retval;
0194
0195 /* allocate the memory for the whole object */
0196 foo = kzalloc(sizeof(*foo), GFP_KERNEL);
0197 if (!foo)
0198 return NULL;
0199
0200 /*
0201 * As we have a kset for this kobject, we need to set it before calling
0202 * the kobject core.
0203 */
0204 foo->kobj.kset = example_kset;
0205
0206 /*
0207 * Initialize and add the kobject to the kernel. All the default files
0208 * will be created here. As we have already specified a kset for this
0209 * kobject, we don't have to set a parent for the kobject, the kobject
0210 * will be placed beneath that kset automatically.
0211 */
0212 retval = kobject_init_and_add(&foo->kobj, &foo_ktype, NULL, "%s", name);
0213 if (retval) {
0214 kobject_put(&foo->kobj);
0215 return NULL;
0216 }
0217
0218 /*
0219 * We are always responsible for sending the uevent that the kobject
0220 * was added to the system.
0221 */
0222 kobject_uevent(&foo->kobj, KOBJ_ADD);
0223
0224 return foo;
0225 }

 

 

 

 

 

 

 

 
 
 
 
 


 

 
 
 
 
 
 
 
 

יום שישי, 10 במאי 2013

ocp והרחבת שיכבת ה Domain של השואב הרובוטי

זהו השואב הרובוטי שלנו :

NovoRobot

אשר חובר באמצעות Wifi למחשב .

Capture10

כל הלוגיקה של השואב (הניווט בין החדרים , מתי לחזור לטעינה , מתי להתריעה על מגירת אשפה מלאה ) במקום להיות בבקר של השואב הועברה למחשב.ונכתבה באמצעות Domain Driven design .

נניח ששיכבת ה BL של התוכנה במחשב בנויה בצורה הבאה :

Capture11

במרכזה של שיכבת ה Domain נמצא לו ה CleaningProcessOrchestrator שמכיל לוגיקה של Workflow .על סמך Events שהוא מקבל מ Entities שונים הוא מבצע החלטות ומפעיל Entities אחרים בהתאם .

 

Capture13

מבחינת Deployment של ה packages המערכת נראתה כך:

Capture14

הכל עבד על מי מנוחות עד אשר הגיעו דרישות חדשות .

קודם כל הגיע מכשיר חדש די דומה. ה Sensor יחיד ובודד שודרג אבל הלוגיקה של CleaningProcessOrchestrator נשארה אותו הדבר .

את אותו ה package של ה Domain שיכבת ה BLL פיצלנו 3 package שיכיל את כל המרכיבים המשותפים ועבור כל מכשיר יהיה package יעודי עם הclassים הקונקרטים רק לו.

 

Capture15

ה packages הקונקרטים נשארו מאוד אנמיים ומכיוון ש CleaningProcessOrchestrator נשאר כמעט אותו הדבר ועל מנת להימנע משכפול קוד הוחלט  להשאיר את ה CleaningProcessOrchestrator ב Base Domain package .

גישה לEntities השונים מתבצעת באמצעות פנייה ל EntitiesRepository אשר מביאה  Entity קונקרטי .

Capture16

למה לא בחרנו פשוט לרשת מ CleaningProcessOrchestrator ל Class קונקרטי ?

כי לא היה כל הבדל בין הלוגיקות הנדרשות רק ה sensor השתנה .אם היינו יוצרים CleaningProcessOrchestrator יעודי הדבר היה גורר עבודה ולוגיקה נוספת בתוכנית אשר רצינו להימנע ממנה .

אח”כ באה דרישה חדשה לעשות מערכת שדומה מאוד לקודמת למעט תיפקוד מיוחד כאשר צריכם לבא אורחים ויש להאיץ את פעולת השואב.

נפתח את הכל ונשנה ארכיטקטורה ? לא חבל בסך הכל נדרש שינוי מינורי ב CleaningProcessOrcastrator שלנו.

כל שינוי בהמשך הוסף ל CleaningProcessOrchestrator היחיד עוד תנאי בסגנון :

if mCurrentWorkingMode == BeforeGuestsAreComing 
mBrushesEntities.SetSpeed (MaxSpeed)
end



דבר שגרם CleaningProcessOrchestrator לגדול ולהפוך לclass אשר קשה לתחזוקה ,מה גם שכל שינוי היינו צריכים לבדוק את כל המערכות הקיימות  מחדש.


המצב הלא רצוי הזה נגרם מהפרה של עקרון הocp. ה class של CleaningProcessOrchestrator אשר שכן לו בשכבה משותפת היה אמור להיות סגור לשינויים ופתוח רק להרחבות על ידי ירושה. בכל זאת הוא  שונה כל הזמן .


הפתרון של להגדיר את ה  CleaningProcessOrchestrator כ Abstract  ועבור כל תצורה של מערכת לרשת ממנו וליצור class קונקרטי גם יוצר בעיה מימושית עקב העובדה שבתצורות השונות יש הרבה לוגיקה משותפת .


Capture17


הפתרון שבחרנו הינו להגדיר את הלוגיקה של CleaningProcessOrchestrator בקובץ קונפיגורציה כדוגמא באמצעות spring integration , camel  או WF .


בפוסטים הבאים אי ארע דוגמאות של כל אחד מהטכנולוגיות הנל לפתרון הבעיה .

יום חמישי, 9 במאי 2013

ניתוח מטלת קידוד מראיון עבודה

במסגרת תהליך מיון המועמדים לעבודה בתחום התוכנה אצלנו אחת הבחינות המרכזיות הינה מטלה בה המועמד מתבקש לקודד תוכנית .

התוכנית הינה מורכבת מפנייה למאגר נתונים , ניהול טופס וכד לא משהו לא שיגרתי  (לדוגמא ניהול תור של סדרן של תחנת מוניות ) כאשר הטכנולוגיות בהן המעומד יכול להשתמש הינן פתוחות לגמרי כל שפת תכנות שהיא  החל מ  Cobol  , turbo c  וכלה ב groovy  , כל טכנולוגית ui  שהוא ירצה :Wpf , QT , MFC  וכל סוג מאגר נתונים שהוא ירצה (כבר נתקלתי במועמד שהשתמש ב Neo4j ולקח את הפתרון לכיוון מאוד יפה ) כמובן אם מועמד ינסה לפתור את הבעיה תוך שימוש ב Hbase  אני ארים גבות ככה שיונית לוי תוכל רק לקנא .

בסה”כ לא היו הרבה מועמדים שהשתמשו בטכנולוגיות איזוטריות רובם פתרו את התרגיל או ב #C עם sql server  או בjava אפשר היה לספור על יד אחת את אילו שפתרו את התרגיל ב python , ruby וכד

עצם בחירת הטכנולוגיה למימוש על ידי המועמד כבר מלמדת אותי על איזה טכנולוגיה הוא חזק שולט ובעל נסיון .

כאשר אני בודק את התרגיל שמועמד קודד אני שם דגש על הדברים האילו :

Maintainability

.המועמד הכי טוב והכי מבטיח חצי שנה אחרי שיתחיל לעבוד אצלנו יקבל הצעה מפתה וישאיר אותנו גלמודים ובודדים עם לב שבור וקוד שאנו נצטרך להתמודד לתחזק אותו ומי אוהב לתחזק קוד של מישהו אחר ?  לכן תכונה של הקפדה על קידוד קוד קריא ברור ופשוט הינה אחת התכונות המרכזית במועמד שאנו מחפשים . דוגמאות לנקודות עליהן אני שם דגש הינן:

שמות של משתנים :

Foreach ( var next in myList)

לאומת

Foreach ( Taxi nextTexyWaitingInLine in mTexiesInLineList)

שמות של פונקציות

פונקציה ששמה מתחיל  ב Get  או ב Check  לא יכולה לבצע שינוי state  .

GetNoOfWatingTexiesInLine לדוגמא יכולה לשמש רק לצורך הבאת מספר המוניות בתור .אסור לה להציג התראה שאין אף מונית יותר בתור.

שם של פונקציה אמור לשקף את מה שהיא עושה   .

פונקציה בשם UpdateTime  ב class  : של Taxi מה תפקידה בכח ????

לאומת UptadeTaxiArrivalToLineTime

אני פחות שם דגש על תעוד של הקוד כי זה שבר שכל מעומד ירצה להרשים באמצעותו

האם המועמד הינו מפתח תוכנה או סתם code monkey?

המנעות מGOD anti pattern - כלומר חלוקה גרנולרית של התוכנית ל class ים במידה הנכונה. לא סתם class של Taxi שמכיל את כל ה state וה logic בתרגיל אלא חלוקה נכונה של הפתרון ל class ים .לדוגמא class של תחנה שמכיל reference לqueue של ה מוניות .וחשיבה יוצרת של שאלות כדוגמת איזה Entity צריך לענות : איזה מונית הבאה בתור לקבל נסיעה ?

כאשר מועמד שמציג פיתרון מבוסס על Domain driven design  עם כל הפינוקים של הפרדה בין entities  , values  ו services  , שיכבת applicaition  שמתזמרת את שיכבת ה Doamin  וכד מקבל בונוס שמן.

Cohesion גם ברמת הפונקציה וגם ברמת הclass , class בשם Helper שמכיל פונקציות ללא כל קשר בניהם הינה דוגמא קיצונית לכך .

הקפדה על עקרונות : Dry , KISS וYAGNI – האם צריך שTaxi ירש מCar שתירש מvehicale ? (מי צריך או אי פעם יצטרך את זה )

עקרונות solid בעיקר SRP

מתי משתמשים ב function ומתי ב property ב class .

 

הקפדה על קוד יציב וחזק

הבנה היכן פונקציה יכולה להיכשל וטיפול נכון בכישלון אפשרי .

הקפדה על טיפול נכון ב exceptions  : לדוגמא פוקנציה שפונה ל בסיס נתונים להחזיר רשומה כולשהיא  והconnection  לבסיס הנתונים נכשל לא צריכה להחזיר רק רשומה ריקה , אלא להתריע בפני המשתמש על הבעיה .

Logging !!!

מועמד אשר מצרף unit test  מקבל אצלי נקודות זכות .

לסיכום מטלת התיכנות הינה כלי חשוב ומרכזי אצלי בהערכת מועמד למישרת תיכנות ,פתרון עובד לא בהכרח יזכה את המועמד בעבודה או במלוא הטנא של נקודות אלא יש משתנים רבים שנגזרים מאיכות הקוד והDesign של הפתרון.