June 10, 2009

Are Components Views and vice versa?

An English translation is available for this post...

המוטיבציה לכתיבת הפוסט שלפניכם הגיעה משיחה קצרצרה שניהלתי בוקר אחד עם קולגה בעבודה, שהעלתה בי סימני שאלה מטרידים מעט בכל הקשור לארכיטקטורת קומפוננטות פלקס אל מול ארכיטקטורת views או יותר נכון Presentation Model. לצורך הדיון, אני אסביר בקצרה מה ה presentation model אומר; אפלקציית פלקס מורכבת בעיקר מרכיבי view שמייצגים את האיזורים השונים בה. View יכול להיות מסך Login, או טאב מסוים. לכל view שכזה יש את ה"ברזלים" שלו, שהם בעצם הקונטרולים הפלקסיים (containers, lists, buttons) ואת הלוגיקה שעומדת מאחור שכוללת את המצבים השונים של ה view ואת החישובים השונים הקשורים ללהתנהגות המצופה ממנו. הלוגיקה תמצא במה שאנחנו נקרא לו presentation model. וכך, כשאנחנו רוצים לבנות view מסוים, הוא חייב להיות מורכב לפחות מ- Class שמייצג את ה view ו-Class שמייצג את ה presentation model. יש המון יתרונות לשיטת פיתוח זאת מעבר להפרדה הברורה בין הרכיבים, אחד מהם, למשל, הוא טסט-אביליות נוחה.
אני בכוונה לא מרחיב מעבר לכך, בכדי לא לבלבל שלא לצורך.
בתור פלקסאי ותיק, אני מכיר את ה-framework של פלקס (לפחות,כרגע, עד SDK 3.x) ומכיר את מבנה הקומפוננטות הפלקסיות כמו Button, DataGrid וכיו"ב. עכשיו, זה נכון שגם שתי הנ"ל הן לכאורה view ולוגיקה הבאה לשמור על state ועל התנהגות מצופה, רק שב- framework הקומפוננטה Button מיוצגת ע"י Class אחד וכך גם DataGrid ועוד.
צורת הארכיטקטורה הזו, של קומפוננטות הפלקס, נראתה לי נכונה, שכן, לא ראיתי את הצורך לחלק את הקומפוננטה לשניים כאשר אין view שמיוצג ע"י MXML (ובמקרה הזה אני עושה את זה יותר עבור נוחות). הקומפוננטות עדיין היו טסט-אביליות, encapsulated ו-reusable.
אם אני אחזור לפתיחה, השאלה שנשאלתי הייתה מה שונה בין קומפוננטה ל-view, ולצורך ההפשטה – במה שונה מסך Login שנבנה בצורה גנרית לקומפוננטת כפתור גנרית? האם זה נכון לבנות קומפוננטת עם presentation model? האם יש מקום למינוח "קומפוננטה" בפלקס בכלל?
אני, כמו שאני, בוקר זה לא בדיוק פרק הזמן שאתם רוצים לפנות אליי בשאלות מהסוג שדורש חשיבה כלשהי, ישר התרעמתי ואמרתי ש"מה זאת אומרת? View זה view וקומפוננטה זו קומפוננ...”, אבל תוך כדי הרגשתי שמשהו חורק בהכרזה הזו. למה באמת לא לעשות קומפוננטות עם presentation model מאחוריהן? נכון לעכשיו, זה נראה לי יותר ויותר פתרון ארכיטקטוני נכון. זה נכון שיש לנו AS שבונה UI, אז מה? מדוע לא לפרק את הלוגיקה מה- view גם במקרה הזה?
אני עדיין מהרהר בזה ולכן אני מפרסם את הפוסט הזה. מאד הייתי רוצה לשמוע מה אתם חושבים ומה דעתכם.
תודה.

The motivation for writing this post in front of you came from a brief coffee-stand conversation I had the other morning, that raised some troubling thoughts and questions to my mind in all that is regarding the view architecture or to be more precise, the “presentation model” architecture.
For the sake of conversation, I’ll explain in short what the presentation model says; Flex application is mostly made of views that represent different areas in it. A view can be a login screen of a tab for that matter. To each view you have the “iron skeleton” which is the flex control (containers, Buttons, Lists) and the logic that stands behind it, which includes the different states of the view and other calculations that makes it work as expected. The logic will reside on, what we call, the Presentation Model class, and so, when we wish to build a certain view it has to made out of (at least) 2 classes. There are many advantages to this kind of architecture, say, easy testability.
I’m not going deeper to this architecture to keep you focused on the main problem.
As a veteran Flex developer I can pretty much say that I know the Flex framework (at least, until SDK 3.x) and know the component architecture like DataGrid and Button, etc. Now, it’s true that the ones I’ve mentioned are, apparently, views and logic that maintain the view states and its behavior, only that in the Flex Framework these components are represented as a single class.
This architecture of the Flex framework seemed right to me, that is, I didn’t see any need to divide the component into two where there is no view that is represented with MXML (in that case I do it for convenience). The components will still be testable, en capsulated and reusable.
If I’ll go back to the beginning, the question I’ve been asked was “what’s the difference between a view and a component?”, and to make things even simpler, what does a generically made login screen any different than a Button component? Is it right to build a component using the presentation model architecture? Is the term “component” is relevant at all in Flex?
I, being myself, don’t react well when people are showering questions at me at the delicate time of the morning, stood up and claimed that “what do you mean? View is a view and a component is a compon…” but then I felt that something is not right in saying that. Why would you not develop a flex component using the presentation model architecture? As for now it seems to be more and more the right way to do it. It’s true that we have the AS building our UI so what? Why not take the logic and states apart from it?
I’m still pondering on it and would very much like to know what you think about this issue
Cheers.

