software

Anaemic Domain Model

Martin Fowler once wrote an article “AnemicDomainModel” decrying the “anti-pattern” of a service layer that executes actions (as opposed to delegating them to an entity), combined with entities that are just data buckets of getters and setters.

His claim is that this kind of application architecture is wrong because “…it’s so contrary to the basic idea of object-oriented design; which is to combine data and process together.”

Right.

Object oriented design, i.e. designing around conceptual “object” blocks that model distinct entities in your system, has always been a bit of a flawed model, in my opinion. When you go shopping, let’s say to buy a DVD, you grab a basket and wander down to the DVD aisle. You check for the next boxed set of your favourite TV series, grab a copy, put it in your basket, wander across to the till (yeah yeah, no-one gets a basket for one item, just roll with it for now) and pay.

In a standard OO model the Service layer is simply a dumb abstraction that provides delegation, whereas the Domain contains the bulk of the application code.

When you “added” your item to the basket, the product did nothing, and neither did the basket; the entity that performed the action was your hand. That’s because products and baskets can’t do anything, a product is just an inanimate thing (obviously there are exceptions to this, such as if you’re buying a puppy, but there are exceptions to almost everything), and a basket is just a receptacle for inanimate (or animate) things. Still think your product needs an AddToBasket(Basket basket)?

So, if we’re building an eCommerce system (a full-on eco-system, not just the B2C frontend; warehouse management, invoicing etc.), which ones of these will have product data? I’m going to say all of them.

You’ve got options at this point. You can say “No! I’m not going to pollute my applications with shared logic and shared datatypes and shared… well, anything”. I admit, there are some serious downsides to having shared functionality, the main one being the inability to make changes without risk of regression. But risk can be managed, and the organisational upsides of the development velocity that can come from only writing code once, as opposed to once per system, are massive.

