SlideShare a Scribd company logo
1 of 58
360|Flex DC, September 2010




     Re-architecting the
designer-developer workflow


          Richard Lord
         Technical Architect
Coming Up



     A story

   Lots of code

A new architecture
The Set-up
At BrightTALK we do webcasting
At BrightTALK we do webcasting
We have a set of standard players on our website
and we create custom players for specific clients.
Old workflow




Client     Designer     Developer
May 2008
A new player (using Cairngorm!)
Restyling with CSS
Goran (Lead Designer)
November 2008
Another client project (using Mate)
Meanwhile, Goran did something very un-designer
He built a widescreen player




Using the code from another player
This gave me an idea
Since our designer can write MXML, can we
enable him to build an app using only MXML?
January 2009
Components version 1
Too much influence from Mate
Too many non-visual components
Can we build an app using only visual MXML?
May 2009
Smart components
Smart components contain the view
  and associated functionality.
Smart components can find
  and talk to each other.
Designers choose smart components
based on user-interface functionality.
Designers assemble the user-interface,
    and the application just works.
Designers apply skins and css to the
smart components to design the app
The approach


•   Flex 3

•   Dependency injection (with SmartyPants-IOC)

•   Simple event bus

•   Test driven development

•   Lots of refactoring

•   MVC is NOT a requirement
... Live Code ...
(a twitter client)
MXML


<mx:Application>
  <tw:TwitterContext/>



<mx:VBox>
    <tw:TweetsList/>




<mx:TextInput
id="searchInput"/>




<tw:SearchButton
label="Search"
searchTerm="{searchInput.text}"/>


</mx:VBox>
</mx:Application>
The context is the only non-visual component.
It configures the dependency injection container.
TwitterContext
public
class
TwitterContext
implements
IMXMLObject
{
  [Inspectable]
  public
var
oauthConsumerKey
:
String;
  [Inspectable]
  public
var
oauthConsumerSecret
:
String;

  public
function
initialized(
document
:
Object,
id
:
String
)
:
void{
    createContext();
    listenOnDisplayList(
document
);
  }

 

  private
function
createContext()
:
void
{
    injector
=
SmartyPants.getOrCreateInjectorFor(
this
);
    injector.newRule().whenAskedFor(
EventBus
).useSingleton();
    injector.newRule().whenAskedFor(
TweetCollection
).useSingleton();
    injector.newRule().whenAskedFor(
User
).useSingleton();
    injector.newRule().whenAskedFor(
AuthManager
).useSingleton();
    injector.newRule().whenAskedFor(
IOAuth
).useValue(

      new
OAuth(
oauthConsumerKey,
oauthConsumerSecret
)
);
  }
}
The other components are
the SearchButton and the TweetList.
SearchButton

public
class
SearchButton
extends
Button
{


   [Inject]

   public
var
manager
:
SearchManager;


   [Inspectable]

   public
var
searchTerm
:
String;


   public
function
SearchButton()
 {

   
 addEventListener(
MouseEvent.CLICK,
performSearch
);

   }



   public
function
performSearch(
event
:
MouseEvent
)
:
void
{

   
 manager.search(
searchTerm
);

   }
}
SearchButton calls a method on the SearchManager




SearchButton


  calls method

                   SearchManager
SearchManager
public
class
SearchManager
{

    [Inject]
    public
var
service
:
SearchService;

    [Inject]
    public
var
tweetCollection
:
TweetCollection;


  [PostConstruct]
  public
function
setUpListeners(
injector
:
Injector
)
:
void
{
     service.addEventListener(
TweetEvent.TWEETS_LOADED,
updateTweets
);

 }


  public
function
search(
searchTerm
:
String
)
:
void
{
     service.send(
searchTerm
);
  }


  private
function
updateTweets(
event:TweetEvent
):void
{
     tweetCollection.assign(
event.tweets
);
  }

}
SearchManager calls a method on the SearchService


                                          SearchService
SearchButton
                           calls method

  calls method

                   SearchManager
