Thursday, September 30, 2010

Value Objects - some notes

There is a controversy - or maybe a fuzzy consensus about what you should be able to do in templates. Some template engines, like Template Tookit, let you call subroutines and methods on stuff passed to the template. This is very useful - you don't need to care about turning the data into a specially formed hash that can be iterated by the template, you just pass the data there and can be sure that it can display it. But it can also be abused. I think everyone would agree that template should not for example change the data in the database, but where is exactly the limit is not clear. Value Objects seem to be a good answer, templates should work only with Value Objects.

The question is how sharply you can divide your objects into Value Objects and Service Objects. In ActiveRecord is hard to test Hevery proposes a design where the record in Active Record is a Value Object (newable in his terminology is a synonym) with no link to the repository object which would do all the database manipulation. This would work for normal attributes - you'd assign the value there on object creation - but what about relations? $user->books is very convenient, especially in templates, and it can be pure - if you know that you need the books on the user you could put them there when creating the user object. But then you'd have two kinds of objects - those with books, needed in some places - and those without, when you want to spare the additional database calls. Maybe we need subclasses of User? But then we'd need subclasses for all possible combinations of relations (users with books, users with friends, users with books and friends, ...), not to mention the mess with relations on the related objects.

Sunday, September 26, 2010

Another argument for immutable objects

Class is like a little program, it has data, it has code, it can be instantiated - like a program can be run. From the perspective of the object it's attributes are global. There can also be other variables - like parameters passed to the methods or other block scoped variables - those are local, but attributes are global. If they are immutable - they are like programs constants, but when they are changeable - they are like global variables. And we know that global variables are bad.

Saturday, September 25, 2010

Managing Object Lifetime

This is the title of a blog post by Misko Hevery. There are also lot's of other materials authored by him freely available on the net. I have just started exploring them, and there is a lot of repetition if you just google around like me - but I already want to recommend it to anyone working on improving the design of their programs.

WebNano does not (yet?) meet all the design criteria he is talking about - but he is putting into words many of the foggy intuitions that made me not satisfied with all of the existing Perl web framework and write yet another one.

Thursday, September 23, 2010

Inheritance and rapid prototyping

There is much talk about the dangers of too much inheritance and how composition is better then inheritance - and probably they are right if we are talking about the final product. What they don't account for are the dynamics of the development - where you grab the first thing that does something similar to what you need and you start testing it, changing it, evaluating your ideas. Inheritance allows you to do exactly that - making changes to something that was already finished and working somewhere else. With procedural code this is not possible, the most similar thing you can get there are examples.

In other words Inheritance might lead to tightly coupled code, with intricate execution paths, but at least it is an easy way to get something working quickly. You can refactor it later.

Thursday, September 16, 2010

Installing Dist::Zilla plugins

Dear lazyweb - when I try out a distribution converted to DistZilla I often discover that I don't have all the plugins used there. Starting the work then consists of a string of 'dzil build' commands, searching the monstrous error stacks for the name of the missing plugin and then running cpan with it. Sure that should be automated!

And, by the way, it could also install the distribution's prerequisites.

Update: Repeating one of the comments - apparently the latest Dist::Zilla supports following solution dzil authordeps | cpanm.