Archive for the tag 'General'

Maintaining Loose Coupling in Seaside Components

There is an interesting question that often comes up often when writing components. How do my components communicate with each other in a way that doesn’t bind them together explicitly. How does a child component call a method on a parent component without explicitly knowing who the parent is.

Knowing who the parent is prevents the component from being re-used in other contexts with different parents. There is a general solution to this whole class of problems and it was solved quite elegantly by Vassili Bykov with his Announcements framework.

The basic idea is to setup an announcer somewhere global, in the session for example.

MySession>>announcer
    ^ announcer ifNil: [announcer := Announcer new]

Then subclass Announcement for any interesting thing that might happen like removing a child.

Announcement subclass: #RemoveChild
    instanceVariableNames: 'child'

RemoveChild class>>child: aChild
    ^self new
        child: aChild;
        yourself

RemoveChild>>child: anChild
    child := anChild

RemoveChild>>child
    ^child

Any component interested in this announcement registers its interest when it initializes.

Parent>>initialize
    super initialize.
    self session announcer on: RemoveChild do:[:it | self removeChild: it child]

Parent>>removeChild: aChild
    self children remove: aChild

And any component who wants to fire this event simply announces it by sending in an instance of that custom announcement object.

Child>>removeMe
    self session announcer announce: (RemoveChild child: self)

Works great, and depending on where you place the announcer, you could even have different sessions sending events to each other, or different applications.

Here’s a file out of a commented working demo that has a child remove itself from the parent via an announcement.

UPDATE: I use the port of Announcements from Lukas Renggli’s public repository. The one on SqueakSource is a different port.

A Smalltalk ActiveRecord using Magritte, Seaside, and Glorp

I’ve been working on a side project that’s given me reason to want to use Glorp with Seaside. Having just mapped the sample blog written from my screencast into Glorp manually, by writing Glorp descriptors, I decided that I wanted something simpler, something more like Ruby on Rails, automatic persistence, with almost no configuration.

Having used Magritte for a while to describe my Seaside UI’s, I decided that those same descriptions contained all the necessary meta data to write Glorp descriptions from. Unlike the ActiveRecord in Rails, or the one Alan Knight is working on, I’m not using the database as the source of my metadata, I’m using the objects themselves with meta data from Magritte instead.

I sat down and started hacking out my own ActiveRecord implementation, which is really just a small framework that glues these three existing frameworks together for me and makes using Seaside against a Postgres database easy for me. Needless to say, knowledge of Magritte is a prerequisite for using this code.

I just open sourced the code I’ve been using on SqueakSource, just add this repository to Monticello to get a copy

MCHttpRepository
    location: 'http://www.squeaksource.com/MagritteGlorp'
    user: ''
    password: ''

This is a first cut Alpha release, I make no guarantees, only the brave need attempt using it. To use it, simply requires the following.

subclass MGActiveRecord, this will be your root class, all your biz classes can descend from this.

MGActiveRecord subclass: #SBActiveRecord
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'SeasideBlog-Glorp'

subclass MGDescriptorSystem and override #rootClass, returning the class above, like so…

rootClass
	^SBActiveRecord

and on the class side, override #defaultLogin

defaultLogin
    ^(Login new)
        database: PostgreSQLPlatform new;
        username: 'xxxx';
        password: 'xxxx';
        connectString: '127.0.0.1_yourDatabaseName'

and optionally #initializeDatabase: if you want to insert some test data on creation of the schema…

initializeDatabase: aSession
    aSession inUnitOfWorkDo: [aSession register: SBPost testPost]

Now, describe your classes with Magritte, here’s an example…