Common functionality is unlikely on your Product class. Warehouses don’t have baskets; customers don’t buy quarterly overviews; your accountant probably doesn’t care too much about how much stuff fits onto a pallet. But common data is very much the case, everyone will need to know what the product is (warehouses need to know that Product #45126 is a crate of beans, not the wrongly-marked ostrich steak they can’t fit on a pallet; the accountant will need to know that a crate of tennis balls can’t possibly be priced at $4,000 a pop), everyone will need pretty much the same level of basic information.

How does this fit into a domain model?

In the ADM (I would like to coop this as the moniker for this pattern, I don’t even slightly think it’s insulting), our “Domain model” is only “anaemic” in the data layer. We have a full-blown domain model at the “service” layer. There’s just an extra conceptual leap between having a polymorphic product and a polymorphic service.

In the ADM, the Service layer contains the bulk of the logic, and therefore the bulk of the code, and the Domain is only used to model the data.

Under “normal” circumstances (old-skool circumstances, more like) you’ll probably have a factory that takes the “productType” attribute from the raw dataset and decides which type of product to instantiate, then whichever class that’s handling the basket addition delegates the AddToBasket() call to the newly-instantiated SubProduct.

With the newschool (super-awesome) method, we’ll probably have a factory that takes the “productType” attribute from the Product class and decides which type of IBasketHandler to instantiate, then whatever class that’s handling the basket addition delegates the AddToBasket() call the to newly-instantiated SubProductBasketHandler.

See the difference? That’s right, very little. But in terms of separation of concerns, well, we’ve gained a whole lot. Products don’t need to know anything, so there’s no danger of one of the juniors deciding that it’s fine to have the Product(string productId) constructor load the product data from the database (performance and maintenance problem, here we come); IoC will come naturally, testing is much easier with the kind of statelessness that comes with this pattern.

If we’re talking semantics, yeah, we don’t have a “domain” model anymore, we have a data model and a process model, and they’re separate. But really, do your products have behaviour, or do various procedures happen to the products? Data and process should be separate, they’re fundamentally different things; behaviour is dictated by data, data is dictated by behaviour, but there’s a fundamental divide between the two, in that process can (and will) change and data is generally so static that it simply cannot.

So, who’s right? Well, I’d say that both models are appropriate, depending on context. If you’ve not got an ecosystem, and you’re fairly sure your single system will always be the one and only, and you’re confident you’ll get the best results from mixing process and data then go for it. If you’re worried about maintainability and have more than one interlinked system, then think seriously about what’s going to give you the best results in the long term. Just be consistent, and if you’re not, be clear about why you’re deviating from your standards or you’ll end up with an unholy amalgamation of different patterns.

This post originally appeared on Ed’s personal site.

First thoughts on Windows 8 – the Developer standpoint

I’ve been to a few demos recently of the full Windows 8 experience so thought I’d put a few thoughts down about it.

For those who have not seen it, Windows 8 really is “revolution not evolution”. It throws away many of the concepts we have been familiar with since Windows 95 (start menu, task bar…) and even some of the core concepts of Windows such as … well… Windows. It is the first OS designed to work across desktops and tablets.

The core of the new system is the Metro interface which genuinely doesn’t have windows. All applications are run full screen for what (I have heard called many times during these demos) is a “fully immersive experience”.

Windows 8 will seamlessly integrate between desktop, tablet and mobile.

The standard means of navigating around and between programs have been largely removed. There are no more close and minify buttons or menu bars. Instead addition options for programs are found by swiping the appropriate part of the screen. The right hand side is for the “charm” screen which is a set of common options that apply to all programs (notably search and share), while top and bottom can be used for application options. Programs are closed by dragging them off the bottom, and minimised by dragging across and bringing another program on.

This leads onto another key change: when a program is inactive its processing is suspended. To a certain extent this can be developed around but by default Metro apps do not allow multi-tasking.

The Metro screen displays all apps as tiles; tiles and other notifications can be fed information from within your application or pushed from remote services via a cloud based distribution service. This leads to a dynamic desktop and gives developers the ability to entice users back into their application.

There are probably a lot of people thinking that this will mean the end of traditional windows based applications but worry not, there is also desktop mode. In desktop mode traditional Windows programs will run in the same format as they always did. Desktop apps can be launched via shortcuts from the Metro tile screen or from a separate menu within desktop mode.

As always with Microsoft products the support and facilities given to developers for the new platform is extensive and supports all the systems needed for creating innovative apps but that is a subject for a blog post of its own.

Verdict

So, what do I think of all this? Metro is clearly designed to be a tablet interface; indeed Microsoft have said that it is designed for touch first and everything else follows out of it. As a tablet interface it is very innovative. The sharing ability between programs is excellent and a big step forward over anything that has been seen before. The built in cloud support for multiple devices is also a great feature, allowing synchronisation across multiple devices straight out of the box.

I think it works less well in a desktop environment; I have been trying to think about what applications I would use in Metro mode. Twitter, email, IM, and web browser immediately spring to mind. However I spend most of my time in Visual Studio, SQL Server, Office or other such tools and usually have the other tools mentioned above open at the same time, usually on a separate monitor so I can watch over them while carrying on working. Ultimately, I have paid for a large screen and I don’t want a fully immersive experience; I want to control my level of immersion by setting windows to the size I want.

The other issue I have is that, despite how many times I hear or read about Microsoft people saying how beautiful the Metro interface is, I am not wowed by it. I have never loved the look and feel of Windows phone and Metro is essentially and evolution of that theme. The tiles are great in their ability to stream real-time information outside of the application, but I find the look too busy and I’m really not keen on the way things flip in and out. Basically, I look at the Metro interface, I look at my iPad, and I’m not wanting to throw out the iPad.

The Windows 8 logo

Building a standard system across all platforms is a bold move and only time will tell how well it will work out. It is fair to say that Windows 8 is a pretty good stab at it.

What I find interesting is that to me this is much more of a consumer than a business solution. I feel that many of the business users who, like me, spend all day in tools like Visual Studio or Office may share my concerns specified above. Consumer users though will probably love the concepts behind the Metro interface. In this market a tablet is a serious alternative to a laptop to achieve their aims (web, email, twitter, IM, Skype etc).

This raises an interesting question about whether the historical vision of Windows as a shared system between business and consumers is actually flawed and Microsoft should be looking at selling Metro only (with no desktop) as a consumer option and a full Windows 8 system with desktop support for business users. The consumer version could even be a free offering (like iOS) that is funded by the profits on app sales.

I started by saying that Windows 8 was “revolution not evolution” and am going to end by saying that it may be revolution beyond just UX, and go to the heart of Windows as a product.

Approaching Application Performance with TDD

This blog post was written by Intechnica Senior Developer Edward Woodcock. It originally appeared on his personal website, which you can view here

Test Driven Development (TDD) is a development methodology created by Kent Beck (or at least, popularised by him), which focuses on testing as not just the verification of your code, but the force that drives you to write the code in the first place.

Everyone who’s been exposed to TDD has come across the mantra:

Red. Green. Refactor. Repeat.

For the uninitiated that means you write a unit test that fails first. Yup, you aim to fail. Then, you write the simplest code that’ll make that test (and JUST that test) pass, which is the “Green” step (obviously you have to re-run the test for it to go green). Then you’re safe to refactor the code, as you know you’ve got a test that shows you whether it still works or not.

Test Cycle - Red is where I'm going to do my next dev step (or a long-outstanding issue I'm marking with a failing test)

