Sunday, March 16, 2008

I recently participated in a webcast covering SOA, REST and various related topics. You can listen to it here

http://www.slickthought.net/post/Minneapolis-Developer-Roundtable-Podcast---Talking-REST.aspx

Sunday, March 16, 2008 6:32:37 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  | 

 Thursday, January 24, 2008

I reader recently sent me an email asking why the PTWebService project in the CSLA .NET ProjectTracker reference app has support for using the data portal to talk to an application server. His understanding was that web services were end points, and that they should just talk to the database directly. Here's my answer:

A web service is just like any regular web application. The only meaningful difference is that it exposes XML instead of HTML.

 

Web applications often need to talk to application servers. While you are correct – it is ideal to build web apps in a 2-tier model, there are valid reasons (mostly around security) why organizations choose to build them using a 3-tier model.

 

The most common scenario (probably used by 40% of all organizations) is to put a second firewall between the web server and any internal servers. The web server is then never allowed to talk to the database directly (for security reasons), and instead is required to talk through that second firewall to an app server, which talks to the database.

 

The data portal in CSLA .NET helps address this issue, by allowing a web application to talk to an app server using several possible technologies. Since different organizations allow different technologies to penetrate that second firewall this flexibility is important.

 

Additionally, the data portal exists for other scenarios, like Windows Forms or WPF applications. It would be impractical for me to create different versions of CSLA for different types of application interface. In fact that would defeat the whole point of the framework – which is to provide a consistent and unified environment for building business layers that support all valid interface types (Windows, Web, WPF, Workflow, web service, WCF service, console, etc).

Thursday, January 24, 2008 8:01:56 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  | 

 Monday, November 05, 2007

I was recently asked how to get the JSON serializer used for AJAX programming to serialize a CSLA .NET business object.

From an architectural perspective, it is better to view an AJAX (or Silverlight) client as a totally separate application. That code is running in an untrusted and terribly hackable location (the user’s browser – where they could have created a custom browser to do anything to your client-side code – my guess is that there’s a whole class of hacks coming that most people haven’t even thought about yet…)

So you can make a strong argument that objects from the business layer should never be directly serialized to/from an untrusted client (code in the browser). Instead, you should treat this as a service boundary – a semantic trust boundary between your application on the server, and the untrusted application running in the browser.

What that means in terms of coding, is that you don’t want to do some sort of field-level serialization of your objects from the server. That would be terrible in an untrusted setting. To put it another way - the BinaryFormatter, NetDataContractSerializer or any other field-level serializer shouldn't be used for this purpose.

If anything, you want to do property-level serialization (like the XmlSerializer or DataContractSerializer or JSON serializer). But really you don’t want to do this either, because you don’t want to couple your service interface to your internal implementation that tightly. This is, fundamentally, the same issue I discuss in Chapter 11 of Expert 2005 Business Objects as I talk about SOA.

Instead, what you really want to do (from an architectural purity perspective anyway) is define a service contract for use by your AJAX/Silverlight client. A service contract has two parts: operations and data. The data part is typically defined using formal data transfer objects (DTOs). You can then design your client app to work against this service contract.

In your server app’s UI layer (the aspx pages and webmethods) you translate between the external contract representation of data and your internal usage of that data in business objects. In other words, you map from the business objects in/out of the DTOs that flow to/from the client app. The JSON serializer (or other property-level serializers) can then be used to do the serialization of these DTOs - which is what those serializers are designed to do.

This is a long-winded way of saying that you really don’t want to do JSON serialization directly against your objects. You want to JSON serialize some DTOs, and copy data in/out of those DTOs from your business objects – much the way the SOA stuff works in Chapter 11.

Monday, November 05, 2007 11:53:58 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Friday, June 01, 2007

The WCF NetDataContractSerializer is an almost, but not quite perfect, replacement for the BinaryFormatter.

The NDCS is very important, because without it WCF could never be viewed as a logical upgrade path for either Remoting or Enterprise Services users. Both Remoting and Enterprise Services use the BinaryFormatter to serialize objects and data for movement across AppDomain, process or network boundaries.

Very clearly, since WCF is the upgrade path for these core technologies, it had to include a serialization technology that was functionally equivalent to the BinaryFormatter, and that is the NDCS. The NDCS is very cool, because it honors both the Serializable model and the DataContract model, and even allows you to mix them within a single object graph.

Unfortunately I have run into a serious issue, where the NDCS is not able to serialize the System.Security.SecurityException type, while the BinaryFormatter has no issue with it.

The issue shows up in CSLA in the data portal, because it is quite possible for the server to throw a SecurityException. You'd like to get that detail back on the client so you can tell the user why the server call failed, but instead you get a "connection unexpectedly closed" exception instead. The reason is that WCF itself blew up when trying to serialize the SecurityException to return it to the client. So rather than getting any meaningful result, the client gets this vague and nearly useless exception instead.