descriptionCategories
    ^ (MAMultipleOptionDescription selector: #categories label: 'Categories' priority: 1000)
        options: [SBCategory findAll execute] dynamicallyRefreshed ;
        classes:{SBCategory};
        reference: SBCategory description;
        componentClass: MACheckboxGroupComponent;
        yourself

[SBCategory findAll execute] dynamicallyRefreshed is a shortcut for (MADynamicObject on:[SBCategory findAll execute]) that I implemented, since Magritte descriptions are cached, I do this to ensure each time a UI is rendered, a fresh query is done against the database.

You must manually create your database in Postgres. Once created, to create your schema, simply call #createSchema on your MGDescriptorSystem subclass like so…

SBGlorpDescriptions createSchema.

It will use your default connection to infer and create the schema necessary to support your object model. I’ve only used this on two schemas so far, but it seems to work OK, though I’m sure there must be bugs.

Now, to use this all in Seaside, subclass MGGlorpSession and override #glorpDescriptionClass like so…

glorpDescriptionClass
    ^SBGlorpDescriptions

Once done, from Seaside, I can execute queries like so…

blogPosts
    "Grab published blog posts from database and return them in reverse order"

    ^(SBPost findAll)
        limit: self numberOfPostsToShow;
        where: [:each | each isPublished];
        orderBy: [:each | each timestamp descending];
        execute

And have the full power of Glorp available from two class methods, #find and #findAll which return Glorp queries wrapped in a decorator that allows you to call execute on them for the current Seaside context. All classes are commented. If anyone is brave enough to use this, I’d appreciate any feedback on any trouble you run into, or just general discussion about the approach. As I said before, I make no guarantees, but I’m using this code myself, and so far, it seems OK.

UPDATE: The tests included in the package are there to demonstrate a missing feature, automatic inheritance mapping. They do not need to be ran and have nothing to do with the base package. If createSchema works, you’re done, just start using it.

My Personal Pet Peeves I See in Other People’s Code

If you don’t have a sense of humor, stop reading now, go somewhere else, otherwise, continue reading this purposefully over the top rant. Keep in mind, I’m discussing VB, C#, and Java, not [insert your favorite language where these things don't apply].

On occasion, I’m forced to get into other peoples code, in Smalltalk, this is usually a pleasure and a chance to learn something. In other languages (VB, C#, and Java) where code isn’t of the general quality of the average Smalltalker, I continually run into the same things over and over again that drive me insane. Off the top of my head, here’s a few…

Inability To Grok Booleans

Using an if statement to evaluate a boolean, only to return a boolean…

if(someCondition)
    return true;
else return false;

Instead of…

return someCondition;

Comparing a boolean to true or false, as if it isn’t already one…

if(someCondition ==  true)
    doSomething();

Inability To Grok Assignment

I can’t tell you how many times I’ve seen this code…

ArrayList someItems = new ArrayList();
someItems = BuildSomeList();

when it’s so blindingly obvious that this is equivalent…

ArrayList someItems = BuildSomeList();

Seriously, I can’t imagine what mental defect makes people thing they have to create an ArrayList before the variable will allow an ArrayList to be assigned to it.

Ignorant Prefixing

From VB’ers, prefixing declared object variables with an “o”, as in oXml, to declare it an object, as if everything else somehow isn’t an object. In fact, Hungarian notation in general. Stop prefixing your damn code with type declarations. Booleans don’t need to start with b, strings don’t need to start with “str”, wake the hell up and join this decade people.

Single Exit Points

Constantly jumping through hoops and writing extra unnecessary code just to have a single return statement in a method…

string result = "";
if(someCondition)
    result = "foo";
else result = "bar";
return result;

Instead of…

if(someCondition)
    return "foo";
return "bar";

There’s not a shortage of return statements, use them liberally, exit early and often, it produces much cleaner and much less ambiguous code. Those old papers about structured programming that recommend this practice, no longer apply, we have garbage collection and your methods shouldn’t be that damn long to begin with.

1000 Line Methods

A method should be 7 to 10 lines of code, any longer than that and you start having to comment sections to explain them, which is what methods are for in the first place. There are exceptions, but they are exceedingly rare, on average, method should be short and simple and require little if any explanation beyond the method name itself. Seriously, I’m starting to think we should eliminate the scroll bar in code editors, when you hit the bottom, the computer should just start beeping at you like you’re an idiot for typing that much.

Declaring Variables At The Top Of A Method

In languages that allow it, you should always declare your variables and initialize them in the exact spot you want to use them. Don’t declare variables as if they’re somehow a limited resource and keep reusing the same one over and over in different sections of code. Declare your variables at the minimum level of scope necessary for them to be useful. If you only need a variable inside a loop, then declare it in the loop (optimizations aside), the code will be cleaner and more readable. This is another one of those mental quirks that seems to come from having a history in Basic. Stop it, please.

Too Many comments / Worthless Comments.

If I see more green than code, somethings wrong. This modern JavaDoc style stuff is ignorant, if you need to explain the code that much, it sucks, really. Comments should not replicate what the code says, they should augment what it can’t, things like “why” you made a design choice belong in comments. How, is for code, don’t repeat the how in the comments.

Don’t comment closing tags.

if(foo == bar){
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
    //bunch of code
} //end if(foo == bar)

this is beyond ignorant, you should be shot. If you can’t see the beginning of a tag on the same screen as the end of a tag, you need to learn how to factor. Break thing up into smaller methods. See 1000 line methods above, you have a disease, seek help.

Don’t comment sections of code to explain it, factor it into its own method and make the method name explain it. Then if necessary, comment the method explaining the “why”. Functions/Methods are the most basic building block of programs, they should be as small as bricks, not the size of entire freaking houses. You can’t compose solutions from a few giant functions, only from many many small ones. Giant functions aren’t reusable, maintainable, or acceptable, ever.

Still Using Error Codes

Stop using error codes and return values, use exceptions instead. To put it simply, use the Samurai Principle, a method either succeeds, or blows up with a suitable exception. Error codes are not acceptable in a modern language, it’s a dead technique.

Lack Of Consistency And Style

I might not like certain styles, but all too often I see code that lacks any style at all. Code should have a style, things like naming conventions, casing conventions, factoring conventions, something. Nothing bugs me more than code that clearly lacks any sort of style whatsoever. Don’t name thing haphazardly, sometimes uppercase, sometimes lowercase, sometimes abbreviated, sometimes long.

Pick a style for local variables, parameters, instance variables, method names, class names, package names, constructor names, and accessor names. If you haven’t actually thought out how you want to do these things, stop, take the time, it’ll allow you to think much less in the future and write code cleaner and faster. Go read Kent Beck’s Smalltalk Best Practice Patterns, steal his style until you develop your own. Pick a style, stick with it, don’t write schizophrenic random looking code, it’s maddening to people who read it later.

Still Using Switch Statements

Stop using them, period. There’s hardly any cases where polymorphism isn’t more appropriate. Use a class for each case, and break up these nightmare methods into separate pieces that can be worked on in isolation without fear of breaking the other cases. Your switch statements will be duplicated, eventually, so just start with classes and avoid the inevitable refactoring. There’s a reason Smalltalk has never had a case statement, think about it, HARD. If you think you can’t live without them, think harder, you’re wrong.

Obsessed With Simple Types

Though you can represent anything with a string, it’s ignorant to do so. Every program should not be expressed with only Strings, Chars, Booleans, Integers, Doubles, and Decimals. Build your own primitive types and use them as such. Things like Money, SocialSecurityNumber, Address, Contact, User, Name, Email, Url, Company, and OrderNumber can all be primitives as well.

Write your programs in the language of the domain, not in the language of existing primitive types that are native to your language. Stop passing around specially formated strings and validating them constantly, just stick them into a real object and use it instead. Pass around whole objects, not id’s to objects that you can look up later. Learn to override ToString/asString/to_string so that your object print well when you stick them into things like drop down lists and such.

Writing code with objects native to the domain in general, greatly reduces the amount of code necessary to express rules in that domain in large part because it greatly eliminates duplicate code.

XML Hell

Stop using XML as if it were an object model. Trees of objects are far superior to trees of strings loaded up into a generic DOM. Use a real object model, and then if you need XML, serialize the objects into XML for transport. Rarely should XML be built manually, use objects instead, they work better, are easier to force business rules onto, and are easily serialized into any format. XML is for configuration files and data transport, not for general purpose programming.

I’m sure there are more, but this post is getting a bit long. Anyone have any other major pet peeves they like to share?

Screencast: How to Package Smalltalk Code with Monticello

In my last post I built a simple blog, so I thought I’d do another short screencast showing how Squeakers package and share code. As with the first screencast, this one has no sound, it’s just video.

I create a package for the blog, save it to my package repository, which happens to be an ftp site on my server, but it could be a directory, an http repository, or quite a few others.

After saving the first version, I make a few changes and just bounce around Monticello a bit, to give you a general feeling of what we do and how we do it. I look at the latest version of Seaside, merge in the changes, change my mind, revert back to the old package, add a dependency to Seaside2 to my package, etc. Just watch it, you’ll get the general idea.

Once in the repository, packages are easily loaded into any image making sharing code trivial. I didn’t really show off everything Monticello can do, just the basics. Like most things in Smalltalk, you learn the most when you simply dive and start poking and prodding stuff to see what can be done, so if you want to see everything Monticello can do, you know where to start.

UPDATE: The screencast is now in Quicktime and only 7 megs thanks to a reader Manuel Blanc re-encoding it for me.

« Previous PageNext Page »