12 comments:

Lior said...

התשובה היא פשוטה.

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

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

FlashMattic said...

אהלן ליאור,
הגישה שאתה מציג היא מעט נאיבית. ה- view שלי לא אמור להכיר את cairngorm. אני לא הרחבתי בכוונה אבל אולי כאן המקום; ה- presentation model מוזרק ל-view (סטייל IOC של ספרינג), כאשר ה- view מצידו מכיר אינטרפייס שהוא עובד מולו. בצורה הזו יש decoupling טוב בין הלוגיקה ל"ברזלים". האימפלמנטציה של הלוגיקה זה כבר משהו אחר, תקרא ל- caingorm או מה שלא יהיה.
אם נסתכל על זה אחרת, תראה למשל view שבתחילה נמצא במקום אחד, אך מאוחר יותר הוא אמור להיות גם במקום אחר באפליקציה. הרבה יותר נוח לעבוד כך, כאשר ה view הוא למעשה קומפוננטה. ההבדל בניהם הם די דק לכאורה. ה view לא אמור להכיר את ה bussiness logic של האפליקציה שלי ולכן אני יכול לשלוח אותו לאוסטראליה בכיף.
מה שאתה אומר הוא שה-presentation model מכיר את cairngorm ובגלל זה הוא שונה מארכיט' של קומפוננטה, אבל זו לא השאלה - השאלה היא מדוע לא להשתמש ב presentation model גם בקומפוננטות. אז שלא יכיר את cairngorm, שרק ישלח החוצה אירועים פלקסיים... זו לא הנקודה.
אתה איתי, אחי?

Lior said...

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

FlashMattic said...

כן, אבל... האם יש מקום למינוחים קומפוננטה או view יחדיו בפלקס?

Lior said...

לא הבנתי, אתה שואל אם עדיין יש מקום להבדיל במערכת בין VIEW לקומפוננטה?

FlashMattic said...

בדיוק,
עכשיו התגובה הראשונית היא "כן!", אבל תחשוב שנייה...

Lior said...

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

Ulysses222 said...

This is is an interesting question, provided the question is well understood.

Anyway, my answer is no. You do not need the presentation model when writing Flex components.

Components are not views as such. Talking about a view make sense only in the broader context of the MVC design pattern (of which the presentation model is derived).

The presentation model is most useful when designing Flex applications, not Flex components.

There are many different ways to architect a Flex application, not so when writing a native Flex component.

When writing a Flex 3 component, you will most probably extend the UIcomponent, and then implement methods like createChildren(), measure(), layoutChildren() and draw(). (The Gumbo component architecture is different : http://opensource.adobe.com/wiki/display/flexsdk/Gumbo+Component+Architecture). The reason why you have not a lot of options is because you're producing a UI element that has to play well with the Flex framework.

When writing a Flex application, you will most probably want to separate business logic from the UI. In this scenario, you can use an architectural framework such as Caingorm or Mate, but you can also achieve the same separation of concerns with Flex-only facilities (binding, events and classes). In both cases, you will probably use a certain version of the MVC design pattern.

In conclusion, Flex applications need a well-designed architecture because they address a wide variety of concerns.

A Flex component by nature addresses one main concern, enriching an existing UI framework.

Hope this adds some insights to the conversation.

Daniel Szmulewicz

FlashMattic said...

Hi Daniel,
Your comment did bring new considerations into our little discussion here. As I understand from what you’re saying, you see the main difference between the two due to the concerns of that entity (view or component) in the application, and the fact that views don’t have to answer the component life cycle… Although… if you check out a view, say and MXML container, (for instance) it’s a UICompoent at the end. It, too, have the same life cycle of the flex components that you can override and so forth.
Could it be true that the reason for not using a presentation model for the components is due to the fact that they (the view and the logic) supposed to be tightly coupled to begin with?

Ulysses222 said...

They are tightly coupled because that's how Adobe wrote them. It would have been different, if they had done it different. Nothing stops you to write a component with more encapsulation. Actually, itwould be a nice exercise. If you try that, tell us your , thoughts, OK? 

Nir said...

I read your talks and i would like to add some thoughts to it.
Let's take for example the Datagrid.
The DataGrid has a kind of presentation model called the dataprovider which is an interface of a list. This allows you implement streaming / simple data providing when using it.

FlashMattic said...

I’m not sure that I understand your point. No doubt in me that this data provider should not know anything about the layout of the data it represents and that’s the way it is on the Flex Framework. If you’ll read this post: http://flashmattic.blogspot.com/2009/06/catalyst-motivation-as-i-see-it.html you’ll see that the new framework named “Spark” pretty much answers the question I raised here. There you have a total separation of the data, logic and layout. My question was more about the decoupling of the logic and layout form the view of the components.
Can you please explain what you meant?
Cheers.