imageAspect-Oriented Programming (AOP) can help to clearly separate concerns. But it´s kinda cumbersome to do without a tool. At least if you want to do it along the beaten path of object orientation. But things become much more easy, when you switch your thinking to a different paradigm at least during high level design.

In a three part series on AOP with Event-Based Components (EBC) I´ve describe how this can be done. Easy AOP without a tool is possible. And it even makes your designs more understandable, I believe.

Part I introduces a scenario to apply AOP to. It´s a text file indexing application. In Part II I show how to beef up the application with simple aspects like logging, exception handling and validation. Then in Part III I use AOP to make the whole application multi-core friendly. Some parts become asynchronous, other´s are run in parallel. And the domain logic stays oblivious to that.

Come on over an read about EBC and AOP on The Architect´s Napkin

Have come to feel very uneasy with the usual object orientation. It simply does not deliver on its promises. That´s of course not the fault of object oriented languages like C# or Java or C++. It´s the fault of those who use them in a way that leads their code straight into a brownfield. And it´s the fault of those who cannot provide easy enough guidance in using these languages.

The situation is very dire. I have seen only a very few developers who do not fear clean whiteboard. Because when they are asked to draw the design for a software they hardly know what to do. Where to start, what to do next, when and how to begin coding so that in the end an evolvable whole is created.

Class diagrams are definitly not enough as a design tool. Nor are three boxes stacked upon another labeled “Layered architecture”.

Also Domain Driven Design (DDD) falls short of providing true guidance. It is full of valuable abstractions and concepts – but how to apply them to a software design task at hand?

Maybe this is bullshit to you and you find software design just plain easy and straightforward. You deem UML and OOA/OOD enough. Your software is based on OO principles and is highly evolvable. Then I congratulate you and would like to know more about how you´re accomplishing this.

imageBut maybe, just maybe my decription resonates with you because you too feel uneasy when it comes to software design (as opposed to software implemention aka coding). Then I´d like to invite you to follow along a series of articles I´m writing up in my architecture blog: http://geekswithblogs.net/theArchitectsNapkin.

Over the past months I´ve tried out a different way of designing software. A less object oriented one. One that´s less dependency focused, that does not need mock-frameworks for testing anymore. One that tries to deliver value to the customer right away. One that makes it easier to derive software architecture from requirements. One that makes AOP a first class citizen of any design. One that prepares designs for multi-core execution and distribution. And finally: One that keeps design and implementation in sync.

Sounds too good to be true? Well, see for yourself. It doesn´t cost you anything. Just hop over to The Architects Napkin – and suspend your disbelief for a couple of days while I´m writing up my current view of what I so far call Event-Based Components.

I´m looking forward to fruitful discussions with the community.

