Tuesday, November 13, 2007

Escaping CDATA

This is a handy code that wraps a string with CDATA escaping any CDATA inside it:


public static string CData(string data)
{
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}

string result = Regex.Replace(data, "]]>", "]]]]><![CDATA[>");
return "<![CDATA[" + result + "]]>";
}


Update: Clarity

Friday, November 9, 2007

Architects and programmers

I'm currently working in a project for a client bank. Some days ago we had a meeting where they showed us their IT's organizational chart which had been recently updated. They had two departments, one of them was made by business analysts and software architects, and the other department is the software factory where programmers are supposed to be. I interpreted that they were even physically two different sections. I'm not sure if I'm alone in this but I think this separation is wrong. I think that architects belong to the same space as developers because they are essentially the same thing.

Architects are programmers

We must notice that architecture is a subset of design which implies that an architect is a designer. Now, if we agree that programmers are the designers of software then a good programmer that is capable of designing this subset, is an architect. Also notice that there are no good architects that are bad programmers. Being a good programmer is a prerequisite for being called architect.

With a similar reasoning we can conclude that a programming language is not more nor less than a software design language.
Of course there are other tools to design software (diagrams, etc), but a programming language is better as its product is the only design representation that is directly interpreted by the computer and the only one that has a 1 on 1 relation between what you expect and what you get.
Used correctly, they are better at communicating a design than the alternatives.

So architects should program but they also should do it in the same physical space as the rest of programmers. Not only because they have to communicate their ideas but also for two extra benefits:
  • Feedback.
    Probably the most essential characteristic of software design is that it evolves by iterating. Even when doing waterfall, you evolve and iterate (the problem is that you stop too early doing so and you do it on paper). This evolution can only be done with realtime feedback and you won't get feedback if you are not inspecting and touching the guts of your child.
    You can only assess the correctness of your initial "paper level architecture" with the detailed "code level architecture", you should have a deep understanding of the most real representation of your architecture so you can be able to gather immediate feedback both against interpretation errors when some developer didn't understand you and against your own errors. Even if you are errorless (I don't believe that), feedback lets you learn about the domain and improve continuously your design.

  • Maximizing transfer of expertise and knowledge.
    If an architect is just a good and respected developer, then why not transfer its merits to the teammates. This would end up being a win-win situation because they'll keep improving and they know they will be responsible for the general improvement. The waste and problems that represent using programmers as if they were code generation tools is as silly as having not programming architects. Their design abilities must be improved. If they can't improve, well, then they are too stupid and risky even as a code generation tool, so don't hire them if you don't intend to use them as architects.


The separation problem

Divide and conquer it's a great heuristic. But if you fail to spot the point in which you should stop dividing, then it's counterproductive. Some things belong together. And when those things are split you'll find problems.
So if we have an architect that is not involved in programming we'll get two situations:
  • We have an excellent programmer, probably the best in our company, that is being used only for writing word documents and making presentations and diagrams. This is any design representation you imagine except the one in which he is good at and at the same time the one that is the more important and cannot be skipped. Yes, this is the one that is least understood by other departments of the company, but the architect role should be constructing software, his main target of communication are the programmers from the trenches. Communication with the rest is secondary.

  • We have a bad programmer that was choosen for some reason to make the architecture of the system. Let's not extend on this for obvious reasons.

Tuesday, November 6, 2007

A bit of metaprogramming

I added some functionality to the technique shown in this Jay Fields post so that you can retrieve your original method(s). You can use it for aspect programming but remember that if you want a real framework for doing so then just use AspectR or some similar library.

First you add your behaviour to an existent method:

class TestClass
def testMethod(param1, param2)
"Original output with parameters #{param1} and #{param2}"
end
end

class TestClass
after_method :testMethod do |returnValue, param1, param2|
"The original output is: " + returnValue
end
end

If now you call testMethod('a', 'b') you'll get this string:
The original output is: Original output with parameters a and b, so you successfully decorated the initial method.

Now if you want to get the original behaviour and remove your method decoration, just do:

TestClass.undo_after_method(:testMethod);

And now after sending testMethod('a', 'b') you'll get:
Original output with parameters a and b.

Here is the code:

class Class
def after_method(method_symbol)
previous_method = instance_method(method_symbol)

define_method(method_symbol) do |*args|
returnValue = previous_method.bind(self).call(*args)
yield returnValue, *args
end

singleton_class.push_previous_method(previous_method)
end

def undo_after_method(method_symbol)
method_key = instance_method(method_symbol).to_s.to_sym
previous_method = singleton_class.pop_previous_method(method_key)
if previous_method
define_method(method_symbol) do |*method_args|
previous_method.bind(self).call(*method_args)
end
end
end

def singleton_class
class<<Class;self;end;
end

class<<Class
#A hash that holds all the stacks.
#Each stack holds the current set of behaviours that decorate the initial method
@previousMethodsStacks = {}

def pop_previous_method(method_key)
previous_methods_stack = previous_methods_stacks[method_key]

if(previous_methods_stack and previous_methods_stack.size > 0)
previous_method = previous_methods_stack.pop

if(previous_methods_stacks[method_key].size == 0)
previous_methods_stacks.delete(method_key)
end
end
previous_method
end

def push_previous_method(previous_method)
previous_methods_stack = previous_methods_stacks.fetch(previous_method.to_s.to_sym) do
previous_methods_stacks[previous_method.to_s.to_sym] = []
end
previous_methods_stack.push(previous_method)
end

def previous_methods_stacks
@previousMethodsStacks
end
end
end

The RSpec tests are here.

Sunday, November 4, 2007

Functional programming

I remember making a Mastermind solving program in Erlang some years ago back in university. I enjoyed it a lot and I thought it was a shame that the functional programming paradigm was not mainstream.

Luckily it seems times are changing and you can find that Erlang is getting more popular, DSLs are getting attention (so Lisp will gain it too) and Microsoft seems to be slowly trying to put his own functional language, F# (ML), at the same level of C#.

So while surfing the web about this interesting times I found this very pleasant to read web page that can make you recover from your imperative programming comma. Good reading!

Saturday, November 3, 2007

About the object-relational impedance mismatch

I agree 100% with this Bob Martin's post about the problems that arise when using the Active Record data layer pattern.

I think Active Record's problems come from implementing it from the beginning of your project which has the risk of biasing your design towards a weak domain model. You will tend to make design decisions that fit well with Active Record and it will be more difficult to realize you should be refactoring towards having a domain model.

You can't be sure whether your app will be really data-centric until it's finished and the most flexible design to cope with this doubt is starting with the simplest domain model. If at the end it gets anemic and you don't find it's behaviour outside, possibly in a service layer, then you can substitute it with the data layer, which could be Active Record.

So I like Martin's idea of considering the datalayer as an implementation detail. It may be an important detail, but details don't belong to abstractions, and if you mix them you fix'em (sorry couldn't avoid that).

It's easier to start flexible and then tighten than start tight and then get flexible.

So I think it's easier to add Active Records to your domain models than adding a domain model to your Active Records. And you'll have the advantage that you are not tied with a particular Active Record implementation.

I'd use a pure AR solution only if I'm very very sure that I'm dealing with a simple CRUD that won't change in the future, and even then I'd feel uncomfortable. The application may be data centric now but you can't be sure if it will keep being that way in the future. You don't know that even if you are the only client of the app.