SearchService
public
class
SearchService
extends
EventDispatcher
{

    [Inject]
    public
var
request
:
TwitterRequest;

    [PostConstruct]
    public
function
setUpListeners(
injector
:
Injector
)
:
void
{
      request.addEventListener(
ServiceEvent.COMPLETE,
parseResults
);
    }

    public
function
send(
searchTerm
:
String
)
:
void
{
      request.url
=
"http://search.twitter.com/search.atom";
      request.sendData
=
new
URLVariables();
      request.sendData.q
=
searchTerm;
      request.sendAndLoad();
    }

    private
function
parseResults(
event
:
ServiceEvent
)
:
void
{
      var
tweets
:
TweetCollection
=
parseFeed(
event.data
as
XML
);
      dispatchEvent(
new
TweetEvent(
TweetEvent.TWEETS_LOADED,
tweets
));
    }
}
SearchService dispatches an event when complete


                                          SearchService
SearchButton
                           calls method
                                           dispatches event
  calls method

                   SearchManager
SearchManager
public
class
SearchManager
{

    [Inject]
    public
var
service
:
SearchService;

    [Inject]
    public
var
tweetCollection
:
TweetCollection;


  [PostConstruct]
  public
function
setUpListeners(
injector
:
Injector
)
:
void
{
     service.addEventListener(
TweetEvent.TWEETS_LOADED,
updateTweets
);

 }


  public
function
search(
searchTerm
:
String
)
:
void
{
     service.send(
searchTerm
);
  }


  private
function
updateTweets(
event:TweetEvent
):void
{
     tweetCollection.assign(
event.tweets
);
  }

}
SearchManager updates the TweetCollection


                                           SearchService
SearchButton
                            calls method
                                            dispatches event
  calls method

                   SearchManager


                              updates data



                      TweetCollection
Tweet Collection
public
class
TweetCollection
extends
EventDispatcher
{

    private
var
_tweets
:
Array;

    [Bindable(
event="tweetsChanged"
)]
    public
function
get
tweets()
:
Array
{
      return
_tweets;
    }

    public
function
set
tweets(
value
:
Array
)
:
void
{
      if
(
value
!=
_tweets
)
{
        _tweets
=
value;
        dispatchEvent(
new
Event(
"tweetsChanged"
)
);
      }
    }

    public
function
assign(
other
:
TweetCollection
)
:
void
{
      tweets
=
other.tweets;
    }
}
TweetCollection is bound to the TweetList


                                             SearchService
SearchButton
                              calls method
                                              dispatches event
  calls method

                      SearchManager


                                updates data


        is bound to
                        TweetCollection
Tweets List


public
class
TweetsList
extends
List
{

    [Inject]
    public
var
tweetCollection
:
TweetCollection;

    private
var
tweetsWatcher
:
ChangeWatcher;

    [PostConstruct]
    public
function
setUp(
injector
:
Injector
)
:
void
{
      tweetsWatcher
=
BindingUtils.bindProperty(
        this,
"dataProvider",
tweetCollection,
"tweets"
);
    }
}
TweetCollection is bound to the TweetList


                                             SearchService
SearchButton
                              calls method
                                              dispatches event
  calls method

                      SearchManager


 TweetList                      updates data


        is bound to
                        TweetCollection
At the component level, it is MVC(S)

                                     SearchService
 SearchButton
                                           SERVICE
                CONTROLLER

                 SearchManager


  TweetList

                                      MODEL
VIEW               TweetCollection
Traditional Flex MVC


        View


               Controller

Model

                Service
Smart Components MVC




M   M   M    M   M    M   M    M    M   M
V   V   V    V   V    V   V    V    V   V
C   C   C    C   C    C   C    C    C   C
S   S   S    S   S    S   S    S    S   S




Each component is a slice of functionality
 implemented using MVCS architecture
A component set is



•   A collection of smart components that work
    together.

•   Each component set has a context component for
    its dependency-injection configuration.

•   Each component set has an event bus for
    components to talk to each other.
The application architecture




•   An application is created in MXML using
    components from one or more component sets.
Is it new?




•   The architecture feels new.

    •   Although I gained a lot of ideas from other
        peoples work.
Is it new?



•   On reflection, it has a strong similarity to MVC in
    Smalltalk-80, which is 30 years old!