So, that’s your standard dev cycle, RGRR. Every now and again you might drop out and have a poke around the UI if you’ve plugged anything in, but you’ll generally just be doing your RGRR, tiny little steps towards a working system.

Finally, when you’re happy with the release you’re working on, you deploy your code to production and go for a beer, safe in the knowledge that your code will work, right?

Continuous Integration - Useful for seeing your project's red/green status

Well, yes, and no. You’re safe in the knowledge that your business logic is “correct” as you understand it, and that your code is as robust as your tests are. But if your app is a large-scale internet (or even intranet) application with many concurrent users, you’ve only covered half the bases, because having the green tests that say that the system works as expected is useless if the system is so clogged that no-one can get on it in the first place. Even a system that simply degrades in performance under high- (or worse, normal-) load scenarios can leave a sour taste in the mouth of your otherwise happy customers.

So, the question is: how can you slide in performance as part of your RGRR cycle? Well, TDD says that the tests should drive the system, but they don’t specify what type of test you need to use. A common thought is to add automated UI tests into the mix, to be run in batches on a release, but why not add in a performance test as part of the build-verification process.

Going from our RGRR cycle, first we need a failing test. So, decide on a load model for the small section of the system you’re working on right now. Does it need to handle a hundred users at once, or will it likely be more like ten? It makes sense to go a little over what you might expect on an average day, just to give yourself some extra headroom.

Response Time Comparison - If your graph looks something like this you're probably doing OK!

Next, pick a load time that you think is acceptable for the action under test. If you’re loading search results, do they need to be quick, or is it more of a report that can be a fire-and-forget action for the user? Obviously input may be required from your client or Product Owner as to what they consider to be an acceptable time to carry out the action, as there’s nothing worse than being proud of the performance of something when it didn’t need to be fast, as then you’ve wasted effort that could be used elsewhere!

Now you’re going to want to run the test, in as close a match to your live environment as possible. At this point I need to point out that this is more of a theoretical process than a set of steps to take, as you’re unlikely to have one production-like environment for each developer! If needs be, group up with other developers in your team and run all your tests back-to-back. Make sure you have some sort of profiling tool available, as running the tests in a live-like environment is the key here, if you run them locally you’ll not be able to replicate the load effectively (unless you actually develop on the live server!).

If you’re using an iterative development approach and this is the first time you’ve run a test on this particular piece of functionality, most likely your test will fail. Your average response time under load will be above your target, and you may not even get up to the number of users you need to account for.

So, that’s the “Red” step accounted for, so how do you get to green? This is where we start to diverge from the RGRR pattern, as to get good performance you’ll need to refactor to make the test green. If you can’t run the same test, just take a few stabs through the UI manually to get some profiler results, and spend the time you’ve saved waiting for the test to complete thinking about how you can implement tests that can be run locally and from a load injector.

Profiling in action: DynaTrace giving us a realtime comparison. We're looking for some red bars, which indicate worse performance.

Hopefully your profile should have some lovely big red bars that show you where the hotspots are for your particular piece of functionality and you can use this information to refactor to make the algorithm less complex, the DB call faster, or to add some caching. If you’re being a rigorous TDD-adherent you’ll probably only want to make a single architectural change before you re-run the performance test, but in most cases you’ll want to do as many things as you can think of as performance tests on a live-like system won’t be available all the time.

Once you’re happy with that, re-run your test, this should be the “Green” step, if it’s not you should go back and refactor the code again until you hit your target. If you’re struggling to find enough headroom from code or architecture changes to hit your performance targets you most likely need to either leverage more hardware or refactor your UI to divert traffic to other areas.

Right then, we’ve done Red, Refactor, Green, next comes “Repeat”. If you think you can eke out more speed from the area you’re working on, you can go back and adjust your test load, but if you’ve gone for a known (or expected) production load with a little extra on top you probably don’t want to waste time on that. After all, when you’re practicing TDD you do just enough to hit your target, and then move on.

Repeat Load Test - When you do your repeat you can add in the "Change" column, which helps identify possible areas on concern for the next cycle.

So what’s next? Well, next you implement another piece of functionality, and do another load test. As you go along you’ll eventually build up quite a collection of load test scripts, one for each functionality area in the system, and you should run these together each time you add a new piece of functionality, just like in a unit testing session. However, I’d avoid doing tests on multiple new pieces of functionality at once the first time around, as you will likely come across a situation where a single piece of functionality knocks off performance across the board, giving you a big spreadsheet full of red boxes.

