Synthetic Classes

Ovid on 2009-10-12T12:52:02

A synthetic class is one written by the compiler and which doesn't correspond to code a programmer has written. It's an obscure term and because it meshes well with synthetic code, I'm going to borrow this term for something else entirely. Other suggestions welcome.

Side note: I've not forgotten about the discussion from my last post, but I'm waiting for a response on one issue from the Moose mailing list, so continuing that will have to wait. Now buckle up and let's get rolling.

Your boss is upset. Seems Little Timmy's mother is upset because Little Timmy enjoyed that bottle of Port-finished Glen Morangie he ordered from your Web site. This shows two things. First, Little Timmy has excellent taste in whiskey. Second, your order process sucks.

Your boss comes to you and says "whenever someone tries to add an age restricted item to their shopping cart, verify their age before adding the item."

Ignoring the technical issues of age verification, notice anything about that? Your boss talked about things like "shopping carts" and "items" which are probably represented by classes in your system. Your boss did not talk about your persistence layer, your audit system or anything else which the customer does not see or care about. You will probably have to have a shopping cart object, but the persistence layer is an artifact of the problem you're trying to solve. More on that in a moment. First, let's look at synthetic code.

Mark-Jason Dominus described "natural" code as code which solves your problem and "synthetic" code as code which relates to other code. Part of the reason we like Perl is because we can spend a lot of time solving customer problems instead of language problems. Here's how you used to have to iterate over things in Java:

Iterator urlPatterns = getUrlPatterns().iterator();
while (urlPatterns.hasNext()) {
    String urlPattern = (String)urlPatterns.next();
    ...
}

Fortunately, their enhanced for loops makes this simpler:

for (String urlPattern: getUrlPatterns()) {
    ....
}

The first Java snippet shows the ugliness of synthetic code and the second version shows how Sun realized that reducing synthetic code is valuable.

Ah, but don't be so smug! We get this in Perl, too.

for my $i (0 .. $#some_array) {
    my $object = $some_array[$i];
    if (my $new_object = munge($object)) {
        $some_array[$i] = $new_object;
    }
}

Of course, those of you familiar with aliasing in for loops know you might be able to get away with this:

for (@array) {
    if (my $object = munge($_)) {
        $_ = $object;
    }
}

But if you know that, you know the pitfalls here, too.

So synthetic code is code which often works around issues with the underlying language or with your design, but the more synthetic code you have, the more bugs you're likely to have. Unfortunately, synthetic code is needed and this is why we earn our paychecks.

So when your boss talks about business classes, you have to also consider "synthetic" classes. I think of these as classes designed to deal with implementation issues rather than solving the core business needs. For example, object persistence is only an artifact of the fact that we need to track state over time. Imagine that your business has now transformed into a middle layer between customers and suppliers and you merely proxy transactions for a profit. It's conceivable (albeit unlikely) that much of your persistence layer goes away while retaining the need ShoppingCart class.

Synthetic classes tend to represent abstract concepts (not "abstract" as in "class") which don't map well to the end-users knowledge. These classes might be involved with HTTP modelling, auditing, object persistence and so on. A business class represents a customer, your Web site, an order, and so on. The synthetic classes may be created, replaced or eliminated as needed, but you still still probably need a Web site unless your core business changes.

So what does all of this mean? As I continue doing research into roles, I'm finding that things I would traditionally consider to be synthetic classes make prime candidates for roles (these aren't the only cases for roles, however). They tend to be cross-cutting concerns and if instantiated, tend to be rather artificial things with strange interfaces which don't intuitively map to our understanding.

Thus, in looking at roles this way, business classes are sometimes aggregations of roles which were previously synthetic classes. While people talk about "God Objects" and express concern that I'm going down this route, I'm finding that assembling a class out of a set of predefined components very appealing. The upside of this approach is obvious: you tend to be exposed to a core set of classes which map cleanly to the problem domain rather than to the problems of the problem domain. Or the problems of the problems of the problems of the problem domain. This, to my mind, is a win.


AOP

nothingmuch on 2009-10-12T14:32:09

This distinction lies at the heart of aspect oriented programming, where the idea is that using declarative decorations you can add additional aspects without introducing the cross cutting concerns into the main flow (herein referred to as the "natural" code).

The general idea is that if the natural code is well factored then it is easy to use a hook based system to do things like passing around shadow parameters, wrapping with hooks, adding validation, etc.