•   Although our components are smarter than those in
    Smalltalk-80.
BrightTALK component Library


 The BrightTALK component library is

  •   158 components

  •   547 classes

  •   31,500 lines of code

 Working very well so far.

 We now build all our projects this way.
New workflow


         Developer




Client               Designer
New technologies we could use


Since we started, new technologies have emerged.

 •   This architecture would work with Flex 4
     components

 •   This architecture can be implemented using Swiz,
     Robotlegs, or Parsley

     •   Some details in the code differ, but the principles
         remain the same.

 •   At BrightTALK we use Signals instead of Events
The basic principles are




•   Doesn't matter whether you use Flex3, Flex4, or
    something else?

•   Doesn't matter whether you use Smartypants,
    Robotlegs, Swiz, Parsley or do it yourself.

•   Make your components smart.
That's all folks




http://www.richardlord.net/presentations/


       twitter.com/Richard_Lord

More Related Content

Similar to Re-architecting the designer-developer workflow

Similar to Re-architecting the designer-developer workflow (20)

Moderne App-Architektur mit Dagger2 und RxJava
Moderne App-Architektur mit Dagger2 und RxJavaModerne App-Architektur mit Dagger2 und RxJava
Moderne App-Architektur mit Dagger2 und RxJava
 
What's new in asp.net mvc 4
What's new in asp.net mvc 4What's new in asp.net mvc 4
What's new in asp.net mvc 4
 
Tdd,Ioc
Tdd,IocTdd,Ioc
Tdd,Ioc
 
Working with Servlets
Working with ServletsWorking with Servlets
Working with Servlets
 
Building Push Triggers for Logic Apps
Building Push Triggers for Logic AppsBuilding Push Triggers for Logic Apps
Building Push Triggers for Logic Apps
 
Labs And Walkthroughs
Labs And WalkthroughsLabs And Walkthroughs
Labs And Walkthroughs
 
Mvc acchitecture
Mvc acchitectureMvc acchitecture
Mvc acchitecture
 
2011 - DNC: REST Wars
2011 - DNC: REST Wars2011 - DNC: REST Wars
2011 - DNC: REST Wars
 
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteMVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
 
Asp objects
Asp objectsAsp objects
Asp objects
 
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...
MongoDB World 2018: Ch-Ch-Ch-Ch-Changes: Taking Your Stitch Application to th...
 
Tutorial mvc (pelajari ini jika ingin tahu mvc) keren
Tutorial mvc (pelajari ini jika ingin tahu mvc) kerenTutorial mvc (pelajari ini jika ingin tahu mvc) keren
Tutorial mvc (pelajari ini jika ingin tahu mvc) keren
 
It depends: Loving .NET Core dependency injection or not
It depends: Loving .NET Core dependency injection or notIt depends: Loving .NET Core dependency injection or not
It depends: Loving .NET Core dependency injection or not
 
Mvc interview questions – deep dive jinal desai
Mvc interview questions – deep dive   jinal desaiMvc interview questions – deep dive   jinal desai
Mvc interview questions – deep dive jinal desai
 
Model View Presenter (MVP) In Aspnet
Model View Presenter (MVP) In AspnetModel View Presenter (MVP) In Aspnet
Model View Presenter (MVP) In Aspnet
 
Mvc summary
Mvc summaryMvc summary
Mvc summary
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web Toolkits
 
How to create an Angular builder
How to create an Angular builderHow to create an Angular builder
How to create an Angular builder
 
Tutorial: Building Your First App with MongoDB Stitch
Tutorial: Building Your First App with MongoDB StitchTutorial: Building Your First App with MongoDB Stitch
Tutorial: Building Your First App with MongoDB Stitch
 
Medium TechTalk — iOS
Medium TechTalk — iOSMedium TechTalk — iOS
Medium TechTalk — iOS
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Recently uploaded (20)

"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 