In my previous blog post I hopefully was able to demonstrate how low the entry barrier is to asynchronous remote communication. It´s as easy as hosting a service like this

   10 using(var serverSpace = new CcrSpace().ConfigureAsHost("wcf.port=8000"))

   11 {

   12     serverSpace.HostPort(

   13                     serverSpace.CreateChannel<string>(t => Console.WriteLine(t)),

   14                     "MyService");

and connecting to such a service like this:

   16 using(var clientSpace = new CcrSpace().ConfigureAsHost("wcf.port=0"))

   17 {

   18     var s = clientSpace.ConnectToPort<string>("localhost:8000/MyService");

   19 

   20     s.Post("hello, world!");

Under the hood this is net.tcp WCF communication like Microsoft wants you to do it. But on the surface the CCR Space in conjunction with the Xcoordination Application Space provides you with an easy to use asynchronous API based on *Microsoft´s Concurrency Coordination Runtime.

Request/Response

Calling a service and not expecting a response, though, is not what you want to do most of the time. Usually you call a service to have it process some data and return a result to the caller (client). So the question is, how can you do this in an asynchronous communication world? WCF and the other sync remote communication APIs make that a no brainer. That´s what you love them for. So in order to motivate you to switch to an async API I need to prove that such service usage won´t become too difficult, I guess.

What do you need to do to have the server not only dump the message you sent it to the console, but to return it to the caller? How to write the most simple echo service? Compared to the ping service you saw in my previous posting this is not much of a difference. Here´s the service implementation:

   11 public static string Echo(string text)

   12 {

   13     Console.WriteLine("SERVER - Processing Echo Request for '{0}'", text);

   14     return text;

   15 }

Yes, that´s right. It´s a method with a return value like you would have used it in a WCF service. Just make sure the request and the response message types are [Serializable].

And this is the code to host this service:

   19 using(var serverSpace = new CcrSpace().ConfigureAsHost("wcf.port=8000"))

   20 {

   21     var chService = serverSpace.CreateChannel<string, string>(Echo);

   22     serverSpace.HostPort(chService, "Echo");

The only difference is in the two type parameters to CreateChannel(). They specify this is request/response channel. The first type is for the request type, the second for the response type.

When does it start to become difficult, you might ask? Async communication is supposed to be difficult. Well, check out the client code. First it needs to connect to the service:

   40 using(var clientSpace = new CcrSpace().ConfigureAsHost("wcf.port=0"))

   41 {

   42     var chServiceProxy = clientSpace.ConnectToPort<string, string>("localhost:8000/Echo");

This isn´t difficult, or is it? Like before for the one-way ping service the client just needs to specify the address of the service. But of course the local channel needs to match the remote channel´s signature. So the client passes in two type parameters for the request and response message types.

And now the final part: sending the remote service a message and receiving a response. Sure, this looks a bit different from your usual remote function call. But I´d say it´s not all too inconvenient:

   44 chServiceProxy

   45     .Request("hello!")

   46     .Receive(t => Console.WriteLine("Answer from echo service: {0}", t));

You send the request by calling the Request() method with the request message. Then you wait for the response using the Receive() method passing it a continuation. It´s a method to be called once the response arrives at the caller.

Remember: This is asynchronous communication. That means the code after the Receive() will be very likely executed before (!) that of the continuation. So if you want to have a conversation between client and service you´d need to be a bit careful how you model it. Don´t just write channel.Request().Receive() statements one after another. But let that be a topic for a future posting.

For now I  hopefully was able to show you how easy request/response communication can be even in the async world. There are of course other ways to accomplish this, but here I wanted to show you the most simple way so you can get started without jumping through too many mental async hoops.

Request/Response in WinForms Applications

This is all well and good – but it won´t work in your WinForms application. Because when the response arrives it arrives on a different thread than the request had been issued from. And that means you can just simply display the result in a WinForms control. That can only be done on the WinForms thread.

I take up the challenge and demonstrate to you this is easy too using the CCR Space. Check out this tiny WinForms application:

image

Whatever you type into the text box gets sent to the echo service and returned in upper case letters only. You can guess how easy such a service will look:

   17 using (var serverSpace = new CcrSpace().ConfigureAsHost("wcf.port=8000"))

   18 {

   19     serverSpace.HostPort(

   20                     serverSpace.CreateChannel<string, string>(t => t.ToUpper()),

   21                     "Echo");

Also the client is as easy as before:

   23 using (var clientSpace = new CcrSpace().ConfigureAsHost("wcf.port=0"))

   24 {

   25     var chService = clientSpace.ConnectToPort<string, string>("localhost:8000/Echo");

But then to let the client form know about the service, the service channel is injected like any other ordinary dependency:

   29 Application.Run(new Form1(chService));

   15 public partial class Form1 : Form

   16 {

   17     private Port<CcrsRequest<string, string>> echoService;

   18 

   19     public Form1(Port<CcrsRequest<string, string>> echoService)

   20     {

   21         InitializeComponent();

   22 

   23         this.echoService = echoService;

   24     }

And how does the client form interact with the service so there will be no cross-thread calling problem?

   26 private void button1_Click(object sender, EventArgs e)

   27 {

   28     this.echoService

   29             .Request(this.textBox1.Text)

   30             .Receive(t => listBox1.Items.Add(t),

   31                      CcrsHandlerModes.InCurrentSyncContext);

   32 }

It´s the same pattern as above: call Request() on the channel and append Receive() to this call. However, as the final parameter to Receive() pass in CcrsHandlerModes.InCurrentSyncContext. This advises the client Space to switch to the WinForms synchronization context before executing the response message handler.

Notice, however, the signature of the remote service port. It´s Port<CcrsRequest<TRequest, TResponse>>. By wrapping the application message in a CcrsRequest<,> message the channel.Request().Receive() magic is possible.

Summary

Asynchronous communication certainly is different from synchronous. It takes some time wrap your head around it. And you certainly don´t want to start with it slinging threads yourself. But with a pretty high level async API like the CCR and the CCR Space provides, it´s not beyond the average developers reach, I´d say.

What´s next? I guess you want to know how errors are handled in distributed async scenarios. Let that be the topic of my next posting. Until then trust me: It´s much easier than with WCF ;-)

If you´ve read my previous posts about why I deem WCF more of a problem than a solution and how I think we should switch to asynchronous only communication in distributed application, you might be wondering, how this could be done in an easy way.

Since a truely simple example to get started with WCF still is drawing quite some traffic to this blog, let me pick up on that and show you, how to accomplish the same but much easier with an async communication API.

For simplicities sake let me put all the code of client and server in just one file. In the following sections I´ll walk you through this file. The service it implements is simple. I start with a ping service. The client sends a text message to the server; the server dumps the text to the console.

The implementation is based on Microsoft´s CCR and two layers of abstraction encapsulating the CCR as well as WCF. See, I´m not saying WCF is bad per se; I just don´t want to use it in my application code. As a low level communication infrastructure the WCF is just great.

The two layers of abstraction on top of the CCR and WCF are the CCR Space and Xcoordination Application Space (or AppSpace for short). Both are open source. The CCR Space wraps CCR concepts and the AppSpace to make it easier to work with them. And the AppSpace enables you to use CCR ports for remote communication.

From now on I´ll refer to both as “the Spaces” or “Space based communication”.

If you want to follow along my samples download the binaries from the CCR Space project site and reference the CCRSpace.dll as well as microsoft.ccr.core.dll.

Service implementation

With the Spaces it´s easy to define a service. No special service contract is needed. You can use any method with just one parameter and no return value. The parameter type needs to be serializable, though. Use the [Seriablizable] attribute for your own message types.

    1 using System;

    2 using System.Threading;

    3 

    4 using CcrSpaces.Core;

    5 

    6 namespace AsyncSimple.Server

    7 {

    8     public class Program

    9     {

   10         public static void Ping(string name)

   11         {

   12             Console.WriteLine("SERVER - Processing Ping('{0}')", name);

   13         }

Of course there are ways to define services with several methods (or to say it differently: which can process different message types). But for now let´s keep the service as simple as possible, like I did in the WCF sample.

Service hosting

Next you need to host the service. For that you create a CCR Space (CcrSpace) and configure it as a host using a certain transport layer (line 17). I´m using WCF with net.tcp binding as a transport, but I could also have used raw TCP sockets or WCF with named pipes or Jabber or MSMQ.

By passing “wcf.port=8000” to the configuration method the transport layer type is selected and the listening port specified.

   15 public static void Main(object state)

   16 {

   17     using(var serverSpace = new CcrSpace().ConfigureAsHost("wcf.port=8000"))

   18     {

   19         var chService = serverSpace.CreateChannel<string>(Ping);

   20         serverSpace.HostPort(chService, "Ping");

   21 

   22         Console.WriteLine("SERVER - Running...");

   23         Console.ReadLine(); // keep alive

   24     }

   25 }

Once the Space is running, the service is bound to a channel (line 19). The channel is used to send messages to the service.

To make the channel available for remote clients it´s hosted in the Space (line 20). This defines an address for the service listening on the channel. The service can now be reached over all registered transports by using their addresses combined with the service name; here that´s “localhost:8000” for WCF plus “Ping”: localhost:8000/Ping.

Is you leave out ConfigureAsHost() and HostPort() you get local communication instead of remote. With the Spaces it´s easy to switch between the two communication modes. The communication paradigm stays the same. No other changes are needed to your code. The only differene between local and remote async communication is hosting a port or not (and how you connect to a port depending on it being local or remote).

Client implementation

Since this is a self-contained example the client starts with kicking off the server:

   30 namespace AsyncSimple.Client

   31 {

   32     class Program

   33     {

   34         static void Main(string[] args)

   35         {

   36             ThreadPool.QueueUserWorkItem(AsyncSimple.Server.Program.Main);

Then comes the important part: connecting the client to the server and calling the service:

   38 using(var clientSpace = new CcrSpace().ConfigureAsHost("wcf.port=0"))

   39 {

   40     var chServiceProxy = clientSpace.ConnectToPort<string>("localhost:8000/Ping");

   41 

   42     chServiceProxy.Post("world!");

   43 

   44     Console.ReadLine(); // keep alive

   45 }

Like the server the client needs to instantiate a CCR Space. Async communication is symmetric. So both parties communicating need to look the same. Both “are” Spaces.

Since the client does not publish any services, its port is of no interest so I set it to 0 for the AppSpace to choose. But of course the client Space needs to use the same transport layer like the server (line 38).

Then the client connects to the service´s remote port using its address (line 40). From now on the client can send messages to the service through the channel (line 42).

Summary

That´s it. This is how easy async communication can be. This is how easy remote communication can be. The application does not bother itself with complicated WCF configuration. Think of all the concepts and terms you need to understand for that, e.g. ServiceContract, OperationContract, ServiceBehaviour, InstanceContextMode, ServiceHost, and ChannelFactory.

With the Spaces you just need a CcrSpace and a Port (aka channel). Create a space, create a channel and bind your service methode to it, host/publish the channel on the server, connect to the channel on the client.

Once you grog the communication paradigm (async message oriented communication) it´s only 4 lines of code to set up service and client.

And now tell me: Can it become any easier, and stay true to the nature of remote communication? I doubt it.

Please get me right, I´m not saying those Spaces are a panacea or the ultimate communication API. I´m just challenging WCF´s position as the one-size-fits-all solution to remote communication. There are alternatives to WCF. Service busses like NServiceBus or Mass Transit are alternatives, but I think to use them seems to be an overkill for developers in many scenarios. That´s why I´m trying to show you a another alternative: Space based communication. It kind of looks like regular service communication, but it´s all asynchronous like the busses.

Ok, if this still sounds interesting to you, you sure have a couple of questions. How to do return a result from a service? How to notify clients of service progress? How to deal with service failures? Bear with me, I´ll try to answer them in the next couple of postings. For now I just wanted to show you how easy it is to get async remote communication running at all.

In my previous blog post I argued WCF was not the most usable and most easy to learn way for communication in distributed applications. This is due to its focus on synchronous communication (even though you can do asynchronous communication as well).

Distributed applications by their very nature cannot communicate synchronously. Their parts are running on different threads (or even machines). And communication between threads is asynchronous. Always. And if it appears otherwise then there is some machinery behind the scenes working hard on that.

Now, if distributed functional units are running on different threads, why would anyone even try to hide that fact? Why do Web services, Enterprise Services, .NET Remoting, and also WCF abstract away this inherent parallelism? Well, it´s because asynchronous communication and asynchronous systems are harder to reason about.

Great, you could say. That´s what I want: easy to reason about systems. Isn´t that purpose of abstraction? Making complex things easy?

Well, sure. We love C# as an abstraction for how to command a processor. Nobody would want to go back to low level assembler coding.

But not just any abstraction is a good abstraction. Some abstractions are, well, “unhealthy” or plain wrong. Think of the abstraction “man is like a machine” and all its implications for the health industry.

Abstractions usually have a limited scope. Treating humans like a machine when “repairing” a wounded finger might be ok. But when treating cancer, physicians surely should view their patients differently.

So the question is: When to stop using an abstraction? Or whether to use it at all.

That´s what I´m asking myself regarding WCF. When should I stop using it and start coping with the asynchronous nature of distributed systems myself?

My current answer is: I should not even start to do remote communication with any synchronous API. And my reason is simple:

  1. The communication paradigm (sync vs async) is very fundamental to any application. Switching it in mid course is usually very hard.
  2. Async communication is the sine qua non for truely scalable systems.
  3. Our industry is notoriously bad at forseeing the course of development of applications. Many start small, as a prototype – just to become mission critical with the need to scale far beyond the initial purpose. (I´m sure you too know at least one of those MS Access applications that have become unmaintainable but need to live on because today maybe hundreds of people are depending on them.)

Taken together this means: Systems start small, even when distributed. So they use a sync communication API. Then they grow, need to scale, and thus need to switch to async communication – which then is probably infeasible or very hard to accomplish.

So when I´m saying, “You should not even start to do remote communication with any synchronous API.”, I´m just trying to apply lessons learned. If we know switching from sync to async is hard, and if it´s very likely this switch will be necessary some time in the future (because, well, “you never know” ;-)… then, I´d say, it´s just prudent to not go down the path, that might be easier at the moment, but will be much harder in the future.

There´s a time and place to do synchronous communication between functional units. And there´s a time and place to do asynchronous communication. The latter being always the case when developing multi-processor code or distributed code.

The earlier a developer learns to see this boundary the better.

Enough with theory for now. Let´s get our hands dirty with some code.

Switching from sync to async using the CCR

How can you start with asynchronous programming? Let me say that much: Don´t even try to manage threads yourself! Instead leave that to some framework or runtime. Concentrate on an easy programming model.

The programming model I´m going to use is purely message oriented and based on “pipes” through which those messages flow. A client “poures” message into such a “pipe”, and a service at the other end “ladles” them out in order to work on them.

You can implement such a programming model using queues. But I recommend you don´t think about doing it yourself ;-) Instead use an existing component like Microsoft´s Concurrency Coordination Runtime (CCR). It´s part of Robotics Studio, but can also be use standalone. All I´m gonna show you in terms of async and distributed communication will be based on the CCR. I just love it :-)

Here´s the notorious Hello World code snippet to show you, how messages are sent using the CCR:

using Microsoft.Ccr.Core;

var p = new Port<string>();

p.Post("hello, world!");

The “pipes” I was referring to are called Ports in CCR lingo. They are queues – but thread-safe ones.

So this is how a client sends a message off to some service. It just stuffs it into a Port and forgets about it. The message is processed asynchronously by the service.

To let a service listen for messages on a Port is somewhat cumbersome using just the CCR. But I´ll show you anyway, even though later on abstraction layers on top of the CCR will shield you from such details (most of the time).

Assume there is a service method like this:

void ProcessText(string text)

{

    Console.WriteLine("processing: {0}", text);

}

Never mind its simplicity. For the purpose of explaining the communication basics it´s sufficient. What you want to learn is how to make it listen on a Port. Here´s how:

Arbiter.Activate(

    new DispatcherQueue(),

    Arbiter.Receive(

        true,

        p,

        ProcessText

        )

    );

You need to set up a so called Receiver on the Port. The Receiver is associating the service method (ProcessText()) with the Port (p) as an event handler. The DispatcherQueue then is used to schedule event handling by the service method on some thread from a pool. Messages posted to the Port are automatically processed asynchronously and in parallel on background threads.

But as I said: Don´t feel frustrated right now. You won´t need to wire-up event handlers like that very often just to do distributed communication the async way. If you nevertheless want to learn more about the CCR, feel free to browse its documentation.

The only thing you have to remember is: Async communication flows through CCR Ports from clients to services as messages. You can even call those Ports channels, if you like – and feel at home since WCF has channels, too ;-) for the same reason as the CCR. Because WCF is message oriented and deep down internally even works asynchronously. It just does not show that to you very often or in an elegant way.

Why asynchronicity for distribution?

Before I move on to API details a quick word about why I think asynchronicity is fundamental for communication in distributed applications. Look at this code:

IService s =

s.ProcessText("hello, world!");

What expectations to do have about how the service is delivered? Think about it for a moment…

If you´re like me, you probably thought at least…

  • ProcessText() better be fast because the client is waiting for the result.
  • You need not bother to think about how often to call the service object. Why should you?
  • There is no doubt there is an object where s is pointing to. So there is no doubt the service ProcessText() will be delivered.
  • The order the client is giving the service will of course reach it, and the result the service produces will sure reach the client.
  • There is of course no security risk in calling the service. Why should there be?

Or maybe only the first thought occurred to you? That would be quite naturally, I guess. Because why should you even think about the other points at all? They are non-issues for method calls.

And that´s what I find important: Since the usual Web service-, .NET Remoting-, Enterprise Services-, WCF-call is a method call like any other local method call, developers tend to don´t even think about all that what is so different in remote communication.

  • You cannot assume any particular performance from a remote service because you don´t know anything about its load at call time. So your client better is prepared to wait just a little longer for a response.
  • Since remote communication is 3 or more orders of magnitude slower than local stack based communication you need to very cautious about how often to call a service. Roundtrips are very expensive.
  • You cannot be sure a remote service is running when you issue a call to it. Maybe it has crashed, maybe it hasn´t started yet, maybe it has been taken offline for whatever reason… So waiting for a quick response is not such a good idea.
  • Even if the remote service is running you don´t know if the client can reach it. Maybe the connection is down? Maybe the connection is going down after the order is issued but before a result could be returned? Another reason why you should not rely on a response to be delivered in a time frame it would be worth while waiting for on the client side.
  • And what about eavesdroppers on the line between client and service? Have measures be taken to thwart them?

As long as you cannot decide by looking at a service usage whether it´s a local service or a remote service you can´t be sure if all this has been taken into account. That I find very disturbing. To me a remote service usage through a regular method call like above thus is kind of misleading, fostering falling prey to fallacies, or simply lying. It´s lying about very basic properties, because 99% of the time we´re looking at method calls and don´t have to bother about all this.

Now, that´s all different when you see this in a code base:

Port<ProcessTextMsg> service =

service.Post(new ProcessTextMsg{Text = "hello, world!"});

You immediately realize: This is not just any ordinary request for a service. This is special, because it´s asynchronous and clearly message oriented. And then you start thinking about whether the properties of this service usage are really like what you expect.

  1. Performance is not so much of an issue anymore because the client is not waiting for a result.
  2. True message orientation is a tad more cumbersome to use. This makes you (more) aware of the price you´re paying when requesting remote services. You automatically become cautious about roundtrips. This will guide you when designing a service contract.
  3. If the remote service is not running, the request can easily be put into a queue which can be volatile or persistent.
  4. If the connection to the service is down or goes down, then queues can help again. They can even be transactional.
  5. Since you´re aware of the nature of the connection to the service you are more prone to give security at least a thought.

You see, I don´t want to take away the usual sync method call for remote communication from you lightly. I think there are at least 5 good reasons why distributed communication should always be async. Always.

But of course, you don´t want to pay too high a price for such “honest communication”. So let´s see what we can do about usability when going asynchronous. Stay tuned for my next blog post…

Posted by Ralf Westphal | 4 comment(s)
Filed under: , , ,

The title of this post has caught your attention? So let me explain what I mean by it: I think WCF is great. It´s the best communication framework Microsoft ever has come up with. WCF solves a lot of problems of its predecessors, it is tremendously extensible, and it supports the main communication paradigms (sync, async, P2P). WCF certainly is a solution of some kind.

But to whom? Who benefits from all these capabilities of WCF? Is it the average application programmer? I doubt it.

Remember when first Webservices and .NET Remoting came out? The Microsoft developer community rejoiced. What a relieve compared to sophisticated COM+ and raw TCP socket programming. Developers were so glad, remote communication finally became easy, usable.

Unfortunately this did not last long. Webservices hit their limits and needed to be amended with tons of WS-* standards. .NET Remoting hit its limits when it turned out that remote stateful objects really were a bad idea in terms of scalability.

So Microsoft set out to unify remote communication and do close any conceptual holes. Out came true message oriented WCF, the one size fits all communication API.

Well, great. I love WCF for this.

But I don´t like it for two things:

  • I strongly believe that remote communication should always be asynchronous. Yes, always. Because that´s how autonomous systems communicate. And if you deny that fact you run in all sorts of problems. It´s a case of LOLA. So WCF is betting on the wrong horse with its focus on synchronous communication. (And I say “focus” because you can do async communication with WCF. But do you really want to?)
  • WCF tries to be a Jack of all Trades. Its drive to unification is so strong it has lost sight of usability. Webservices and .NET Remoting had so much appeal because they promised to finally make remote communication simple. But then they failed. Not because their APIs did not live up to the promise of simplicity, but because they too bet on the wrong horse: synchronicity.

Let me say it like this: WCF is great in the hands of experts. But Microsoft should not expect developers to become WCF experts en masse.

I feel reminded of the early 1990s. Back then there was the Windows API for doing Windows programming. And you could do cool stuff with it. But, let´s be honest, you had to be an expert for doing that. And even Charles Petzold had not been able to turn masses of developers into expert Windows GUI programmers.

Enter VB 1.0.

And the world changed completely. Suddenly just about any developer was able to do Windows GUI programming. Maybe not all outcomes were as beautiful and usably as their creators thought, but anyway. Windows GUI programming had become a mass phenomenom almost overnight.

Today WCF to me seems to be the new Windows API. So much is possible – if you´re an expert. But even Don Box and Juval Löwy together won´t be able to turn developers into WCF experts en masse.

That´s why I think WCF is not the solution but the problem. By its very nature it stands in the way of solving the remote communication problems for Joe Developer. It has made it much easier to do certain things for many developes. But still the average developer is baffled by its complexity.

Almost three years ago I wrote a small blog article on how to start using WCF: A truely simple example to get started with WCF. And since then it´s one of the most popular articles in this blog. Why´s that so? Because WCF is so darn difficult to learn, you really need all the help you can get.

That said, what can we do? Put up with WCF? I don´t think so. We need the equivalent of VB for the world of remote communication. We need some layer of abstraction on top of WCF lie VB was on top of the Windows API.

WCF is here to stay. Great!

But as an application developer I certainly don´t want to need to use WCF directly. To an application programmer WCF like Tcp Sockets are a problem, not a solution. A learning and usability problem.

We need some communication API which brings back usability and understandability like .NET Remoting, but at the same time gets it right. That means at least it must not be synchronous but asynchronous.

If you agree with me, say aye ;-)

Next time I´m going to give you an idea of how such an API might look.

Posted by Ralf Westphal | 9 comment(s)
Filed under: , , ,

In his recent blog posting Seth Godin once again questions the value of competence. Sure, he does not want to people dumber. He just argues that sole reliance on competence as a compass to navigate the future can - well - be a hindrance. He´s written about it already in 1999 and made clear, that competence is about accomplishing something on the basis of existing knowledge - and thus is different from finding new ways of doing stuff. Whoever is competent is not necessarily innovative or imaginative. But that´s what we need in the face of constant change.

If the environment keeps changing you need to constantly adapt. Adaption is trying out new ways of coping with the environment - hopefully finding better ways to deal with it than in the past. So adaption needs innovation, not competence.

To understand what Seth Godin means and what I see necessary for the software industry let me put the argument about competence into perspective:

In the beginning of any issue there is incompetence. People have a hard time to get things right. The need to build up competence. They need to gather a body of knowledge and rules. Conventions need to be established on how to most effectively reach desired results. This is the pre-phase of any issue. It´s pre-conventional.

Then there is a long phase of competence. It´s about rules, regulations, canonicallity. Conventions rule, so to speak. There is a way to do things right. To become competent you learn to adhere to the rules. Whoever knows and executes the rules best is most competent. You don´t know the rules, you´re incompetent - say the competent ones. It´s a phase of duality. The good are the competent people, all others are the bad who need to be converted (or just faught). To the competent ones this phase is the pinnacle of development.

But, alas, the competence phase is just a phase. Although many can live in it pretty well, in the end it´s a dead end. Innovation is hard under a regime of competence driven people.

Enter the next phase: After competence comes... conscious incompetence. Transcending competence is about knowing when it´s right to apply - and when not. Whoever "is trans" (and not just competent) knows the rules, but feels free to abide by them or not. He knows about the reasons behind the rules, their history, the conditions that once formed them. So if conditions change he can step over any no longer fitting rules and start anew as a "pre".

The cycle of pre->conventionalism->trans starts again. And with it begins innovation.

Becoming trans might not be for everyone in the competence phase. But at least the competence people should recognize the importance of stepping up. So they should allow for people to become trans and move on. They should even foster trans-formation.

Not seeing beyond the pre- or conventionalism-phase is falling prey to the pre-trans-fallacy. It´s either asserting there is nothing beyond competence. Or it´s asserting to already be trans. The latter might be more dangerous, because it´s mostly mixing up being pre with being trans. "No rules" is true in the pre and trans phase - but for different reasons. Whoever is pre denies the rules or the necessity of any - just per se. But who´s trans has gone through learning rules but sees their limitations - and thus does not feel compelled to abide by them. However, being trans means to empathically admit the (passing) phase of conventionalism.

So if we want to move on in the software industry we need to be conscious of not falling into the pre-trans-fallacy trap! Otherwise we might get stuck with our software projects in the ever changing morast technologies and requirements.

PS: If you want to read more about the pre-trans-fallacy try to google it. But never mind the context of spirituality and esoteric thinking. Although the fallacy got pointed out first in those circles it does not mean it can´t be applied to technical issues.

As I read Kevin Kelly´s "Fate of the Book" I come to wonder what this debate he´s referring to is all about? Is it about form or content? Is is about texts as opposed to video or audio? Is it about texts of a certain minimum length and/or structure as opposed to text snippets? Or is it about a certain physical container for texts as opposed to digital texts? Or is it about certain types of physical containers?

Until digital word processing it was pretty clear what a book was: a text longer than a couple of pages bound and put between covers. Text of a minimum length in a certain physical form made a book.

Since then, though, because we all write texts using word processing software and don´t need to print them out anymore to have other´s read them, since then what a book is has changed. Or at least if you talk about books you need to be more specific what you mean.

Today, I´d say, a book can be at least two different things: it can be the traditional book as described above. Go to a bookstore of your choice and you find thousands of them there. Or a book can be just a imagedigital text you call a "book". It could be just 10 pages with a single sentence on each page or it could be 500 pages full of small print text. If you assume this point of view, it´s pretty much up to you what you call a book.

Well, before you call a digital text a book, I think, something more needs to be added. Just text is not sufficient. Otherwise any blog posting like this would be a book. If you want a text to be a book, you need to prep it up a little bit. You need to make it print-ready. It should be typeset on electronic sheets of paper; also it should sport at least a title page. But other than that... pretty much any text can be called a book. Because, if you can print it and bind it, well, it becomes a "traditional" book.

So my bottom line is: essentially the book is in the eye of the beholder. Take any text you like, print it out, bind it, voilá, there´s your book.

But that´s certainly not what the debate is about. What is in question is: What´s the fate of texts longer than a couple of pages? And what´s the fate of the physical form of the book - regardless of whether it containers 5, 50 or 500 pages?

Physical Books - Quo Vadis?

It´s difficult but I´ll try to abstract from my personal taste. I like physical books. But just because I like them they don´t need to exist indefinitely. So if I try to subtract my emotional attachment from the picture, what´s left?

image I think the benefit of having a physical book in one´s hands is underestimated. Reading a book is more than "taking in" a text by scanning pages full of letters. It´s like following a conversation right in front of you. There are not just words, but real people who send signals on different "channels". It´s how they look, how they move, how their whole body language is. Following a conversation in a conference call is much more difficult.

Likewise reading a text online is more difficult than reading it printed out. And reading it on just a couple of loose pages that came out of a desktop laser printer is more difficult than reading it as a book. A book provides a context, it provides input through more than the visual sense. A physical book makes a text tangible - even more than some printouts. It literally manifests the thoughts behind a text.

If we realize this, we realize the age of the physical book is not over. Because there will always be texts which highly benefit from being "taken in" with more than the visual sense. And we should not think ePaper or Amazon´s Kindle are a danger for physical books. They simply don´t provide the total sensual input of a physical book.

Whoever want´s to read most effectively and with most please will always want a book in his/her hands.

Digital Books - Quo Vadis?

Digital books, i.e. digital texts of a certain length and form, as opposed to blog postings or podcasts are on a rise, too. Linear text is not dead. As useful as linked digital text snippets and other media are, digital books will stay useful too. Why´s that?

It´s because of the benefits of longer sequential texts for readers and authors alike.

image Readers benefit from sequential texts because they help guide and focus their thoughts. The ability to choose among any text at any moment is good; but for most people it´s hard to not just be free to decide what to do next, but to be actually forced to decide. Especially when reading for recreational purposes and learning something new it thus is a virtue to provide guidance and focus for the reader´s mind. A digital book lowers the cognitive effort a reader needs to invest to immerse herself in a topic.

That´s not to say we all should only read books. Of course not! I just want to put books and other media and textual forms in perspective. Different forms are optimal for different purposes. Until quite recently there were only physical books to transport knowledge and stories in a 1 to many way. That´s completely different today. So we can and have to choose which form and media to use for which purpose. Today almost everyone can choose between digital text, video, audio, pictures, and drawings - all of different forms. That´s good and won´t go away anymore. But it does not mean longer sequential texts are of no use anymore. Right to the contrary! We´re just in a transitional period where we need to assess all the new toys at our fingertips. It´s like with desktop publishing some decades ago: when it was new, everybody tried out all those new fonts. And many DTP products looked ugly. This period is over, we´ve learned how to use all those options in a beneficial manner. Times Roman and the Golden Section have survived the turmoil. So will the digital book.

Not only readers benefit from sequential texts, authors do, too. Finding an easy to read sequential textual layout for a topic is a process which excersises the author´s complete knowledge about his topic. And not only that, it also requires him to think very hard about the reader, the receiver of his text message. Shredding a topic into hypertext pieces is easy. But it easily puts the burden on the reader: he´s the one who needs to piece together the picture of the whole topic.

Hypertexts and text snippets seem to have "explorative learning" and the ubiquitous "time crunch" in their favor. But in the end, quite often they leave the reader alone, don´t provide guidance, and cost more time than a (good) sequential text.

An author should not let himself get lured into producing modern forms of text just because they are, well, modern and make writing easier for him. An author always needs to have his audience in mind. And that´s easier if he needs to wreck his brain to come up with a single sequential text for whatever he´s to say.

The Future of the Book

Their is a future for books (and magazines, for that matter). But it will look different than the past. Books cannot stay the same.

Firstly printed books need to become digital. Only eBooks provide all the flexibility readers want to have - including the option to print and bind them.image

Secondly the eBooks of the future need to become modular, at least whatever is not a story. Again because readers want the flexibility to just buy or print parts of a larger textual body. Why buy a whole eBook if I´m just interested in chapters 6 and 27 out of 48? Such flexibility was not possible in a world of physical books only - but it is in the digital world.

Thirdly eBooks or just any text needs to be easily printed and bound as a book. Printing texts is not on a decline but rather on a rise. As argued above reading text on paper bound as a book makes understanding it easier. And it still makes it much more portable. That means, whoever wants to read effectively with his/her whole body will want to print longer sequential texts and bind them. Print-on-Demand (PoD) and desktop laser printers are not up to that task. A world full of eBooks needs new, to be invented printing services.

Since I´m mostly concerned with software architecture and my clients are asking again and again when I´m going to write a book about the topic, I finally decided to set out and compile the material to go into the book. And I decided to do it publicly, in a new blog.

Not that I haven´t done that before here and in my German blog. But now I´ll try to be more comprehensive, put everything in a single place, and add some new stuff I have not written about before. Plus, through a blog all´s open for discussion.

So if you like, have a look at The Architect´s Napkin. It´s the title of my blog, because I think, software architecture is not an arcane art to be practiced by just a few chosen in ivory towers, but can and needs to be practices by almost all developers at some point in time. So it better be easy - and what can be more easy than something that can be done on the back of a napkin?

So the architectural images you´ll see in the blog are like this

image

or like this

image

None will be more complicated than whatever fits on a napkin in a readable and understandable way. I strongly believe in the power of visualization; and I believe that any minute invested by an architect into a simpler depiction will save his developers hours of head scratching.

Hope to see you over there at the bar at www.geekswithblogs.net. I´ll be there sketching some architectures while sipping a cocktail...

image

image Please find the sample code for my presentations at Software Architect 2008 on Aspect Oriented Programming with PostSharp and Software Transactional Memory with NSTM here for download:

http://www.ralfw.de/download/Software_Architect_08_Samples.zip

If you´ve any questions, feel free to contact me by email.

Enjoy!

More Posts Next page »