By the way, if you want to see the failure, just run this code:

    Dim buffer As New System.IO.MemoryStream
    Dim formatter As New System.Runtime.Serialization.NetDataContractSerializer
    Dim ex As New System.Security.SecurityException("a test")
    formatter.Serialize(buffer, ex)

And if you want to see it not fail run this code:

    Dim buffer As New System.IO.MemoryStream
    Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    Dim ex As New System.Security.SecurityException("a test")
    formatter.Serialize(buffer, ex)

I've been doing a lot of work with the NDCS over the past several months. And this is the first time I've encountered a single case where NDCS didn't mirror the behavior of the BinaryFormatter - which is why I do think this is a WCF bug. Now just to get it acknowledged by someone at Microsoft so it can hopefully get fixed in the future...

The immediate issue I face is that I'm not entirely sure how to resolve this issue in the data portal. One (somewhat ugly) solution is to catch all exceptions (which I actually do anyway), and then scan the object graph that is about to be returned to the client to see if there's a SecurityException in the graph. If so perhaps I could manually invoke the BinaryFormatter and just return a byte array. The problem with that is in the case where the object graph is a mix of Serializable and DataContract objects - in which case the BinaryFormatter won't work because it doesn't understand DataContract...

In the end I may just have to leave it be, and people will need to be aware that they can never throw a SecurityException from the server...

Friday, June 01, 2007 11:34:14 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Sunday, February 04, 2007

It seems that people are always looking for The Next Big Thing™, which isn’t surprising. What I do find surprising is that they always assume that TNBT must somehow destroy the Previous Big Thing™, which in the field of software development was really object-orientation (at least for most people).

 

Over the past few years Web Services and then their reincarnation as SOA or just SO were going to eliminate the use of OO. As more and more people have actually implemented and consumed services I think it has become abundantly clear that SOA is merely a repackaging of EAI from the 90’s and EDI from before that. Useful, but hardly of the sweeping impact of OO, at least not in the near term.

 

Though to be fair, OO took more than 20 years before it became remotely “mainstream”, and even today only around 30% of developers (based on my informal, but broad, polling over the past couple years) apply OOD in their daily work. So you could question whether OO is “mainstream” even today, when the vast majority of developers use procedural programming techniques.

 

Even though the majority of .NET and Java developers don’t actually use OO themselves, both the .NET and Java platforms are OO throughout. So there’s no doubt that OO has had an incredible impact on our industry, and that it has shaped the major platforms and development styles used by almost everyone.

 

So perhaps in 15-20 years SO really will have the sweeping impact that OO has had on software development. And I’m not sure that would be a bad thing, but it isn’t a near-term concern.

 

However, I was recently confronted by a (so-called) newcomer: workflow. Yes, now workflow (WF) is going to kill OO, or so I’ve been told. In fact, Through indirect channels, my challenger suggested that the CSLA .NET framework is obsolete going forward because it is based on these “old-school” OO concepts.

 

Obviously I beg to differ :)

 

It is true that some of the concepts I employ in CSLA .NET are quite old, but I am not ready to through OO into the “old-school” bucket just yet... The idea is somewhat ironic however, because WF is being put up as The Next Big Thing™. Depressingly, there's virtually no technology today that isn't a rehash of something from 20 years ago. That's more true of SOA and WF than OO. Remember that SOA is just repacking of message-based architecture, only with XML, and workflow is an extension of procedural design and the use of flowcharts. At least OO can claim to be younger than either of those two root technologies.

 