Re-architecting the designer-developer workflow

  • 1. 360|Flex DC, September 2010 Re-architecting the designer-developer workflow Richard Lord Technical Architect
  • 2. Coming Up A story Lots of code A new architecture
  • 4. At BrightTALK we do webcasting
  • 5. At BrightTALK we do webcasting
  • 6. We have a set of standard players on our website and we create custom players for specific clients.
  • 7. Old workflow Client Designer Developer
  • 9. A new player (using Cairngorm!)
  • 13. Another client project (using Mate)
  • 14. Meanwhile, Goran did something very un-designer
  • 15. He built a widescreen player Using the code from another player
  • 16. This gave me an idea
  • 17. Since our designer can write MXML, can we enable him to build an app using only MXML?
  • 20. Too much influence from Mate Too many non-visual components
  • 21. Can we build an app using only visual MXML?
  • 24. Smart components contain the view and associated functionality.
  • 25. Smart components can find and talk to each other.
  • 26. Designers choose smart components based on user-interface functionality.
  • 27. Designers assemble the user-interface, and the application just works.
  • 28. Designers apply skins and css to the smart components to design the app
  • 29. The approach • Flex 3 • Dependency injection (with SmartyPants-IOC) • Simple event bus • Test driven development • Lots of refactoring • MVC is NOT a requirement
  • 30. ... Live Code ... (a twitter client)
  • 31. MXML <mx:Application> <tw:TwitterContext/> 

<mx:VBox> <tw:TweetsList/> 



<mx:TextInput
id="searchInput"/> 



<tw:SearchButton
label="Search"
searchTerm="{searchInput.text}"/> 

</mx:VBox> </mx:Application>
  • 32. The context is the only non-visual component. It configures the dependency injection container.
  • 33. TwitterContext public
class
TwitterContext
implements
IMXMLObject
{ [Inspectable] public
var
oauthConsumerKey
:
String; [Inspectable] public
var
oauthConsumerSecret
:
String; public
function
initialized(
document
:
Object,
id
:
String
)
:
void{ createContext(); listenOnDisplayList(
document
); } 
 
 private
function
createContext()
:
void
{ injector
=
SmartyPants.getOrCreateInjectorFor(
this
); injector.newRule().whenAskedFor(
EventBus
).useSingleton(); injector.newRule().whenAskedFor(
TweetCollection
).useSingleton(); injector.newRule().whenAskedFor(
User
).useSingleton(); injector.newRule().whenAskedFor(
AuthManager
).useSingleton(); injector.newRule().whenAskedFor(
IOAuth
).useValue(
 new
OAuth(
oauthConsumerKey,
oauthConsumerSecret
)
); } }
  • 34. The other components are the SearchButton and the TweetList.
  • 35. SearchButton public
class
SearchButton
extends
Button
{ 
 [Inject] 
 public
var
manager
:
SearchManager; 
 [Inspectable] 
 public
var
searchTerm
:
String; 
 public
function
SearchButton()
 { 
 
 addEventListener(
MouseEvent.CLICK,
performSearch
); 
 } 
 
 public
function
performSearch(
event
:
MouseEvent
)
:
void
{ 
 
 manager.search(
searchTerm
); 
 } }
  • 36. SearchButton calls a method on the SearchManager SearchButton calls method SearchManager
  • 37. SearchManager public
class
SearchManager
{ [Inject] public
var
service
:
SearchService; [Inject] public
var
tweetCollection
:
TweetCollection; 
 [PostConstruct] public
function
setUpListeners(
injector
:
Injector
)
:
void
{ service.addEventListener(
TweetEvent.TWEETS_LOADED,
updateTweets
); 
 } 
 public
function
search(
searchTerm
:
String
)
:
void
{ service.send(
searchTerm
); } 
 private
function
updateTweets(
event:TweetEvent
):void
{ tweetCollection.assign(
event.tweets
); }
 }
  • 38. SearchManager calls a method on the SearchService SearchService SearchButton calls method calls method SearchManager
  • 39. SearchService public
