ארכיון חודשי: מאי 2015

buzz words

הבעיות שיש לי עם תכנות ריספונסיבי

הקדמה

אנחנו חיים בעולם שיש בו המון מילות באזז, כדוגמת big data, responsive design, cloud computing, סייבר וכיוב' …
כל המילים האלו מגיעות מעולם השיווק, אבל לאדם טכני לא באמת אומרות הרבה.

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

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

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

מונחי יסוד

HTML – שפה אשר יודעת לתאר מסמכים ומה המידע שיתקיים בהם, תוך שימוש באלמנטים שבהם המידע יכול להתקיים.

CSS – הם קבוצה של חוקים אשר יכולים לכסות אחד את השני (מכאן השם: Cascading Style Sheet) בצורה שתספק עיצוב למסמך.

הסבר

כאשר אנו מדברים על "תכנון ריספונסיבי", לרוב אנו מדברים על כך שעיצוב המראה עבור המערכת שלנו תתאים להרבה מאוד מסכים בגדלים שונים, אבל אנחנו צריכים לחשוב בתפיסה לגמרי שונה – איך המערכת תתנהג בכל סוג של מכשיר.

בטח תשאלו מה ההבדל בין הדברים.
ובכן, כאשר מדברים על עיצוב, אנחנו מדברים על איך המראה יהיה תחת רזולוציות שונות, אבל למשל תקשורת סלולרית (HSPA) כדוגמת 3G, 4G, LTE וכיוב', אינן נלקחות בחשבון, היות והן מדברות על תעבורה, לא על מראה.

העניין הוא, שהתעבורה של המידע צריכה להילקח בחשבון גם כאשר מספקים מערכת למכשירים שונים.
יותר מזה, אנחנו צריכים לקחת בחשבון את הזיכרון שיש למכשיר, מעבד, גודל אחסון של מידע וכיוב' כאשר אנחנו מתכננים סביבה שהיא "תכנון ריספונסיבי", אבל אלו מעולם לא היו חלק מהיכולת של HTML או CSS. כלומר מסמך HTML אינו מודע לכל זה.

כך שאולי יש מסמך איכותי עם המון מידע, שמעוצב מדהים ויודע להיות מוצג בהרבה רזולוציות, אבל האם הוא באמת יודע להגיב כמו שצריך למגבלות המכשיר אשר המסמך מוצג בו?

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

כאשר יש הבנה לדברים האלו, ולוקחים אותם בחשבון, לרוב מוצאים כי יש שניים או יותר אתרים בשביל להתמודד עם זה: להמשיך לקרוא

הרעיון של תכנון מערכות גמישות – חלק ראשון

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

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

בהרצאה שהעברתי לפני מספר שנים בשם database free application, דיברתי על עיקרון ה actor model, שבו יש לי מערכת פשוטה אשר יודעת לקבל צורך מסויים ולבקש ממערכת מסויימת לבצע את הפעולה ולהחזיר תשובה.

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

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

כך גם הגישה של actor model שבה אנחנו מקבלים משהו שיודע לשלח בקשות ולקבל תשובות, אך זה לא חייב להיות אותו החלק.

גישה נוספת אשר מפשטת מאוד פיתוח, אך קשה יותר לתכנון נקראת micro services.
הרעיון הוא די פשוט ואנחנו מכירים אותו למעשה מעולם היוניקס: יש משהו קטן שיודע לעשות פעולה אחת ורק אותה, ולהחזיר אותה הלאה.
למשל מכירים את הפקודה cat? היא יודעת להציג פלט מתוך "קובץ" – בברירת המחדל ל sdout.
אם נשלב אותה עם sort למשל, נוכל עכשיו לסדר שורות לפי סדר מסויים שנבחר. אם נשלב עוד תוכנה בשם uniq, עכשיו נעיף כל מה שחוזר על עצמו, ונקנח בפקודה tr, אשר תתרגם לנו סוף שורה לפסיק, ועכשיו נשים את הכל בקובץ חדש, והנה יצרנו מערכת יחסית מסובכת המשתמשת בפעולות מאוד מאוד פשוטות.

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

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

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

בנוסף, אני מגלה בזמן התכנון כי אני לא בטוח ששפת ג'אווה לצורך העניין מסוגלת לספק לי מענה נורמאלי לmicro-service בעוד ששפות כדוגמת go, פיתון ורובי דווקא כן מסוגלות. הסיבה לכך היא די פשוטה – מורכבות של מערכת או שפה משפיעים על מה שניתן להשיג ובאיכות של מה שניתן לקבל.
שפת ג'אווה מורכב יותר, וקשה לקבל ממנה פשטות. למשל הקוד הזה בג'אווה, נראה כך ב jRuby. הספרייה היא של ג'אווה, הסביבה היא של ג'אווה, אבל הקוד ברובי ממוקד יותר מטרה, בעוד שג'אווה דורשת ממני הרבה עודפים שבלעדיהם אני לא מסוגל להגיע למטרה.

בחלק הבא, אכנס קצת יותר בצורה טכנית וקצת פחות תיאורטית.