Personally, I very much doubt the use of objects as rich behavioral entities will go away any time soon. Sure, for non-interactive tasks procedural technologies like WF might be better than OO (though that's debatable). And certainly for connecting disparate systems you need to use loosely coupled architectures, of which SOA is one (but not the only one).

 

But the question remains: how do you create rich, interactive GUI applications in a productive and yet maintainable manner?

 

Putting your logic in a workflow reduces interactivity. Putting your logic behind a set of services reduces both interactivity and performance. Putting your logic in the UI is "VB3 programming". So what's left? For interactive apps you need a business layer that can run as close to the user as possible and using business objects is a particularly good way to do exactly that.

 

Neither WF nor WCF/SOA are, to me, competitors to CSLA. Rather, I see them as entirely complimentary.

 

Perhaps ADO.NET EF and/or LINQ are competitors - that depends on what they look like as they stabilize over the next several months. Everything I’ve seen thus far leads me to believe these technologies are complimentary as well. (And Scott Guthrie agrees – check out his recent interview on DNR) Neither of them addresses the issues around support for data binding, or centralization of business logic in a formal business layer.

 

But when it comes to SOA I still think it is a “fad”. It is either MTS done over with XML - which is what 95% of the people out there are doing with "services", or it is EDI/EAI with XML - which is a good thing and a move forward, but which is too complex and has too much overhead for use in a typical application. I think that most likely in 5-10 years we'll have a new acronym for it – just adding to the EDI/EAI/SOA list.

 

Just like "outsourcing" became ASP which became SaaS. The idea doesn't die, it just gets renamed so more money can be made by selling the same stuff over again - often to people who really don't need/want it.

 

The point is, our industry is cyclical. And we're heading toward into a period where "procedural programming" is once again reaching a peak of usage. This time under the names SOA and workflow. But if you step back from the hype and look at it, what's proposed is that we create a bunch of standalone code blocks that exchange formatted data. A set of procedures that exchange parameters. Dress it up how you like, that's what is being proposed by both the SOA and WF crowds.

 

And there's nothing wrong with that. Procedural design is well understood.

 

And it could actually work this time around if we don't cheat. I still maintain that the reason procedural programming "failed" was because we cheated and used common blocks and global variables. Why? Because it was too inefficient and required too much code to formally package up all the data and send it as parameters.

 

If we can stomach the efficiency and coding costs this time around - packing the data into XML messages - then I see no reason why we can't make procedural programming work in many cases. And by naming it something trendy, like SOA and/or workflow, we can avoid the negative backlash that would almost certainly occur if people realized they were abandoning OO to return to procedural programming.

 

Having spent the first third of my career doing procedural programming, I wouldn't necessarily mind going back. In some ways it really was easier than using objects - though there are some very ugly traps that people will have to rediscover again on this go-round. Most notably the trap that a procedure can't be reused without introducing fragility into the system, not due to syntactic coupling or API changes, but due to semantic coupling (about which I've blogged).

 

This is true for procedures and any other "reusable" code block like a workflow activity or a service. They all suffer the same limitation - and it is one that neither WSDL nor compilers can help solve...

 

Anyway, kind of went on a rant here - but I find it amusing that, in some circles at least, OO is viewed as the "legacy" technology in the face of services or workflow, which are even more legacy than OO ;)

Sunday, February 04, 2007 1:03:57 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [13]  | 

 Monday, October 09, 2006

For better or worse, SOA (service-oriented architecture) continues to be the current industry fad. As SOA continues along the “hype curve” (a term I’m borrowing from Gartner), more and more people are starting to realize that SOA isn’t a silver bullet, and that it doesn’t actually replace n-tier client/server or object-orientation.

 

What will most likely happen over the next couple years, is that SOA will fall into the “pit of disillusionment” (part of the hype curve, that I think of as the “pit of despair”), and many people will decide, as a result, that it is totally useless. This will happen, not in small part, because some organizations are investing way too much money into SOA now, when it is overly hyped – and they’ll feel betrayed when “reality” sets in.

 

After a period of disrepute, SOA may then rise to a “plateau of productivity”, where it will finally be used to solve the problems it is actually good at solving.

 

Some technologies don’t live through the “despair” part of the process. Sometimes the harsh light of reality is too bright, and the technology can’t hold up. Other times, a competing technology or concept hits the top of its hype curve, derailing a previous technology. Over the next very few years, we’ll see if SOA holds up to the despair or not.

 

This is a pattern Gartner has observed for virtually all technologies over many, many years. If you think about any technology introduced over the past 20 years or more, almost all of them have following this pattern: over-hyping, over-reacting-to-reality and finally used-as-a-real-solution.

 

My colleague and mentor, David Chappell, recently blogged about some of the realities people are discovering as they actually move beyond the hype and try to apply SOA. It turns out, not surprisingly, that achieving real benefits in terms of reuse is much harder than the SOA evangelists would have anyone believe.

 

I think this is because SOA focuses on only one part of the problem: syntactic coupling. SOA, or at least service-oriented design and programming, is very much centered around rules for addressing and binding to services, and around clear definition of syntactic contracts for the API and message data sent to and from services.

 

And that’s all good! Minimizing coupling at the syntactic level is absolutely critical, and SOA has moved us forward in this space, picking up where EAI (enterprise application integration) left off in the 90’s.

 

Unfortunately, syntactic coupling is the easy part. Semantic coupling is the harder part of the problem, and SOA does little or nothing to address this challenging issue.

 

Semantic coupling refers to the behavioral dependencies between components or services. There’s actual meaning to the interaction between a consumer and a service.

 

Every service implements some tangible behavior. A consumer calls the service, thus becoming coupled to that service, at both a syntactic and semantic level. At the syntactic level, the consumer must use the address, binding and contract defined by the service – all of which are forms of coupling. But the consumer also expects some specific behavior from the service – which is a form of semantic coupling.

 

And this is where things get very complex. The broader the expected behavior, the tighter the coupling.

 

As an example, a service that does something trivial, like adding two numbers, is relatively easy to replace with an equivalent. Such a service can even be enhanced to support other numeric data types with virtually no chance of breaking existing consumers. So the semantic coupling between a consumer and such a service is relatively light.

 

Another example is credit card verification. Obviously the internal implementation of this behavior is much more complex, but the external expectations of behavior remain very limited. Like adding two numbers, verifying a credit card is a behavior that accepts very little data, and returns a very simple result (yes/no).

 

Contrast this with many other possible business services, such as shipping an order, or generating manufacturing documentation. In these (quite common) scenarios, the service performs, or is expected to perform, a relatively broad set of behaviors. The result is a whole group of effects and side-effects – all of which should be considered as black-box effects by any caller. But the more a service does, the less “black-box” it can be to its callers, and the tighter the coupling.

 

And this leaves us in a serious quandary. There’s a high cost to calling a service. There’s a lot of overhead to creating a message, serializing it into text (XML), routing it through some communications stack onto the wire, getting the electrons across the wire through some protocol (probably TCP) and all the attendant hardware involved, picking it up off the wire on the server, routing it through another communications stack, deserializing the text (XML) back into a meaningful message and finally interpreting the message. Only then can the service actually act on the message to do real work.

 

Worse, that’s only half the story, because most people are creating synchronous request/response services, and so that whole overhead cost must be paid again to get the result back to the caller!

 

Before going further, let me expand on this “overhead cost” concept to be more precise.

 

I worked for many years in manufacturing. In that industry there’s the concept of cost accounting – people make their living at tracking costs. They divide costs into overhead, setup and run (there are other models, but this one’s pretty standard).

 

To make this somewhat more clear, I’ll use the metaphor of baking cookies.

 

Overhead cost are all the salaried people, the buildings, equipment and so forth. Costs that are paid whether widgets are manufactured or not. When baking cookies, this is the cost of having a kitchen, a stove, electricity, natural gas, and of course the person doing the baking. In most homes these costs exist regardless of whether cookies are baked or not.

 

Setup costs are applied overhead. They are costs that are required to build a set of widgets, but they are only incurred when widgets are being manufactured. These costs include setting up machines, programming devices, getting organized, printing documents, etc. When baking cookies, this is the cost (in terms of time) of getting out the various ingredients, bowls, spoons and other implements. It is also the cost of cleaning up after the baking is done – all the washing, drying and putting-away-of-implements that follows. These costs are directly applied to the process, but are pretty much the same whether you bake one dozen or ten dozen cookies.

 

Run costs are those costs that are incurred on a per-widget basis to make a widget. This includes the hourly rate of the workers manning the assembly line, the materials that go into the widget and so forth. When baking cookies, this is the time spent by the baker, the cost of the flour, eggs and other ingredients consumed in the process. Ideally it would include the amount of electricity or natural gas used to run the stove as well. Obviously detailed run costs can be hard to determine in some cases!

 

When calculating the cost of your cookies, each of these three costs is added together. The run rate is easy, as it is per-cookie by definition. The setup rate is variable – the more cookies you make in a batch the lower the relative setup cost, and the fewer cookies the higher the relative setup cost. Overhead is typically aggregated – the annual overhead cost is known, and is divided by the number of cookies (and other things) made over a year’s time. Obviously there’s lots of wiggle room in this last number.

 

For my purposes, in discussing services, the overhead rate isn’t all that meaningful. In our industry this is the cost of the IT staff, the servers, the server room, electricity and cooling and so forth.

 

But the setup rate and run rate become very meaningful when talking about services.

 

Calling a service, as I noted earlier, incurs a lot of overhead. This overhead is relatively constant: you pay about the same whether you send 1 byte or 1024 bytes to or from the service.

 

The run rate is the actual work done by the service. Once the message is parsed and available to the service, then the service does real, valuable work. This is the run rate for the service.

 

In manufacturing it is always important to manage the overhead and setup costs – they are a “pure cost”. The run rate cost must also be managed, but it is directly applicable to a product, and so that cost can be factored into the price you charge. Perhaps more importantly, your competitors typically have a comparable run rate (materials and labor cost about the same), but the overhead can vary radically.

 

To switch industries just a bit, this is why Walmart does so well (and is so feared). They have managed their overhead and setup costs to such a degree that they actually do focus on reducing their run rate (in their case, the per-unit acquisition cost of items).

 

Coming back to services, we face the same issue. Typically we deal with this using intuition rather than thinking it through, but the core problem is very tangible.

 

Would you call a service to add two numbers? Of course not! The setup/overhead cost would outweigh the run cost to such a degree that this makes no sense at all.

 

Would you call a service to ship an order, with all the surrounding activities that implies? This makes much more sense. The setup/overhead cost becomes trivial when compared to the run cost for such a service.

 

And yet coupling has the opposite effect. Which of those services can be more loosely coupled? The addition service of course, because it performs a very narrow, discrete, composable behavior.

 

Do you even know what the ship-an-order service might do? Of course not, it is too big and vague. Will it trigger invoicing? Will it contact the customer? Will it print pick lists for inventory? Will it update the customer’s sales history?

 

I would hope it does all these things, but very few of us would be willing to blindly assume it does them. And so we are forced to treat ship-an-order as something other than a black box. At best it is gray, but probably downright clear. We’ll require that the service’s actual behaviors be documented. And then we’ll fill in the gaps for what it does not provide, or doesn’t provide in a way we like.

 

(Or, failing to get adequate documentation, we’ll experiment with the service, probing to find its effects and side-effects and limitations. And then we’ll fill in the gaps for the bits we don’t like. Sadly, this is the more common scenario…)

 

At this point we (the caller of the service) have become so coupled to the service, that any change to the service will almost certainly require a change to our code. And at this point we’ve lost the primary goal/benefit of SOA.

 

Why? How can this be, when we’re using all the blessed standards for SOA communication? Maybe we’re even using an Enterprise Service Bus, or Biztalk Server or whatever the latest cool technology might be. And yet this coupling occurs!

 

This is because I am describing semantic coupling. Yes, all the cool, whiz-bang SOA technologies help solve the syntactic coupling issues. But without a solution to the semantic, or behavioral, coupling it really doesn’t get us very far…

 

What’s even scarier, is that the vision of the future portrayed by the SOA evangelists is one where we build services (systems) that aggregate other services together to provide higher-level functionality. Like assembling simple blocks into more complex creations, that in turn can be assembled into more complex creations or used as-is.

 

Except that each level of aggregation creates a service that provides broader behaviors – and by extension tighter coupling to any callers (though the setup vs run costs become more and more favorable at the top level).

 

To bring this (rather long) post to a close, I want to return to the beginning. SOA is heading down the steep slope into the pit of disillusionment. You can head this off for yourself and your organization by realizing ahead of time, right now, that SOA only addresses syntactic issues. You must address the much harder semantic issues yourself.

 

And the tools exist. They have for a long time. Good procedural design, use of flow charts, data flow diagrams, control diagrams, state diagrams: these are all very valid tools that can help you manage the semantic coupling. Unfortunately the majority of people with expertise in these tools are nearing retirement (or have retired) – but the tools and techniques are there if you can find some old, dusty books on procedural design. Just remember to include the setup/overhead cost vs run cost in your decisions on whether to make each procedure into a "service".

 

SOA solves some serious and important issues, but it is overhyped. Fortunately the hype is fading, and so we can look forward (perhaps 18 or 36 months) to a time when we can, with any luck, start focusing on the “next big thing”. Maybe, just maybe, that “big thing” will be some new and interesting way of addressing semantic coupling.

Monday, October 09, 2006 5:07:08 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [14]  | 

 Monday, March 13, 2006

Somebody woke up on the wrong side of the bed, fortunately it wasn't me this time :)

This is a nice little rant about the limitations of OO-as-a-religion. I think you could substitute any of the following for OO and the core of the rant would remain quite valid:

  • procedural programming/design
  • modular programming/design
  • SOA/SO/service-orientation
  • Java
  • .NET

Every concept computer science has developed over the past many decades came into being to solve a problem. And for the most part each concept did address some or all of that problem. Procedures provided reuse. Modules provided encapsulation. Client/server provided scalability. And so on...

The thing is, that very few of these new concepts actually obsolete any previous concepts. For instance, OO doesn't elminate the value of procedural reuse. In fact, using the two in concert is typically the best of both worlds.

Similarly, SO is a case where a couple ideas ran into each other while riding bicycle. "You got messaging in my client/server!" "No! You got client/server in my messaging!" "Hey! This tastes pretty good!" SO is good stuff, but doesn't replace client/server, messaging, OO, procedural design or any of the previous concepts. It merely provides an interesting lense through which we can view these pre-existing concepts, and perhaps some new ways to apply them.

Anyway, I enjoyed the rant, even though I remain a staunch believer in the power of OO.

Monday, March 13, 2006 11:44:39 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Friday, August 05, 2005

Ted Neward believes that “distributed objects” are, and always have been, a bad idea, and John Cavnar-Johnson tends to agree with him.

 

I also agree. "Distributed objects" are bad.

 

Shocked? You shouldn’t be. The term “distributed objects” is most commonly used to refer to one particular type of n-tier implementation: the thin client model.

 

I discussed this model in a previous post, and you’ll note that I didn’t paint it in an overly favorable light. That’s because the model is a very poor one.

 

The idea of building a true object-oriented model on a server, where the objects never leave that server is absurd. The Presentation layer still needs all the data so it can be shown to the user and so the user can interact with it in some manner. This means that the “objects” in the middle must convert themselves into raw data for use by the Presentation layer.

 

And of course the Presentation layer needs to do something with the data. The ideal is that the Presentation layer has no logic at all, that it is just a pass-through between the user and the business objects. But the reality is that the Presentation layer ends up with some logic as well – if only to give the user a half-way decent experience. So the Presentation layer often needs to convert the raw data into some useful data structures or objects.

 

The end result with “distributed objects” is that there’s typically duplicated business logic (at least validation) between the Presentation and Business layers. The Presentation layer is also unnecessarily complicated by the need to put the data into some useful structure.

 

And the Business layer is complicated as well. Think about it. Your typical OO model includes a set of objects designed using OOD sitting on top of an ORM (object-relational mapping) layer. I typically call this the Data Access layer. That Data Access layer then interacts with the real Data layer.

 

But in a “distributed object” model, there’s the need to convert the objects’ data back into raw data – often quasi-relational or hierarchical – so it can be transferred efficiently to the Presentation layer. This is really a whole new logical layer very akin to the ORM layer, except that it maps between the Presentation layer’s data structures and the objects rather than between the Data layer’s structures and the objects.

 

What a mess!

 

Ted is absolutely right when he suggests that “distributed objects” should be discarded. If you are really stuck on having your business logic “centralized” on a server then service-orientation is a better approach. Using formalized message-based communication between the client application and your service-oriented (hence procedural, not object-oriented) server application is a better answer.

 

Note that the terminology changed radically! Now you are no longer building one application, but rather you are building at least two applications that happen to interact via messages. Your server doesn't pretend to be object-oriented, but rather is service-oriented - which is a code phrase for procedural programming. This is a totally different mindset from “distributed objects”, but it is far better.

 

Of course another model is to use mobile objects or mobile agents. This is the model promoted in my Business Objects books and enabled by CSLA .NET. In the mobile object model your Business layer exists on both the client machine (or web server) and application server. The objects physically move between the two machines – running on the client when user interaction is required and running on the application server to interact with the database.

 

The mobile object model allows you to continue to build a single application (rather than 2+ applications with SO), but overcomes the nasty limitations of the “distributed object” model.

Friday, August 05, 2005 9:12:29 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  | 

 Tuesday, May 24, 2005

It is clear to me that Service Oriented Architecture has gone about as far as it can go in a vacuum. And Service Oriented Programming continues to evolve somewhat randomly as vendors and/or standards bodies see fit (WSE, Indigo, etc).

 

So there needs to be more rigorous thought apply to Service Oriented Design. If we assume the SOA concepts of autonomous entities communicating via contract-defined messages over negotiated channels. And if we assume we’ll have programming tools that provide contractual synchronous and asynchronous communication vectors, then we can move ahead and work on thought models for designing services and systems composed of services.

 

Note that there are two very different aspects here. One is how to create a service, the other is now to build systems where services interact. The inside view and the outside view. And the rules and concepts are very different for each.

 

In that vein, here's a good/interesting article on SO design from Rich Turner at Microsoft. He’s taking the inside view and discussing some high-level design concepts for how you might build an autonomous service that still requires other services to function. He’s proposing a couple thought models that might be useful in design efforts – exactly the kind of dialog that is required to move SOD forward.

 

Personally I think that a number of the object-oriented design concepts behind CRC cards (class, responsibility, collaboration) apply equally well to services. In such a scheme, Rich’s relationships (constellation or fractal) would be listed as collaborators from a service.

 

I’m convinced that at least the first side of a CRC card, where the class (now service), responsibility and list of collaborators (other services) are a good design tool for services. Some of the other sides (like the list of behaviors) aren’t so useful, since a service is an atomic procedure and thus by definition has exactly one behavior. Still, applying those parts of CRC that do work is very helpful.

Tuesday, May 24, 2005 9:02:10 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [3]  | 

 Sunday, May 08, 2005
I try not to do too much simple link-fowarding, but this is a very good, clear article on SOA.
Sunday, May 08, 2005 6:45:51 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  | 

 Tuesday, May 03, 2005

Over the past few weeks I've given a number of presentations on service-oriented design and how it relates to both OO and n-tier models. One constant theme has been my recommendation that service methods use a request/response or just request method signature:

 

   response = f(request)

or

   f(request)

 

"request" and "response" are both messages, defined by a type or schema (with a little "s", not necessarily XSD).

 

The actual procedure, f, is then implemented as a Message Router, routing each call to an appropriate handler method depending on the specific type of the request message.

 

In concept this is an ideal model, as it helps address numerous issues around decoupling the client and service, and around versioning of a service over time. I discussed many of these issues in my article on SOA Covenants.

 

Of course the devil is in the details, or in this case the implementation. Today's web service technologies don't make it particularly easy to attach multiple schemas to a given parameter - which we must do to the "request" parameter in order to allow our single endpoint to accept multiple request messages.

 

One answer is to manually create the XSD and/or WSDL. Personally I find that answer impractical. Angle-brackets weren't meant for human creation or consumption, and programmers shouldn't have to see (much less type) things like XSD or WSDL.

 

Fortunately there's another answer. In this blog entry, Microsoft technology expert Bill Wagner shows how to implement "method overloading" in asmx using C# to do the heavy lifting.

 

While the outcome isn't totally seamless or perfect, it is pretty darn good. In my mind Bill's answer is a decent compromise between getting the functionality we need, and avoiding the manual creation of cryptic WSDL artifacts.

 

The end result is that it is totally possible to construct flexible, maintainable and broadly useful web services using VB.NET or C#. Web services that follow a purely message-based approach, implement a message router on the server and thus provide a good story for both versioning and multiple message format stories.

 

Indigo, btw, offers a similar solution to what Bill talks about. In the Indigo situation however, it appears that we’ll have more fine-grained control over the generation of the public schema through the use of the DataContract idea, combined with inheritance in our VB or C# code.

Tuesday, May 03, 2005 10:15:53 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [5]  | 

 Monday, April 18, 2005

Indigo is Microsoft’s code name for the technology that will bring together the functionality in today’s .NET Remoting, Enterprise Services, Web services (including WSE) and MSMQ. Of course knowing what it is doesn’t necessarily tell us whether it is cool, compelling and exciting … or rather boring.

 

Ultimately beauty is in the eye of the beholder. Certainly the Indigo team feels a great deal of pride in their work and they paint this as a very big and compelling technology.

 

Many technology experts I’ve talked to outside of Microsoft are less convinced that it is worth getting all excited.

 

Personally, I must confess that I find Indigo to be a bit frustrating. While it should provide some absolutely critical benefits, in my view it is merely laying the groundwork for the potential of something actually exciting to follow a few years later.

 

Why do I say this?

 

Well, consider what Indigo is again. It is a technology that brings together a set of existing technologies. It provides a unified API model on top of a bunch of concepts and tools we already have. To put it another way, it lets us do what we can already do, but in a slightly more standardized manner.

 

If you are a WSE user, Indigo will save you tons of code. But that’s because WSE is experimental stuff and isn’t refined to the degree Remoting, Enterprise Services or Web services are. If you are using any of those technologies, Indigo won’t save you much (if any) code – it will just subtly alter the way you do the things you already do.

 

Looking at it this way, it doesn’t sound all that compelling really does it?

 

But consider this. Today’s technologies are a mess. We have at least five different technologies for distributed communication (Remoting, ES, Web services, MSMQ and WSE). Each technology shines in different ways, so each is appropriate in different scenarios. This means that to be a competent .NET architect/designer you must know all five reasonably well. You need to know the strengths and weaknesses of each, and you must know how easy or hard they are to use and to potentially extend.

 

Worse, you can’t expect to easily switch between them. Several of these options are mutually exclusive.

 

But the final straw (in my mind) is this: the technology you pick locks you into a single architectural world-view. If you pick Web services or WSE you are accepting the SOA world view. Sure you can hack around that to do n-tier or client/server, but it is ugly and dangerous. Similarly, if you pick Enterprise Services you get a nice set of client/server functionality, but you lose a lot of flexibility. And so forth.

 

Since the architectural decisions are so directly and irrevocably tied to the technology, we can’t actually discuss architecture. We are limited to discussing our systems in terms of the technology itself, rather than the architectural concepts and goals we’re trying to achieve. And that is very sad.

 

By merging these technologies into a single API, Indigo may allow us to elevate the level of dialog. Rather than having inane debates between Web services and Remoting, we can have intelligent discussions about the pros and cons of n-tier vs SOA. We can apply rational thought as to how each distributed architecture concept applies to the various parts of our application.

 

We might even find that some parts of our application are n-tier, while others require SOA concepts. Due to the unified API, Indigo should allow us to actually do both where appropriate. Without irrational debates over protocol, since Indigo natively supports concepts for both n-tier and SOA.

 

Now this is compelling!

 

As compelling as it is to think that we can start having more intelligent and productive architectural discussions, that isn’t the whole of it. I am hopeful that Indigo represents the groundwork for greater things.

 

There are a lot of very hard problems to solve in distributed computing. Unfortunately our underlying communications protocols never seem to stay in place long enough for anyone to really address the more interesting problems. Instead, for many years now we’ve just watched as vendors reinvent the concept of remote procedure calls over and over again: RPC, IIOP, DCOM, RMI, Remoting, Web services, Indigo.

 

That is frustrating. It is frustrating because we never really move beyond RPC. While there’s no doubt that Indigo is much easier to use and more clear than any previous RPC scheme, it is also quite true that Indigo merely lets us do what we could already do.

 

What I’m hoping (perhaps foolishly) is that Indigo will be the end. That we’ll finally have an RPC technology that is stable and flexible enough that it won’t need to be replaced so rapidly. And being stable and flexible, it will allow the pursuit of solutions to the harder problems.

 

What are those problems? They are many, and they include semantic meaning of messages and data. They include distributed synchronization primitives and concepts. They include standardization and simplification of background processing – making it as easy and natural as synchronous processing is today. They include identity and security issues, management of long-running processes, simplification of compensating transactions and many other issues.

 

Maybe Indigo represents the platform on which solutions to these and other problems can finally be built. Perhaps in another 5 years we can look back and say that Indigo was the turning point that finally allowed us to really make distributed computing a first-class concept.

Monday, April 18, 2005 10:13:06 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [3]  | 

 Wednesday, February 23, 2005
Just a super-quick entry that I'll hopefully follow up on later. Ted wrote a bunch of stuff on contracts related to Indigo, etc.
 
I think this is all wrong-headed. The idea of being loosely coupled and the idea of being bound by a contract are in direct conflict with each other. If your service only accepts messages conforming to a strict contract (XSD, C#, VB or whatever) then it is impossible to be loosely coupled. Clients that can't conform to the contract can't play, and the service can never ever change the contract so it becomes locked in time.
 
Contract-based thinking was all the rage with COM, and look where it got us. Cool things like DoWork(), DoWork2(), DoWorkEx(), DoWorkEx2() and more.
 
Is this really the future of services? You gotta be kidding!
Wednesday, February 23, 2005 3:00:15 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [4]  | 

 Tuesday, February 08, 2005

I just finished watching Eric Rudder’s keynote on Indigo at VS Live in San Francisco. As with all keynotes, it had glitz and glamour and gave a high-level view of what Microsoft is thinking.

 

(for those who don’t know, Eric is the Microsoft VP in charge of developer-related stuff including Indigo)

 

Among the various things discussed was the migration roadmap from today’s communication technologies to Indigo. I thought it was instructive.

 

From asmx web services the proposed changes are minor. Just a couple lines of code change and away you go. Very nice.

 

From WSE to Indigo is harder, since you end up removing lots of WSE code and replacing it with an attribute or two. The end result is nice because your code is much shorter, but it is more work to migrate.

 

From Enterprise Services (COM+, ServicedComponent) the changes are minor – just a couple lines of changed code. But the semantic differences are substantial because you can now mark methods as transactional rather than the whole class. Very nice!

 

From System.Messaging (MSMQ) to Indigo the changes are comparable in scope to the WSE change. You remove lots of code and replace it with an attribute or two. Again the results are very nice because you save lots of code, but the migration involves some work.

 

From .NET Remoting to Indigo the changes are comparable to the asmx migration. Only a couple lines of code need to change and away you go. This does assume you listened to advice from people like Ingo Rammer, Richard Turner and myself and avoided creating custom sinks, custom formatters or custom channels. If you ignored all this good advice then you’ll get what you deserve I guess :-)

 

As Eric pointed out however, Indigo is designed for the loosely coupled web service/SOA mindset, not necessarily for the more tightly coupled n-tier client/server mindset. He suggested that many users of Remoting may not migrate to Indigo – directly implying that Remoting may remain the better n-tier client/server technology.

 

I doubt he is right. Regardless of what Indigo is designed for, it is clear to me that it offers substantial benefits to the n-tier client/server world. These benefits include security, reliable messaging, simplified 2-phase transactions and so forth. The fact that Indigo can be used for n-tier client/server even if it is a bit awkward or not really its target usage won’t stop people. And from today’s keynote I must say that it looks totally realistic to (mis)use Indigo for n-tier client/server work.

Tuesday, February 08, 2005 12:35:52 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [6]  | 

 Thursday, February 03, 2005

One last post on SOA from my coffee-buzzed, Chicago-traffic-addled mind.

 

Can a Service have Tiers?

 

Certainly a Service can have layers. Any good software will have layers. In the case of a Service these layers will likely be:

 

1.      Interface

2.      Business

3.      Data access

4.      Data management

 

This only makes sense. You’ll organize your message-parsing and XML handling code into the interface layer, which will invoke the business layer to do actual work. The business layer may invoke the Data access layer to get/save data into the Data management (database) layer.

 

But layers are logical constructs. They are just a way of organizing code so it is maintainable, readable and reusable. Layers say nothing about how the code is deployed – that is the realm of tiers.

 

So the question remains, can a Service be divided into tiers?

 

I’ll argue yes.

 

You deploy layers onto different tiers in an effort to get a good trade-off between performance, scalability, fault-tolerance and security. More tiers mean worse performance, but may result in better scalability or security.

 

If I create a service, I may very well need to deploy it such that I can provide high levels of scalability or security. To do this, I may need to deploy some of my service’s layers onto different tiers.

 

This is no different – absolutely no different – than what we do with web applications. This shouldn’t be a surprise, since a web service is nothing more than a web application that spits out XML instead of HTML. It