If you are a software engineer: DON'T PANIC! This blog is my place to beam thoughts on the universe of Artificial Intelligence and Software Architecture right to your screen. On my infinite mission to boldly go where (almost) no one has gone before I will provide in-depth coverage of architectural and AI topics, personal opinions, humor, philosophical discussions, interesting news and technology evaluations. (c) Prof. Dr. Michael Stal
Tuesday, June 27, 2006
Aspects r' us
A valid question in this context always is: should one use AspectJ as a kind of DSL in addition to a programming language such as Java or is it better to apply generative techniques such as MDSD to generate the solution from a DSL? Challenge: the runtime aspects of AspectJ have no counterpart in generative approaches. A possible approach then would be to use integrated DSLs to provide different views in a multi-dimensional approach. For example one DSL for the domain, one for security, one for fault-tolerance. From these descriptions a MDSD generator would then generate Java and AspectJ code. This would make aspects an implementation issue.
No matter how we view it, we always have to cope with multiple dimensions. Unfortunately, as already stated, the number of dimensions is proportional to the complexity of the problem space. Inherent complexity can not be removed (in contrast to accidental complexity). The implication therefore is: either the complexity arises at the OO level or in the architecture or in the DSLs and their combination as well as in the use of these DSLs. Thus, we have to deal with this complexity. Until now no one ever came up with a really complete and consistent solution. Actually, that is exactly the reason why it is so difficult to meet operational and developmental qualities in a software architecture. It is a question of complexity.
From my current viewpoint a combination of domain modeling, AOSD and MDSD seems to promising. But maybe, sometime in the future, someone can come up with the grand unified theory of software engineering.
My conclusion: even if you don't program aspect-oriented and even if you don't use aspects, you will have to deal with them anyway. Thus, tools such as AspectJ are important as thought-provoking mindset.
I am curious about your opinion!
Saturday, June 24, 2006
Variabilities
Development time: The target address could be hard coded into the client code. Compile/Link time: The target address is separated into a different file which is compiled and linked to the component (e.g. a proxy generated using WSDL).
Deployment time: The target address is specified by a configuration file which the container parses. It then passes the target address to the component (or a proxy) using dependency injection upon instantiation of the component.
Maintenance time/Runtime: The proxy which the component used to access the remote object is implemented as a DLL or shared library. This DLL might be exchanged at runtime by the container either using hot deployment at runtime or when the operation of the applications is paused for maintenance.
Patterns such as Decorator, Proxy, Interceptor or Strategy are helpful to deal with these variablities. Programming languages also offer great support for variabilites when they provide concepts such as interfaces, polymorphism, generic types. It is important to mention that each of these different binding times of a variability reveals different implications. For example, runtime binding is very flexible but might lead to performance penalties. In other words, the more loose coupling is introduced between the implementation of a variability and the application, the more flexible the application might be, but also the more resource consumption might be involved.
Another important point in this context consists of the fact that variabilities might be dependent on other variabilities which can be described using feature modelling. For example, if we use remote object RO1 then we also need to access RO2. Thus, the binding time and order need to be determined in advance. But that is a topic for a future posting.
Thursday, June 22, 2006
The Arrival of Language Integrated DSLs
Saturday, June 17, 2006
Lisp again!
There he addresses how developers can learn Lisp. I like this posting because in recent research projects I've made the personal observation that people tend to constantly reinvent the wheel. A good example are developers that grew up with Java or C++ or C#. They are often astonished with new and cool language capabilities such as closures (Ruby), or lambda-expressions (LINQ). Why am I talking about this issue? The good ole languages such as Lisp, Prolog invented several of the features that are so exciting. For example, model-checking in model-baased software development is a good example where Prolog turns out to be a clear winner. And Lisp simply is the singularity where the big bang of dynamic languages originated. Knowing these languages is absolutely valuable. Know the idioms of these languages and you will benefit in your daily developer life. Eric Meijer said recently on a conference: "you should learn a new language each year". That's the right strategy :-)
Complexity and Software Architecture
At university we have learned that the complexity of algorithms is measured by the amount of "processing time" it takes to solve a given problem depending on the number of input values, e.g.:
- O(c) means that to solve a specific problem always needs the same time independent of the input. Example: a constant function that always returns 42.
- O(N) means that the processing time reveals liner increase with the input dimensions.
- O(log N): time for searching an element in a sorted field.
- O(N log N): time to sort an unsorted field of N values.
We know that if we can map a given problem in constant time to let's say a sorting problem, and vice versa, then the problem will also have O(N log N) complexity. However, this kind of complexity is not that significant for software architecture design, is it? At least, we start to assume that there might be differend kinds of complexity.
In the old latin language complexity was defined as the total set of possibilities and capabilities. Thus, we can draw the conclusion that a software architecture is complex if it reveals a large set of properties and capabilities.
An appropriate way to get a gut feeling for software architecture complexity is to ask the following question: What are typical implications when a software architecture IS complex?
Static Structure:
- The architecture consists of a whole ocean of entities with lots of different relationships
- It typically comprises insufficient or confusing abstractions
- There is no clear separation of concerns. For instance, some entities are overloaded with various unrelated responsibilities, a point that is is often tightly related to the previous issue
Dynamics:
- There are lot of possible workflows
- The system contains many states and transitions
As you surely know the old saying is that software architecture and organization are only two sides of the same coin. Complexity of architecture may thus be caused by your organization:
- No clear team responsibilities and role assignments
- Insufficient or missing process
- High level of political issues in daily work
- Documentation-addiction
- Missing doucumentation
- Insufficient amount of time dedicated to architecture design
- No supervision of architecture realization
- Lack of adequate testing
- No sufficient team education upfront
In summary, complexity in software architecture is mainly caused by missing or overused abstractions and inadequate separation of concerns in either static structure or dynamics. Or in other words, the RUP 4+1 view helps us to structure complexity in different (4+1) areas. In addition, inadequate processes, tools, education, and organizational issues inevitably cause software architecture complexity.
Good means to prevent complexity are manifold:
- software patterns
- usage of frameworks and containers
- aspect-oriented programming if done right
- model-based software development if done right
- higher abstraction by introducing domains specific languages and domain modelling
- metrics if applied right
- usage of appropriate methods and tools
- requirements traceability
- ...
All of these means help to obtain appropriate abstractions, and mapping of responsibilities to entities. Note, that humans are normally only capable of processing 8 entities at the same time. Hence, this point should be taken into account on each abstraction layer and for each architectural perspective.
But that's only my 2c.
I am wondering what your opinions are w.r.t. complexity? Any complexity definition that makes sense?
Saturday, June 10, 2006
Michael's Pattern Laws
Here are some laws I found in the last years as a software architect I'd like to share of you. Maybe, you could share your own insights.
- Patterns are no surrogate for human intuition and creativity.
- Overload of patterns in your software architecture implies overload of problems in your system. However, not using patterns where applicable may make your life extremely unpleasant.
- If you just found that cool new pattern, think again before bothering the rest of us! (Remark: I also want to remind you of Brian Foote's famous words: " a pattern is an aggressive disregard of originality").
- Patterns are your best friends if they are treated with friendliness in your architecture design.
- It is easy to become a pattern author but it is surprisingly hard to write a good pattern description.
- If grandma understands it, it is propably a good pattern description.
- Patterns that can be easily formalized are no patterns.
- Patterns and Agility? Patterns are about agility. Without patterns your software architecture tends to become overly complex and thus hard to maintain, change, or evolve.
- The number of pattern books has significantly increased in the last years but that is not necesssarily a sign of good quality.
- Patterns are dead, CORBA is dead. All technologies that turn from hype to pragmatic technologies are declared dead once upon a time. If a technology is considered that way, it is typically safe and valuable to use.
- A pattern is no island. It reveals its true power when connected with other patterns to form complete landscapes.
- You can classify patterns in infinite ways. For example in structural, behavioral or creational patterns such as GoF. Or you may partition the pattern space with respect to granularity, process phases or domain facets. I prefer to have only two classes of patterns, good ones and bad ones.
- Time is money. Applying patterns saves time. Thus, patterns are money! Don't forget to tell that your managers.
- Always add a real life example to your pattern descriptions because some non-software people in your projects won't see the value of patterns otherwise. Take management as an example.
- If you are a good guy, apply patterns. If not, anti-patterns might be a more appropriate choice.
- Patterns are not just collections of UML diagrams. I totally agree with Bertrand Meyer who once said "bubbles don't crash" and "all you need is code". Developers should memorize those sentences.
- Applying the right patterns the right way is like paradise. Applying the wrong patterns or applying the right patterns wrongly, however, is like hell. Thus, make sure you know what you are doing here.
- Sure, you got all pattern books. But that doesn't make you a pattern expert automatically.
- As the pointy-haired boss always ephasizes in Dilbert "work smarter not harder". Applying patterns is generally considered smart.
- Beware of Murphy's Laws when applying patterns.
Friday, May 26, 2006
Agility and the Borgs
Saturday, May 06, 2006
The Problem with Metrics
Wednesday, May 03, 2006
What is Software Architecture
Thursday, April 27, 2006
Events
http://www.expo-c.se
Wednesday, April 26, 2006
Send all Market Analysts to a lonely Island!
Thursday, April 06, 2006
SOA is NOT about Web Services
- XML Web services define a kind of meta middleware dedicated to integration problems. If you need to communicate between a Java EE application and a .NET application then XML Web services represent one possible option. There are other alternatives in this scenario such as CORBA or RMI adapters. However, in most situations when you have to cope with heterogeneous systems without control which applications will have to be integrated, then XML Web services are the clear choice.
- Service-Oriented Architecture as the name implies is not dependent on a specific implementation technology such as XML Web services. Likewise, Object-Oriented Programming is not dependent on Java. Instead, I consider SOA as a set of architectural principles that emphasize loose coupling. I will explain this point in the remainder of this posting.
A typical example for a SOA-compliant technology is regular e-mail. I'd like to present some of the properties of SOA systems using this simple show case.
SOA requires explicit, role-based interfaces for services. Clients do only see interfaces and never implementations. As the bridge pattern is applied, client and server interfaces are implementation-agnostic with respect to each other. Communication between client and interface is provided by standardized protocols.
Applied to e-mail: Mail clients communicate with mail servers using POP3, IMAP or SMTP. As there are no implementation dependencies, a mail client does not need to care about the implementation of the mail server, and vice versa. Thus, you are completely free to use any mail client and mail server if your communication peers abide to the standard protocols and standard interfaces. e-mail is a little bit special in that the services and their semantics are predefined.
SOA communication relies on asynchronous message exchange albeit there might be transparency layers on top providing remote method invocation based communication. Messages are in general dynamically routed, possibly passing through indirection layers.
Applied to e-mail: mails are passed as messages from their origin (client's outbox) to their destination (recipient's inbox) passing different intermediate layers. That means for example that you are not blocked even if your communication peer hasn't yet received your mail.
SOA messages denote standardized documents with different sections such as body or headers. Multiple messages may be used to transmit data in chunks, if necessary. The header usually contains data related to cross-cutting concerns such as routing, attachments, security. The body content may be predefined between the communicating peers or be totally applications-specific.
Applied to e-mail: mails are sent using mail header and mail body. All content must comply with MIME types. That is the only constraint but is not really a constraint in fact.
SOA message exchange patterns relate different messages with each other to introduce additional communication styles such as request/response or oneway. Another example is the return of fault messages upon error situations.
Applied to e-mail: requiring a receiver to send an acknowledgement is the typical example. And what about failure scenarios? When a receiver is not recognized an error message is returned to the sender.
In SOA systems business processes are first class entities. Business processes introduce domain specific languages to combine distributed services to whole workflows. Note that business processes are not just sequential invocations of services. Instead, properties might be applied to complete workflows such as transaction contexts or other kinds of coordination.
Applied to e-mail: this is not directly supported. Instead, such workflows are implemented by applications or human interaction.
This concludes my discussion on e-mail as a SOA implementation example. Another example for a SOA based implementation technology is Messaging middleware such as MSMQ or MQSeries.
Loose coupling is the central mantra of all SOA architecture principles. Don't let vendors or press media fool you. SOA is NOT about XML Web services. Instead, it denotes an architectural paradigm for distributed computing that can be implemented using different technology options. Does it solve all problems? Ideally, it is applicable to all problem domains with inherent loose coupling of distributed entities. But it is counterproductive to apply the SOA paradigm in problem contexts where tight coupling is mandatory such as in several embedded or realtime systems. One could argue that in the end every distribution middleware relies in its bottom layers on SOA based communication such as TCP/IP. But that argument resembles the argumentation that we could implement all our software systems using machine code.
Bottom line: Always use the abstraction layer that helps building your system effectively and efficiently. Don't accept software development projects to be influenced by inadequate personal technology preferences or political decisions.
Saturday, April 01, 2006
Architect's Book Corner
General books on software architecture:
- Software Architecture in Practice ( http://tinyurl.com/qm2dl ) by Bass, Clements, Kazman introduces software architecture and also reveals in-depth perspectives. A must-read if you ask me.
- Beyond Software Architecture: Creating and Sustaining Winning Solutions (http://tinyurl.com/r3ls5 ) by Luke Hohmann does not focus on software architecture technology but also on related issues that influence software architecture.
- Product-Line Engineering has become an important topic for software engineers: Jan Bosch is my personal guru on this subject: Design and Use of Software Architectures (http://tinyurl.com/mffo8 ).
Patterns
- Design Patterns: Elements of Reusable Object-Oriented Software (http://tinyurl.com/nq8yq ) is the seminal book on design patterns by Gamma, Helm, Johnson, Vlissides. For me the content of the book comprised mandatory knowledge for every software architect.
- Our own POSA series extended the GoF book by architecture patterns, added a new documentation form, and also covered software architecture in more detail. Volume 1 (http://tinyurl.com/qk87n ) focuses on general patterns. One comment: I don't like when people call volume 1 the Buschmann book as all authors were contributing equally. The order of author names is structured lexicographically. For instance, I wrote more patterns than anyone else. Thus, call it the POSA 1 book to respect the "et al" in "Buschmann et al" :-). Volume 2 (http://tinyurl.com/rge3o ) concentrates on patterns for concurrent and networked systems. Volume 3 (http://tinyurl.com/qcvgv ) covers resource management. Expect more to come in the near future.
- In Remoting patterns (http://tinyurl.com/prnnz ) and Server Component Patterns (http://tinyurl.com/q9a52 ) you'll find some basic ingredients for remoting middleware and application servers.
- For messaging middleware the book you should read is Enterprise Integration Patterns : Designing, Building, and Deploying Messaging Solutions. By Gregor Hohpe and Bobby Woolfe. (http://tinyurl.com/q2xea ).
- Analysis patterns are more on the domain-level. Another excellent book by Martin Fowler (http://tinyurl.com/m2nfm ).
- For Java EE developers the Core J2EE Patterns book provides essential best ptactices for daily work (http://tinyurl.com/mvtbn ).
- .NET programmers can obtain similar books through http://tinyurl.com/rfyw9 .
- As soon as Markus' book on MDSD is available in english I can wholeheartedly recommend to read it (as I've read the german edition): http://tinyurl.com/q9a52 .
- Software factories extend MDSD by mapping industrial production paradigms to software engineering. Written by some prominent people such as Jack Greenfield the book on software factories is excellent: http://tinyurl.com/ntec6 .
- Generative Programming: Methods, Tools, and Applications was written by Uli Eisenecker and Krzysztof Czarnecki, two friends of mine. Excellent book on generative programming but contains very complex C++-based stuff (http://tinyurl.com/obxqn ).
- In Aspect-Oriented Analysis and Design AOP is considered from a more architectural approach (http://tinyurl.com/o3o2v ).
Process-related issues are important for a software architect. Here are some books on my list:
- Martin Fowler wrote THE book on refactoring which was entitled Refactoring: Improving the Design of Existing Code (http://tinyurl.com/r6s5z )
- An new one is Joshua Kerievsky's Refactoring to Patterns which introduces pattern-based refactoring (http://tinyurl.com/qam9h ).
- Test-Driven Development was introduced by Kent Beck whom all of you might know as the "father" of eXtreme Programming (http://tinyurl.com/ot8k3 ).
Modelling and Engineering Process:
- UML 2.0 in a Nutshell is compact and nonetheless offers a complete overview.(http://tinyurl.com/pasyk ).
- You need a lightweight overview of the Unified Process. Here is the way to go (http://tinyurl.com/q7xul ).
- Extreme Programming Explained : Embrace Change (2nd Edition) by Kent Beck is the source for learning eXtreme Programming (http://tinyurl.com/rwcmn ).
- Ken Schwaber and Mike Beedle in Agile Software Development with SCRUM tell you all to know about SCRUM (http://tinyurl.com/o7cer ).
- Agile development in general was perfectly described by Alistair Cockburn in Agile Software Development (http://tinyurl.com/raghe ).
- Requirements Engineering is often treated with unsufficient care. Thus, read the book Requirements Engineering (http://tinyurl.com/qeald ).
- The bible of writing good use cases? No question. This is definitely Alistair Cockburn's Writing Effective Use Cases (http://tinyurl.com/m5tq2 ).
- CMMI is widely desribed and explained in CMMI : Guidelines for Process Integration and Product Improvement (http://tinyurl.com/p9xsm ).
Domain Driven Design could also be placed into the category of pattern books. I think, it should stand alone as it introduces the new idea of domain languages in an outstanding way
OO and more
- The magic of components. Clemens wrote the seminal book on this topic. Some years old but still worth reading: Component Software: Beyond Object-Oriented Programming (http://tinyurl.com/pyo4u ).
- Effective Java by Joshua Bloch is also a good lecture for C# gurus: http://tinyurl.com/pyo4u .
- One of my favorites on Concurrent Programming: Doug Lea's Concurrent Programming in Java(TM): Design Principles and Patterns (http://tinyurl.com/ok4nd ) .
- On Service-Oriebted Software Architecture there are no really ubiquitous books. Read my articles on this subject (http://www.stal.de). As an intro I recommend Thomas Erl: Service-Oriented Architecture : A Field Guide to Integrating XML and Web Services (http://tinyurl.com/n5oxw ).
- Interested in all these lightweight containers? Read the book by the fathers of Spring, Expert One-on-One J2EE Development without EJB (http://tinyurl.com/lrvne ).
- They have published widely accepted books on Ruby and Programming. But all their other books are also worth reading. The Pragmatic Programmers is a source for excellent and pragmatic books: http://www.pragmaticprogrammer.com/.
Miscellaneous
- Last but not least. It should be mandatory for computer science students to read authors like: Scott Adams (Dilbert), Douglas Adams (Hitchhiker's Guide to the Galaxy), Tom Demarco, and Terry Pratchett (Discworld). Not to forget Stanislaw Lem who recently died. I also consider Star Trek as a foundation which implies you should also read the literature on physics (such as Feynman). But let me stop here :-)
All these books are books I've read in the last years. I recommend them personally. No, I won't get any fees from the publishers or authors. If you like to add some of your personal favorites, please, do so using the possibility to write comments.
Friday, March 31, 2006
What should be in an Architecture Document?
- Introduce special documents on the domain model (if applicable), on central issues such as patterns used, and on different kinds of guidelines. Make sure all architecture documents comply with these guidelines.
- Don't extend 50 pages per document. A large document with more pages will not be read by anyone, at least not all its content.
- This is a no-brainer. But nonetheless, I am going to mention it: Use a standard document template.
- Structure all documents exactly the same way. Otherwise, readers won't feel comfortable, especially when they have to read more than one architecture document.
- Describe the software architecture top-down. Start with the basic abstractions and then step by step move to more concrete details and implementation issues. This way, different readers can read the document according to the detail level they need. For instance, a manager might only be interested in the coarse grained architecture while engineers are also interested in deployment issues. A good way is to use the 4+1 view of the IBM Rational Unified Process. In the beginning, explain what part of the architecture you are actually describing in the document including its motivation and scope. Then address all requirements that have influenced your architecture (decisions) as well as the relevant use cases that drive the architecture design. A context diagram helps to show boundaries of your architecture as well as its integration into the rest of the system. Introduce the logical view with CRC cards, class diagrams, sequence diagrams. Don't come up with technology-centric issues too early. Even if you are using .NET Remoting and C# and SQL Server in your project, to name an example, your architecture baseline should not depend on these technologies, at least not its logical structure. Complete documentation using step-by-step refinement up to the deployment view.
- To ensure symmetry, always use the same diagrams for the same purpose such as UML diagrams, ER diagrams, or domain-specific languages (DSLs). Also make sure, that these diagrams use the same meta-model. For example, introduce project- or domain-specific stereotypes in a separate document (see first bullet).
- Add a glossary that explains all relevant terms and abbreviations. And make sure, all documents use the same terms with the same meanings.
- Add references to other documents that are relevant for reader understanding.
- Motivate all important design decisions that are not obvious. I've read so many documents that introduce architecture without presenting the rationale. Another software architect that reads your document must be able to understand the rationale (the "why" not just the "what"). Understanding the rationale also means understanding the architecture.
- For the same reason, always explain in your document how your architecture addresses the requirements. Thus, requirement traceability will be possible.
- Use patterns and explain the patterns used in the architecture document without providing full pattern descriptions. Rather refer to existing pattern descriptions in literature or special pattern documents.
- Structure the architecture documents in a tree-like hierarchy. The root is defined by the overall strategic architecture document that introduces the whole system. In the root document introduce all relevant subsystems as well as cross-cutting concerns such as security, scalability.
- The nodes right under the root then denote subsystem documents and further documents that address the most important cross-cutting concerns. If your subsystems consist of large entities themselves you may add additional leafs to the document hierarchy.
- Also specify testability (such as unit tests) in your document. This defines the specification of your architecture as well as how its implementation can be tested.
- Check-in all your documents in a configuration management system. Use versioning for your documents.
- Write the lead author or all co-authors onto the document cover page, so that a reader might track down the authors. Also specify date and version.
- Let other people review your document (and design). Feedback should be related to comprehensibility and technical soundness. Don't rely on the colleagues that are in the same subteam but also ask other people (managers, architects, testers) to read and review your documentation.
- A more process-related issue: make sure your architecture document always reflects the current state of the implementation (if already available). Otherwise, reading your document might be a complete waste of time and even cause other teams to draw wrong conclusions.
- Add diagrams and figures to explain your design, especially for complex architectural issues. No one will be capable of understanding hundreds of lines without any visualization. Drawing diagrams requires additional efforts but is always worth the time being spent.
These are some recommendations I have derived from my work as software architect. I am sure there is even more. If you find this helpful or if you have additional suggestions or feedback don't hesitate to add your comment.
Thursday, March 30, 2006
Middleware - what Middleware?
Basically, the following kinds of middleware exist:
- Messaging Middleware: applications send messages to each other. Message contents are application-specific while the structure and header information is specified by the MOM (Message-Oriented Middleware). Messages might be sent from one peer to exactly one other peer (end-to-end or queue-based messaging) or (anonymously) from multiple publishers to multiple subscribers (publisher subscriber or topic-based messaging). Examples: MSMQ, MQSeries, JMS, SonicMQ, JBossMQ.
- Remoting Middleware: hides all communication details from developers by extending conventional operation calls over the network. Clients and servers can almost be implemented as if they were residing in the same address space. All communication issues are handled behind the scenes by glue components that are typically generated using tools. Examples: RMI, WCF aka Indigo, CORBA, ICE, DCOM.
- Eventing Middleware: focuses on distributing fine grained events. Very similar to messaging middleware and thus I won't cover it here in detail.
- Distributed Transaction Monitors: provide transactions management across different components. Examples: Tuxedo, CICS, MTS. Will not be covered in this posting as transaction monitors today are rather integrated into the other types of middleware.
- Service-oriented Middleware is a kind of meta-middleware used to integrate other middleware. Most prominent implementation are XML Web services. Web services are mostly useful in business-level integration scenarios.
- Peer-to-Peer Middleware: a combination of Messaging middleware and Eventing middleware where the locating of remote peers happens through discovery algorithms instead of relying on centralized repositories.
- I won't explain Multi-Agent-Systems here as they are only used rarely.
- Neither I will explain EAI systems here as they are basically built on top of the aforementioned middleware types.
Therefore, the first distinction should be whether your problem domain requires a more method-invocation based or more message-based approach. Asynchronous operation is one of the important issues here. Despite of the fact that some remoting middleware technologies have also introduced asynchronous method invocations (e.g., CORBA), messaging is more appropriate for asynchronous communication. Asynchronous communication basically means, that the sender for its subsequent processing does either not expect a result from its communication peer or does not need the result now. Hence, senders and receivers should be decoupled. Example: sending a purchase order to the order processing subsystem. Another issue for the preferred usage of messaging is when you don't want tight coupling between communication partners. For example, a server that is sending notifications to different receivers which are interested to subscribe for obtaining different messages from different senders. A further example is the provisioning of advanced communication styles such as broadcasting or single request - multiple replies. These styles do not map to existing programming languages, anyway. Thus, it makes no sense to provide them through remoting middleware. Last but not least, scenarios where communication links are not reliable are more appropriate for messaging. Take a mobile phone as an example that lost connection with the network.
If, however, the sender needs an "immediate" result from a specific communication partner, remoting is much more suitable. Example: asking a credit card company for validation of a specific card in a Point-of-Sale system. The advantage of remoting middleware is the transparency they provide. Basically, developers can ignore all communication details. But that is exactly the problem. Developers often tend to leverage remoting middleware as if they were developing non-distributed systems without taking issues such as latency into account. You can easily imagine the performance of such systems. Another problem with transparency is hiding of details can be a disadvantage in terms of tracking errors. Because everything is hidden, error causes also are hidden. In summary, usage of remoting middleware and transparency are totally overestimated in practice.
Messaging middleware can be extended to provide remoting. There is a simple reason for this. Every remote invocation can be separated into two message transfers. A request message is transferred to a receiver which then sends back a result message to the originator. Actually, all remoting middleware is built upon some kind of messaging infrastructure. In contrast to some claims, the opposite is not true as asynchrony can not be guaranteed when remoting middleware is used as the underlying base for a messaging layer.
Peer-to-Peer middleware simply combines messaging and eventing with discovery strategies. Instead of looking up a receiver's location from a known repository, it is much more reliable to discover a resource, especially when the same resource is available more than once in the network. In a Peer-to-Peer system a consumer or sender does not care about which concrete provider or receiver it is using. Thus, Peer-to-Peer approaches are particularly helpful for coping with decentralization. In theory, a similar approach is possible for remoting middleware. Instead of asking a repository where the server object is located, it is possible to use a trading service, ask for a specific service type with specific properties, and get possibly multiple object references returned that meet the specified type and property constraints. This is the right way if you need a remoting based approach combined with decentralized lookup strategies.
SOA basically means loose coupling. For example, peers are implementation-agnostic. The only thing an application sees is the service interface of the application it need to communicate with. The communication itself uses a commonly agreed messaging protocol. This approach can be best implemented using XML Web services and Messaging middleware. SOA is particularly useful to integrate different middleware and application islands with each other.
This posting could only scratch on the surface. There are a lot of issues that could have been discussed such as error handling, fault-tolerance, scalability, security. My intention was to illustrate that no middleware paradigm can be a general solution for all problems. Thus, it turns out to be essential to first specify the problem space and then identify which middleware solution is the appropriate one. For the same reason, it is sometimes not possible to rely on one single middleware technology because there are multiple problems requiring multiple middleware solutions. Remember: select your middleware carefully and base this selection only on the problem domain, not on political or personal preferences.
Making Noise
What does that mean for our life as software engineers? How can we survive our daily professional work without being flooded by information overkill? Getting completely rid of e-mail? Sounds nice to some people but is completely infeasible. The only way is to organize e-mail, filter them, prioritize them, and come up with netiquettes in project teams to use e-mail efficiently in order to reduce noise and make everyone feel comfortable and productive.
to be continued ...
Wednesday, March 29, 2006
Meeting Syndrome
Why is this relevant for software engineers? We as software architects spend most of the time communicating. It is essential that most of this time is dedicated to personal communication than with meetings.
To sum up: Meetings are important, but in order to stay productive meeting culture should focus on quality and efficiency instead of quantity. Meetings by themselves have no particular value. It is the human interaction that counts.
Tuesday, March 28, 2006
Gödel and Computer Science
Monday, March 27, 2006
Software Architect Part II
I'd like to introduce another perspective to shed more light on my points. What exactly are the typical activities of a software architect? Note: no guarantee for completeness given here.
From my viewpoint being an architect implies a really big workload. Architects need to:
- help clarifying the business case and support SWOT analysis if required
- help estimating required costs, resources, persons
- help providing a domain language and a DSL (optional)
- clarify all use cases and requirements as well as other open issues
- build an interface between developers, testers, and other stakeholders
- estimate iterations and increments
- assess at least the most critical technology options
- make sure the right tooling and technology portfolio is used within the project
- communicate with system architects to gurantee proper interaction between infrastructure and software architecture
- commit Commonality/Variability analysis when a Product Line Engineering approach is taken
- develop and document an architecture vision that already contains strategic decisions. Note: this also implies that architects must decide whenever there are different options! Software architecture is not an automated, deterministic process without any degrees of freedom
- help defining architectural guidelines for central issues such as error management
- empower other developers and architects with respect to all architecture aspects and architecture concepts
- take responsibility for all decisions and support partitioning and distributing tasks
- design all structures and behaviors so that they meet requirements
- supervise refinement and implementation of the architecture
- support quality assurance for all parts implemented by distributed teams and integrated into the product. Note: outsourcing and offshoring can be considered just special cases here. I am not considering any cultural, or legal issues in this context
- prove the feasability of a whole software architecture, of its parts, or aspects being leveraged by prototyping
- review software architectures and re-engineer them if necessary
- take test results and feedback as input for refactoring activities
- communicate with key developers to make sure the tactical design does not violate the strategic architecture
- simplify and refactor for injecting properties such as readability, extensibility
- implement (but not on critical paths)
- make sure re-usable assets are integrated
- meet with customers to obtain feedback also during the project
All these points may be uncritical for small projects that use proven technology. This might imply that architects don't need that kind of high profile. Take a one-person project as the most extreme example. As soon as large projects and high risks are involved it is inevitable to make sure, architects can really handle all the aforementioned issues and cope with them. Hope, you can now see from this activity list, how all these required experiences and expertise were derived in my former posting.
And I definitely appreciate additional feedback and comments
Sunday, March 26, 2006
Patterns and the Real Life
Let me give an example. The Half-Sync/Half-Async pattern in POSA 2 deals with systems where asynchronous events are expected to trigger synchronous event processing in distributed systems. To separate both a queue is introduced by the pattern. This is exactly what will happen in a Burger restaurant. New customers will arrive and place their orders to an employee at the counter. This employee won't wait until all food items are ready but will tell some workers in the background to prepare the order, while taking the next order. This way, parallelism and thus efficiency is increasing. If these orders are processed in parallel, then their completion time is non-deterministic. How will the personal know which order is associated with which customer? This is where the ACT pattern is the only viable solution. ACT stands for Asynchronous Completion Token. Its solution structure is very simple: whenever an asynchronous operation is started, the operation is associated with a unique token either created by the requester or by the request processor. When the operation completes, the result is returned back together with the token. This way, the request and result can be easily associated with each other. In a Burger restaurant you'll get a number. As soon as your order is ready, someone will shout your number and you'll be able to pick up your food.
Needless to say that the same strategy works for Starbucks or beer gardens in Munich.
Hope, you'll see that these examples are particularly helpful to understand the patterns. Thus, my suggestion is to add real life examples to every pattern description, at least to those that are hard to understand. I am wondering whether we could also apply this idea in the opposite direction, i.e. taking real life examples for finding new software patterns.