AOP calls the "synthetic" code "advice". Advice is attached to code using point cuts, which are descriptions of the conditions for a the hook to be triggered. When the natural code executes and reaches a join point, a precondition described in a point cut, the advice is executed.

Re:AOP

Ovid on 2009-10-12T15:39:14

From what I've read about AOP, for the developer to truly understand it, he/she needs proper tool support external to the language (such as the AspectJ integration in Eclipse). This seems wrong to me. Defining advice in a file and having that silently alter the behavior of other classes is classic action at a distance. An unknowing developer might change the name of a method, thus eliminating the join point. This seems to be a constant criticism of AOP that I read about.

Join points, from what I see, alter methods found with match the join point pattern, but if that pattern is not there, it's a silent failure. A role's requirements not being met, however, are a composition-time failure.

With roles, you have to do a bit more work to explicitly add the role to the affected classes, but by being explicit, you can gain the advantages of AOP without less mysterious "action at a distance".

So, what am I misunderstanding? :)

Re:AOP

chromatic on 2009-10-12T18:12:12

Defining advice in a file and having that silently alter the behavior of other classes is classic action at a distance.

Welcome to Java, where the solution to "This language is insufficiently dynamic!" is "Get a better IDE that lets you manage external XML files to inject reflection-compiled code at startup time!"

Re:AOP

Ovid on 2009-10-12T18:58:47

I've been using Eclipse lately and I think it has some great features (not all of which can be added to Perl), but I suspect it and similar IDEs are becoming so much of a crutch that some really stupid ideas are becoming popular with it.

Re:AOP

chromatic on 2009-10-12T22:19:26

There's a language design question.

How much can or should your tooling or community standards or patterns of usage make up for deficiencies of abstraction in your language?

The Java language and ecosystem have answered that question based on fundamental design goals of the Java ecosystem (backwards compatibility in the VM trumps almost everything else).

Likewise, I suspect the real reason Mono exists is as much tooling as it is anything else.

Re:AOP

nothingmuch on 2009-10-12T19:03:37

I was just commenting that the goals are similar to those of AOP, and that it might be worth to have a look at the prior art in that field.

Whether or not an IDE is necessary to use AOP is irrelevant. I've never used AOP (apart from playing with the Aspect module), but it was definitely interesting to learn why AOP is defined the way it is.

Your usage of roles in this case and AOP are very different implementations of a similar idea (that there are two "types" of code).

FWIW, Moose's method modifiers and their [ab]use in roles provides similar functionality to a very limited subset of AOP, where you opt in to accept point cuts, instead of just getting them randomly out of nowhere.

Re:AOP

chromatic on 2009-10-12T22:17:04

Your usage of roles in this case and AOP are very different implementations of a similar idea (that there are two "types" of code).

AOP was an inspiration for roles. This is why the phrase "cross-cutting concerns" appears in so many early discussions of what would become roles.

We don't get it in Perl too

Simon on 2009-10-12T17:16:57

...because, considering your example, Perl has a way of transforming stuff in a list:

@array = map { munge($_) } @array;

Nothing synthetic there.

Re:We don't get it in Perl too

Ovid on 2009-10-12T19:02:35

At least keep the code equivalent :)

@array = map { munge($_) || $_ } @array;

I changed the terminology

Dominus on 2009-10-14T02:05:27

I realized after a couple of years that architects have the same distinction. They have "structural" and "functional" elements. The simplest example is a tent. It has a functional element, which is the cloth; the cloth is the whole point of the tent, which keeps the rain off of you. But it also has a structural element, the tent pole, whose purpose is to hold up the cloth. The pole is a pure liability. If you could get the cloth to stay up with no pole, you would, but you can't.

So instead of "natural" and "synthetic" I now discuss it in terms of "functional" and "structural" code, which I think makes the point better.

Re:I changed the terminology

Ovid on 2009-10-14T07:15:52

Ah, "functional" and "structural" classes. This sounds much better. I didn't like the terms "business class" or "synthetic class" because both of those have overloaded meanings, but finding the right names is hard.

Anecdote

Dominus on 2009-10-14T02:06:32

I once had the chance to give the Red Flags talk in a beautiful conference room that had a giant column smack in the middle. It was a perfect illustration.

"Did the people designing this conference room say 'Let's make a beautiful conference room! It will have lots of windows, to let in natural light, and a big front wall with a giant whiteboard. And best of all, a giant column smack in the middle to block everyone's view of the speaker!'

"No, the column is there because without it, the building would fall down."