If you follow this method (RRGR) throughout the development lifetime of your system you should have a rock-stable system that can quantifiably cope with the expected amount of load, and then some. This is a great situation to be in when you’re planning new functionality, as you’ll rarely have to worry about whether you have enough headroom on your boxes to implement killer feature X, and can instead worry about really nailing that cool new bit of functionality.

Webinar: Designing Applications for the Cloud

This webinar, from 6th March 2012, was hosted by Intechnica‘s Technical Director, Andy Still. Andy talked about the key principles of designing and migrating applications to the cloud. This includes scaling out, taking new and imaginative approaches to data storage, making full use of the wide range of products and services on offer from cloud providers (beyond hosting), and exploring the many flavours of hybrid solution which can mean all types of business can leverage the benefits of the cloud.

Andy has architected and built a number of cloud-based applications, specialising in highly scalable, high-performance, business critical applications.

If you’re planning or considering moving to the cloud in 2012 then this webinar is essential viewing.

More Intechnica webinars

What are the options for testing in the Cloud?

I’m in the final stages of preparing my presentation and workshop session for the UK Test Management Summit next week in London and its making me think more about cloud computing in general as well as performance testing. Either testing in cloud environments or using the cloud to deliver more scalable performance tests.

Intechnica’s research paper last year, entitled “How Fast Is The Cloud?” investigated the relative performance of a simple eCommerce application on various different cloud platforms including IaaS and PaaS options. We demonstrated that a well implemented cloud solution could out-perform traditional hardware but that poor implementations would confirm cloud-sceptics suspicions about poor performance in the cloud.

At Intechnica, as well as using cloud environments to functionally and performance test code that we’re developing for clients, we use cloud based performance test tools to test our customer’s own test environments. By using cloud based load generators (injectors) and the Intechnica TrafficSpike product, we can quickly provision tens of load generators, use them for a few hours and then decommission the servers. This allows for highly scalable, comparatively low cost performance testing particularly when compared to trraditional models where multiple servers sit idle waiting for the one day per week or month where they’re used to their full potential.

The trend in performance testing seems to be a move away from traditional performance test tools and towards cloud-based load generation. This is demonstrated by the growth in companies such as SOASTA, LoadStorm, blitz.io and BlazeMeter. Our workshop at TMF will give test managers the opportunity to discuss these different test technologies and obtain a better understanding of cloud performance and the implications for their business. As well as this we’ll be giving attendees the opportunity to use Intechnica’s Cloudflex product to see how easy it can be to provision multiple, identical test environments for themselves.

I’m looking forward to meeting attendees next week to discuss the implications of cloud computing for those of us in the testing industry.

AWS instances, their ever-changing hostnames and the implications for software licensing

I’ve recently been doing some performance testing for a client and evaluating the use of dynaTrace for monitoring application performance under load. As well as an installation of dynaTrace at the client site, we have a demonstration/evaluation licence which is installed on an AWS cloud server. As well as being useful for client demonstrations, this gives us the opportunity to perform proof of concept exercises and “try things out” away from production systems.

Last week, in an effort to save on the cost of keeping the AWS instance up and running all the time, I decided to shut the server down using the AWS console. When I went back to the server and restarted it, I had the following error message in dynaTrace.

I did some investigation and I found that dynaTrace locks the licence key to the hostname of the server on which it is installed. This is all well and good in a normal environment, but I noticed that the name of the host server changed each time that I rebooted. When I installed dynaTrace, my machine name was ip-03a4d76 and when I restarted the server the name had changed to ip-0a3b11c9.

I looked at the server IP address and saw that as the server restarted (even though I was using an elastic IP address to address the server externally), the hostname changed when the private (internal Amazon) IP address changed. The hostname was a hexadecimal representation of the private IP address.

My IP address was 10.59.17.201 and the hostname (which has since changed again) was ip-0a3b11c9 (0A = 10, 3B = 59, 11 = 17 and C9=201).

I spoke to the dynaTrace, the supplier of our software, and they told me that it can be tied to a MAC address, rather than a hostname if required, but that didn’t help me since I understand that MAC addresses change each time AWS instances restart. Instead I looked at ways of fixing the hostname and found that it was remarkably easy (when you know where to look).

On each Windows AWS server there is a program on the start menu called “EC2 Service Properties”. Run this program and uncheck the box “Set Computer Name”, you can then set a HOSTNAME normally which persists after each reboot. Your hostname-dependent software can then be reinstalled or re-licensed and you can relax in the knowledge that your software will run properly next time you restart your server.