class
SearchService
extends
EventDispatcher
{ [Inject] public
var
request
:
TwitterRequest; [PostConstruct] public
function
setUpListeners(
injector
:
Injector
)
:
void
{ request.addEventListener(
ServiceEvent.COMPLETE,
parseResults
); } public
function
send(
searchTerm
:
String
)
:
void
{ request.url
=
"http://search.twitter.com/search.atom"; request.sendData
=
new
URLVariables(); request.sendData.q
=
searchTerm; request.sendAndLoad(); } private
function
parseResults(
event
:
ServiceEvent
)
:
void
{ var
tweets
:
TweetCollection
=
parseFeed(
event.data
as
XML
); dispatchEvent(
new
TweetEvent(
TweetEvent.TWEETS_LOADED,
tweets
)); } }
  • 40. SearchService dispatches an event when complete SearchService SearchButton calls method dispatches event calls method SearchManager
  • 41. SearchManager public
class
SearchManager
{ [Inject] public
var
service
:
SearchService; [Inject] public
var
tweetCollection
:
TweetCollection; 
 [PostConstruct] public
function
setUpListeners(
injector
:
Injector
)
:
void
{ service.addEventListener(
TweetEvent.TWEETS_LOADED,
updateTweets
); 
 } 
 public
function
search(
searchTerm
:
String
)
:
void
{ service.send(
searchTerm
); } 
 private
function
updateTweets(
event:TweetEvent
):void
{ tweetCollection.assign(
event.tweets
); }
 }
  • 42. SearchManager updates the TweetCollection SearchService SearchButton calls method dispatches event calls method SearchManager updates data TweetCollection
  • 43. Tweet Collection public
class
TweetCollection
extends
EventDispatcher
{ private
var
_tweets
:
Array; [Bindable(
event="tweetsChanged"
)] public
function
get
tweets()
:
Array
{ return
_tweets; } public
function
set
tweets(
value
:
Array
)
:
void
{ if
(
value
!=
_tweets
)
{ _tweets
=
value; dispatchEvent(
new
Event(
"tweetsChanged"
)
); } } public
function
assign(
other
:
TweetCollection
)
:
void
{ tweets
=
other.tweets; } }
  • 44. TweetCollection is bound to the TweetList SearchService SearchButton calls method dispatches event calls method SearchManager updates data is bound to TweetCollection
  • 45. Tweets List public
class
TweetsList
extends
List
{ [Inject] public
var
tweetCollection
:
TweetCollection; private
var
tweetsWatcher
:
ChangeWatcher; [PostConstruct] public
function
setUp(
injector
:
Injector
)
:
void
{ tweetsWatcher
=
BindingUtils.bindProperty( this,
"dataProvider",
tweetCollection,
"tweets"
); } }
  • 46. TweetCollection is bound to the TweetList SearchService SearchButton calls method dispatches event calls method SearchManager TweetList updates data is bound to TweetCollection
  • 47. At the component level, it is MVC(S) SearchService SearchButton SERVICE CONTROLLER SearchManager TweetList MODEL VIEW TweetCollection
  • 48. Traditional Flex MVC View Controller Model Service
  • 49. Smart Components MVC M M M M M M M M M M V V V V V V V V V V C C C C C C C C C C S S S S S S S S S S Each component is a slice of functionality implemented using MVCS architecture
  • 50. A component set is • A collection of smart components that work together. • Each component set has a context component for its dependency-injection configuration. • Each component set has an event bus for components to talk to each other.
  • 51. The application architecture • An application is created in MXML using components from one or more component sets.
  • 52. Is it new? • The architecture feels new. • Although I gained a lot of ideas from other peoples work.
  • 53. Is it new? • On reflection, it has a strong similarity to MVC in Smalltalk-80, which is 30 years old! • Although our components are smarter than those in Smalltalk-80.
  • 54. BrightTALK component Library The BrightTALK component library is • 158 components • 547 classes • 31,500 lines of code Working very well so far. We now build all our projects this way.
  • 55. New workflow Developer Client Designer
  • 56. New technologies we could use Since we started, new technologies have emerged. • This architecture would work with Flex 4 components • This architecture can be implemented using Swiz, Robotlegs, or Parsley • Some details in the code differ, but the principles remain the same. • At BrightTALK we use Signals instead of Events
  • 57. The basic principles are • Doesn't matter whether you use Flex3, Flex4, or something else? • Doesn't matter whether you use Smartypants, Robotlegs, Swiz, Parsley or do it yourself. • Make your components smart.

Editor's Notes