Posts Tagged With UserGroups - Musing, Rants & Jumbled Thoughts

Header Photo Credit: Lorenzo Cafaro (Creative Commons Zero License)

My employer, West Monroe Partners, will once again be sponsoring the Chicago Architects Group monthly meeting Tue, July 20th. Chicago has a strong technical community and as I've mentioned before, I'm proud to see WMP support the continued growth and learning of the community at large.

This month's topic is "Architecture And Business Intelligence" by David Leininger. Details and registration can be found at http://chicagoarchitectsgroup.eventbright.com/ Presentation begins at 5:30pm at the ITA/TexusNexus space in the Loop. Attendance is free thanks to corporate sponsorships, such as West Monroe Partners!

I hope you'll join me there!

Chicago Architects Group was founded on the goal to unit various technical architecture competencies into a community for collaboration and knowledge sharing. The group is for people to meet their peers and share some stories and ideas. Architects and those aspiring to understand technical architecture better will enjoy this group. (text from http://chicagoarchitectsgroup.com).



For over a year now I've been attending technical user group meetings across the Chicago area and one in particular has caught my interest more than the others. The Chicago Architects Group ("CAG") has consistently provided presentations and discussion on  topics relevant to me and by presenters with experience and knowledge on the subjects at hand.  Presentations has ranged from Dependency Injection & Inversion of Control Containers, to Onion Architecture, to Agile Project Management strategies. And tonight will be Azure for Architects.  All targeted to the technical architect audience, who discuss the topics, share personal experiences and insights.

Shift gears now to one of the reason I enjoy working for West Monroe Partners: WMP has a set of values core to the culture of the company that help make the company a great place to work:

  • A culture of learning and growth
  • The belief that our clients should learn and grow with us
  • The belief that diverse experiences and thought are required to develop a balanced set of knowledge and skills

So now I am happy to be able to bring these two groups together, I believe to the mutual benefit of all: this month West Monroe Partners  will be sponsoring the CAG meeting by funding the food and drinks. And there are plans in place to further sponsor at least two more meetings this year.  So what does this mean?  Well, it means that CAG meets continue to be free to anyone who wants to attend.  It means that people can continue to learn about new skills, new technologies or alternate views on existing skills for the purpose of learning and growing and picking up on the experiences of others.  It's a small way for WMP to help a community group continue to grow and better the larger technical community and I hope it's a pattern that will continue.

And it means I continue to get free pizza -- which helps offset the long commute back to the 'burbs when staying downtown for after-hours meetings. :-)




(Each month I plan to attend technical user groups in the Chicago area to (re-)learn from peers experiences with new and existing technologies and to network with like-minded techies. This blog is one in a series of recaps of some of the more interesting aspects of the meetings for my own purposes (this is a “web log” afterall) and for others to get a general taste of what’s available in the Chicago user group scene.)

User Group: JavaScript Chicago (JS.chi)
                http://javascriptchicago.com
                http://www.meetup.com/js-chi/
                Twitter: @chicagojs
                Location: CashNetUSA (200 W Jackson – In the Loop)
Meeting Date:Thursday, January 20, 2010

The js.chi meetings follow a format of two main presentations, followed by three “lightning talks” (5-min quick presentations – although I have only seen one actually achieve the 5-min timeframe).   Fairly large attendance again (20 – 30 attendees, from what I could tell), but had audio problems again, which meant it was difficult to hear beyond the first five rows or so (hint: arrive early to get a good seat – beers/sodas and networking before the meeting to help it along).

Presentations:


Prototypal Inheritance

This month, the opening presentation was an overview of prototypal inheritance in JavaScript.  Honestly, I didn’t find the topic that engaging, which combined with an apparently nervous presenter, meant that I didn’t take that many notes.  Check out the website for a video, and http://javascript.crockford.com/prototypal.html for more info.

Node.js

Jason Huggins (twitter @hugs – formerly @jhuggins) of SauceLabs (“Selenium in the cloud”) presented an overview of Node.js.  This presentation I did find intriguing, although may be more applicable to my Linux friends than those living in a Microsoft world. (If you don’t know what POSIX means, you probably won’t want to use Node.js)

Node.js, at a very high level, is a JavaScript environment that lives outside the browser.  Think: server-side JavaScript or shell-scripting on crack.  It’s a three-way marriage with the following actors:
  • Common.JS: An attempt at a common/standard JavaScript library, not tied to any specific framework.  Most other high-level languages have some core library (.Net has – well, the .Net core libs, Perl has CPAN, etc).  Includes library support for file access, database drivers, console drivers, etc. (http://commonjs.org)
  • Google’s V8 JavaScript engine: This is the JS engine in Chrome – written in C++, it’s very powerful, very fast, but really not a standalone system – intended to be run from within a browser.
  • Node.js: The glue that holds it all together. Provides a command line interpreter in addition to the JavaScript run-time environment.  Adds additional libraries to round-out common.js. (http://nodejs.org)

Node.js is fairly new to the scene – started circa Nov 2009. It requires a POSIX environment, which means additional installs in Windows-land if you want to use it. Use out-of-the-box for Linux and friends.

Per the presenter, search Google for “node.js jsconf slides” for the originators presentation slides, which go into depth about the project. (You can also find video of this slide presentation with audio overlay at http://blip.tv/file/3152542 or just this presenter’s slides at http://www.slideshare.net/hugs/nodejs-javascript-chicago-meetup)

So what’s so great about using JavaScript outside a browser?  Well, unlike most other scripting languages, JavaScript is (can be) event-driven – meaning you can provide anonymous functions to method calls to create async callbacks when handling results, providing a more responsive and scalable system, as well as being a feature-rich language:
                db.query($sql, function(result) {
                                //do something with result
                }

The framework provides library inheritance (like the “using” keyword in C#, #include in C).
                var sys = require(“sys”);
                var http = require(“http”);
                http.createServer(…);

The presenter’s proof-of-concept demo was a ~20 line JavaScript application that bound itself to a port as an http listener and responded with an HTTP 200 request and “Hello World” body to any incoming request.  Could be very useful for mocking up web interfaces.

Some drawbacks:
-          Library is new and immature – but appears to be growing up quickly.
-          Currently no “step debugging” support – start loving log output now L

Other notes:
The presenter is a founder of SauceLabs (http://saucelab.com), which provides cloud-based support for the UI testing framework Selenium (http://seleniumhq.org/).  I’ve been wanting to play with Selenium, and if/when I do, this looks like an interesting model for grid-based/pay-as-you-go script agents.

Lightning Talks:

  • Chad Norwood presented his JavaScript-based project for using Google Maps as a filter for large, geography-based data sets.  Specifically, he’s linked Google Maps and Google Calendar to allow the user to display/filter calendar entries by physical location.  In his example, he used a usergroup calendar (such as http://chicagotechcal.com– love it!) and could zoom in/out to narrow/widen the list of events and chart them on the map. Cool idea.  Play with it here: http://chadnorwood.com/gcm
  • The second talk was kind of a teaser for another presentation at a local Ruby group. MongoDB is a JSON-based database (apparently similar to CouchDB) which stores data as BSON (Binary JSON). Its schema-less, so stores the objects as you define them. I could see this useful for cases where you may want to cache AJAX responses for improved performance, but I struggle to see where/how you would use this in an enterprise environment (full disclosure: I’m a big fan of RDBMS, so you’d have to really wow me to move away from a relational design).  More can be found here:  http://mongo.kylebanker.com

That’s all for tonight.  Typically, after the meeting a smaller group goes to the Elephant and Castle pub for drinks and networking – but after a long week, and a list of must-do’s for the client status meeting the next morning, I opted instead to head home.

Bonus Teaser:

I’m working on a blog (rather, the code which will lead to a blog) as an intro to Microsoft’s ASP.NET Charting controls and Google’s .NET Analytics API.  Think: Building your own custom Google Analytics charts.  Why? Because I want to see them on my Flash-less iPhone. And ‘cuz I’m a geek.



(Each month I plan to attend technical user groups in the Chicago area to (re-)learn from peers experiences with new and existing technologies and to network with like-minded techies. This blog is one in a series of recaps of some of the more interesting aspects of the meetings for my own purposes (this is a “web log” afterall) and for others to get a general taste of what’s available in the Chicago user group scene.)

User Group: Chicago Architects Group

http://www.chicagoarchitectsgroup.com/

Location: ITA (200 S Wacker - next to Sears Tower)

Meeting Date: Tuesday, January 19th, 2010

The CAG meetings I’ve been to have had between 10 and 20 attendees and tend to be more of the Architect/Team Lead types and less of the hard-core, in your face techies/developers (this is not a bad thing, in my opinion). Like most user groups, they have pizza and soda as well as giveaways at the end (today included Windows 7 Ultimate, Office 2007, a wireless mouse and several books). Personally, I find the meetings to be useful, although I know some of my coworkers who have come with me will likely not attend unless the topics are of great personal interest to them.

Presenter: Tim Murphy

Blog: http://geekswithblogs.net/tmurphy

Twitter: @twmurph

Topic: Dependency Injection and IOC Containers

I'll admit up front that this entry will be a little light on content, such as the pros/cons to using this pattern – mainly I’m making notes for me to reference later. Here is a link to the presenter’s wrap-up as well, with slides and code (using Unity and Windsor). http://geekswithblogs.net/tmurphy/archive/2010/01/19/cag-january-2010-wrap-up.aspx

But by all means, please read on :-)

The Dependency Injection pattern is intended to lessen the coupling of objects by having dependant objects provided to an object instead of having the object itself generate the dependant objects. For example, you have a Widget object which depends upon a LoggingManager object and a WidgetValidator object. Without Dependency Injection, you might instantiate your dependant objects insider your object constructor, like this:

namespace WrightThisBlog.blogspot.com
{
    public static class MainApp2
    {
        public static void main(object[] argv,  int  argc)
        {
            var  myWidget =  new Widget ();
            //do some widgetity stuff here
        }
    }
    
    public interface IWidget  {}
    
    public interface ILogger  { }
    
    public interface IValidator  { }
    
    public class LoggingManager  :  ILogger { }
    
    public class WidgetValidator  :  IValidator { }
    
    public class Widget :  IWidget
    {
        ILogger  _logger;
        IValidator  _validator;
        
        public  Widget()
        {
            _logger =  new LoggingManager ();
            _validator =  new WidgetValidator ();
        }
    }
}

But now you're tied to a specific implementation of ILogger and IValidator and if you ever wanted to change them, you'd have to modify your code anywhere you referenced those objects and replace them with your new ILogger object.   This is less than ideal and makes your code a bit fragile.

So how does Dependency Injection change this?   Basically, by having the caller provide the ILogger and IValidator to the Widget object, either as parameters in the constructor or as properties. This is further decoupled in my example by using factory classes:

namespace   WrightThisBlog.blogspot.com
{
    public static class MainApp2
    {
        public static void  main( object [] argv,  int  argc)
        {
            IWidget  myWidget =  WidgetFactory.GetWidgetInstanceViaConstructor();
            IWidget  myNextWidget =  WidgetFactory.GetWidgetInstanceViaProperties();
            //do some widgetity stuff here
        }
    }
    
    public class ImprovedWidget :  IWidget
    {
        public  ImprovedWidget( ILogger loggerToUse,  IValidator  validatorToUse)
        {
            LoggerToUse = loggerToUse;
            ValidatorToUse = validatorToUse;
        }
        
        public  ImprovedWidget() {}
        
        public ILogger LoggerToUse {  get ;  set ; }
        public IValidator ValidatorToUse {  get ;  set ; }
    }
    
    public static class WidgetFactory
    {
        ///<summary>
        ///Could provide in constructor
        ///</summary>
        public static IWidget  GetWidgetInstanceViaConstructor()
        {
            ILogger  logger =  LoggerManagerFactory.GetLoggerInstance();
            IValidator  validator =  WidgetValidatorFactory.GetValidatorInstance();
            return new ImprovedWidget (logger, validator);
        }
        
        ///<summary>
        ///Or via properties (beware unset properites!)
        ///</summary>
        public static IWidget  GetWidgetInstanceViaProperties()
        {
            return new ImprovedWidget
                {
                    LoggerToUse =  LoggerManagerFactory.GetLoggerInstance(),
                    ValidatorToUse =  WidgetValidatorFactory.GetValidatorInstance()
                };
        }
    }
        
    public static class LoggerManagerFactory
    {
        public static ILogger  GetLoggerInstance() {  return new LoggingManager (); }
    }
    
    public static class WidgetValidatorFactory
    {
        public static IValidator  GetValidatorInstance() {  return new WidgetValidator (); }
    }
}

Now you’ve created a loose coupling between your Widget and its supporting objects, which will come in handy when

  • You want to use a mocking tool (like RhinoMocks) to unit test your code
  • You want to replace your LoggingManager with something else that implements ILogger – now you only need to update the factory classes (technically, using a factory class is a different pattern, but works well here)

Still, you’re coding in a concrete implementation in your factory, so while you’ve isolated the number of places you need to update, you’re still hard-coding in an implementation.   Additionally, if there are very deep dependencies (you’re Logger needs a FileManager which needs a PermissionsManager which needs a CurrentUserManager….), this can get pretty ugly to manage and you end up writing a lot of plumbing code that is only tangential to the application’s real purpose.

This is where the IOC Containers come into play.   Using an IOC framework, you define which concrete classes implement your interfaces and what dependencies they have.   Then you use the IOC container like a factory class to instantiate your objects.   There are two primary means for defining the dependency trees: using XML in your app.config or via code.   Per the group discussions, some IOC frameworks provide tools (such as Structure Map) which will auto-generate your code mappings, while others (like Microsoft’s Unity Framework) use [Dependency] attributes to denote where there are dependencies.   This allows you to say “I need an IWidget” and the container framework will know that ImprovedWidget should be created and it has dependences on ILogger and IValidator, which are provided by LoggerMananger and WidgetValidator, and so on.

using   Some.IOC.Framework;

namespace   WrightThisBlog.blogspot.com
{
    public static class MainApp3
    {
        public static void  main( object [] argv,  int  argc)
        {
            var  IOC_container = IOC_Framework.GetContainer();
            IWidget  myWidget = IOC_container.GetObject<IWidget>();
            //do some widgetity stuff here
        }
    }
}

Resources and Reference:

Some IOC Frameworks:

  • Structure Map
    • Has “scanning” tool to auto-map dependencies and limit the amount of manual configuration needed. (If only one class in your project implements a given interface, that class will be used when that interface is requested).
  • Ninject
  • Castle Windsor
    • Uses app.config to defined assemblies/classes to use for each interface.    Uses constructor to provide dependencies.
  • Microsoft Unity (part of P & P group)
    • Uses [Dependency] attributes places on class properties to determine where dependencies are needed, as well as to get/set them.

Some links:



(Each month I plan to attend technical user groups in the Chicago area to (re-)learn from peers experiences with new and existing technologies and to network with like-minded techies. This blog is one in a series of recaps of some of the more interesting aspects of the meetings for my own purposes (this is a “web log” afterall) and for others to get a general taste of what’s available in the Chicago user group scene.)

UserGroup: Chicago Alt.Net

Location: Willis (aka Sears) Tower


Meeting Date: Wednesday, January 13, 2010


If you're in the Chicagoland area and do any .Net programming, I recommend this group.  It's got a decent turnout (usually). I've been to three meetings with anywhere from 20 - 40 people in attendance.  And they have good giveaways if you stay till the end. Today was especially good: A copy of Windows7 Ultimate, Office 2007, the JetBrain's product of your choice (ReSharper, dotTrace, TeamCity, IntelleJ -- great products if you're not familiar), $50 Barnes & Noble card, and of course a few Microsoft tech books. And free pizza!


Presenter:John Nuechterlein (aka Jdn) (http://www.blogcoward.com).

Topic: CQRS in roughly an hour or so

(CQRS == "Command Query Responsibility Segregation")


So, I'll be honest: Going into this presentation, I had only a very vague idea of what CQRS is and even less idea why I should care. (I had actually planned to play poker that night instead, but poker got canceled L).  Leaving this presentation, my mind was swirling with all of the projects where CQRS would have been great to use (and the many parallels with the "massively" distributed computing environment we developed at Wayport.  -- where "massive" is defined in pre-Google, pre-Facebook terms).

So, what is CQRS?  Frankly, I couldn't do it justice in this blog -- but I needn’t try, since my smarter, more eloquent people have done so before me. Actually, from what I understand, CQRS got its start in the blogosphere. For more depth, here is one key link (
http://elegantcode.com/2009/11/11/cqrs-la-greg-young/), but here's my lame attempt at a quick definition:


CQRS is a system architecture/design pattern that separates the act of reading data (query) from taking action (command) in order to produce a system which easily scales and provides some useful benefits (such as "playable" event logs) that make the maintenance of the system less burdensome. (For my purposes, I'm going to designate CQRS as an "architecture", partly because I don't want to write "architecture/design pattern" anymore.)



In my mind, CQRS lends itself pretty well to web-based systems, and SOA/SaaS at that, although it could be applied elsewhere.  I'm probably jumping ahead of myself a bit, but that statement is useful for backing this next statement. To consider using CQRS, you must buy into a fundamental assertion: your data is always stale.  How stale depends on your system, but the fact that my last blog entry was about data caching techniques just goes to show that particularly in web-based system, we intentionally make some of our data stale by putting it into a cache. 



But even without intentional caching, your data is stale.  Consider this: you have an eCommere site (say, amazon.com). Your end user pulls up the product page for the Widget2010 product, which includes price and quantity in stock information. In the 60 seconds it takes the user to read the page and click the shopping cart button, five other people have ordered their own Widget2010, so the quantity in stock is now less than what's on the first user's screen -- thus, the data is stale.  You know this -- you expect this -- and you've already coded a dozen ways to deal with this, so accepting that "your data is always stale" is really not that big a leap of faith.

So why is that important?  Because the CQRS architecture separates the reading of data and the acting upon data into two separate logical areas, where the reading area has a data cache which is stale.  Now, it may only be 1 ms stale, but stale none the less.

So let's dive in to my high level summary of Jdn's high level overview. (note: if you want to bypass my bias and possibly complete misinterpretation of the presentation, it is (or will soon be) available on the http://chicagoalt.net website in video form):

CQRS has four logic areas in your system design, as pictured in this drawing stolen squarely from the blog linked above:


Queries
This is the "reporting" piece -- or said another way, this is the read-only interface into your data. Basically, it's a lightweight data layer reading from your data store and proving DTOs back to your UI. It does NOT go through your Domain Model.  It is simply a read-only view into your database.  Your database, however, is really a cache of your data, and likely a local cache.  In other words, since the data is just a cache of the "real" data, why not push it out as close to the UI as possible to minimize the latency to your UI (since the majority of your UI's interactions with your data is reading, making this link super-fast will in turn make your system faster). Since these are read-only views into your data, the DTOs are extremely simple and can/should be specific to the consumer (ie: no "product" DTO, but rather a productForOrderPage which only has the data needed by the order page) reducing the amount of data getting dragged around between layers, etc.  Why pull your full product from the db if you only need 20% of the information for the current page? Need to scale your UI? Just add another data store/cache -- it's practically a rubber stamp.

Commands
The next logical area of this architecture is the Command Bus/Command Handlers. This is where the next tenant of CQRS comes into play: system actions (aka "commands") have specific intent.  If you've practiced Agile Development and you're familiar with the concept of the User Story -- basically requirements as documented from the viewpoint of a user's interaction with the system -- then this may be easy to grasp.  Basically, Commands are actions taken on your Domain objects.  For example: CustomerChangedAddressCommand or AddProductToShoppingCartCommand.

Commands are the only way to update data in your system and are seen as atomic actions which can be wholly accepted or rejected. Commands are generated by the UI and pushed onto the Command Bus and picked up by Command Handlers.  Command Handlers in turn pass those commands into the Domain.  Since commands go onto a bus, they can be queued, prioritized, etc, just like any message on a messaging bus, thus allowing you to ensure your most important commands are handled appropriately (another scalability knob you can adjust to meet your performance needs).

Now, since commands require specific intent (ie: user updates their address/places item into shopping cart), this does have implications for your UI -- specifically, you can't have "Excel-like screens".  There's no "update everything about this user and here's all the data" command (or there shouldn't be), so if that's what you're looking for, you may want to look elsewhere.  But honestly, this may not be a bad thing, as it forces some system designs which will likely result in more user friendly, reliable systems in the long run.

Internal Events / Domain
This area is the authoritative knowledge source.  Your business logic resides here. Your Domain objects reside here.  Here is where you'll find the Event Store. This is the most complicated part of the system, and is where the presenter struggled at times to explain some concepts / answer some questions, so this is where you'll likely want to ensure you've done your homework. (To his credit, Jdn fully admitted up front he did not know all of the ins-and-outs of this area and did his best to explain).

As commands come into your Domain from the Command Handlers, your Domain objects validate business rules to determine if the command is valid for the current state of the world and either reject the command en-whole, or, in one atomic action, update the state of the world according to the command (thus, an “event” occurs). 


Events are written to the Event Store, which is persisted, likely in an RDBMS, ODBMS, etc.  A snapshot of the state of the world is taken periodically and if you want to recreate a place-in-time, just take the previous snapshot and replay the events in order from that snapshot until the place-in-time you care about. Your domain could just remain in memory, if you'd like -- otherwise you'd pull the most recently stored (via snapshot) version of your domain object(s) and replay any new events against that object until it's fully restored, then execute your new command and presto-chango!

Now this was of particular interest to me from a troubleshooting/audit standpoint.  If a problem occurs on the site, pick a snapshot from right before the problem occurred and replay your events to reproduce the issue. (QA engineers applaud here.)  New version deployment go ghastly wrong, rollback the events until right before the deployment.  Theoretically, you could even re-run the events again against the older version of the software and (unless the events weren't supported in that version) recover the data changes.  Try doing that when your domain is specific to your db schema or your audit history is at the db table level (how do you replay an "insert" when the columns have changed?)

One note here is that your Event Store is "write only" -- meaning you don't ever delete things from your domain, you just adjust them.  The presenter used the analogy of an accountant ("accountants don't use erasers").  If an accountant finds an error in the ledgers, they don't edit that line item -- instead they create an adjustment line item to offset the difference.  The Event Store is similar -- you create events to adjust/negate/otherwise manipulate your data.

External Events / Publication
Now, to go full circle, the Domain / Event handling system will publish any events that it handles (but not those that it rejects).  Any data stores/caches will subscribe to that feed, and will update themselves based on those events. Thus, your data cache is only as stale as it takes to process the published events.  Again, you use a message bus here (or a webservice, etc) and use prioritization queues if you wish to enhance performance/scalability.

This is where the concept of "Eventual Consistency" is used -- that is, your Domain and your Data Stores will eventually sync up, just not necessarily in "real time" -- but we're ok with that because we've agreed that latency is almost always ok and availability trumps correctness in the Data Stores -- because "your data is always stale" anyway.

And the big finish...
To conclude, the presenter touched on reasons why you wouldn't want to use CQRS, including:

·         it's new, it's different
·         multiple data stores (maybe you don't want this)
·         operational complexity
·         lots of commands, events, handles, etc

…and my conclusion
All-in-all, this is definitely something I will consider for large systems in the future, although it is likely overkill for most systems in the market I serve.  I suggest doing some Google searches if you're interested at all in learning more (seems to be a good deal of data, videos, webinars, blogs, etc. out there).




(Each month I plan to attend technical user groups in the Chicago area to (re-)learn from peers experiences with new and existing technologies and to network with like-minded techies. This blog is one in a series of recaps of some of the more interesting aspects of the meetings for my own purposes (this is a “web log” afterall) and for others to get a general taste of what’s available in the Chicago user group scene.)


UserGroup: JavaScript Chicago (JS.Chi)
http://javascriptchicago.com
http://www.meetup.com/js-chi/
twitter: @chicagojs

Meeting Date: Thursday, November 19, 2009

This is one of the larger group meetings I’ve attended, with around 40 – 50 attendees. There were two primary speakers, both presenting remotely using video conferencing. Given the number of attendees, the layout of the conference room and the remoteness of the presenters, it was necessary to use a sound system for the presentations; however there were significant audio issues which forced a late start and a less than ideal experience. I’m hopeful this is not typical (and given the number of attendees, I can’t image it is – otherwise people would stop coming). All-in-all, it was worth going to future meetings.

Presentations:
  • Wolfram Kriesing (Developer at Uxebu) [twitter: @wolframkriesing] presented an introduction to the Dojo framework (http://dojotoolkit.org). Dojo is a JavaScript framework in the class of jQuery or MooTools. From the presentation, it seems Dojo’s main call-to-fame is it’s UI effects library and its support for namespaces:
    • dojo.* - core library
    • digits.* - UI widgets
    • dojox.* - eXtentions / eXperimental (such as data storage access from the js layer using things like flicr, Amazon S3, etc).
Dojo has very similar functionality to jQuery (the framework which I am most familiar with – albeit not that familiar). Dojo has a team of full time support and development personel (~10 people) supported by corporate sponsers, plus many official contributors. To contribute to Dojo, you must go through an application process, including some legal documentation to ensure the intellectual property stays with Dojo. It wasn’t clear to me what this extra level of red tape brought to the table that wasn’t provided by using an appropriate open source-style license.

Ultimately, given that my primary web development environment is ASP.NET, much of what this library provides is either better done (in my opinion) on the server side or is fully supported by the jQuery framework, which is being integrated into the ASP.NET framework – so I’ll likely be sticking to jQuery. But for folks who aren’t using .Net (aka: all you Ruby, PHP, TCL developers out there), this is another alternative which may be more appropriate for dramatic UI effects.

  • Aaron Newton (Creator MooTools) [twitter @anutron] presented “Programming to Patterns”, which basically described applying object-oriented programming (mainly Inheritance) in JavaScript, with examples in MooTools. MooTools, as a framework, provides a class structure for JavaScript, which makes some O/O principles easier to apply.


Other odds and ends:
After the main presentations, there were some “Lightning Talks”:
  • Jake Lumetta (http://jakelumetta.com, twitter: @jakelumetta) presented his website http://chicagotechcal.com/ (twitter: @chitechcal) which is an aggregate calendar of Chicago-area technical user groups. I’ve already found this to be a great resource!!
  • A few guys are creating http://jsmeetup.com as a roll-up of existing javascript user groups, planning to launch v1.0 in January.
  • There was also another recommendation for use of Closure Compiler for JavaScript minimization. This appears to be a good, new tool. Part of the Google Closure suite http://code.google.com/closure/