Ethods & Ools: Writing More Than Code in Software Development
Ethods & Ools: Writing More Than Code in Software Development
Ethods & Ools: Writing More Than Code in Software Development
Practical knowledge for the software developer, tester and project manager
ISSN 1661-402X
www.methodsandtools.com
Inside
Testing Performance of Mobile Apps - Part 3: The Network ................................................. page 3
Agile Scrum Sprint Length: Whats Right for You? .............................................................. page 16
Software Developer Business Patterns.................................................................................... page 26
Git-TFS - Work with your Team (Foundation Server) with Git ............................................. page 35
Apache Isis - Developing Domain-driven Java Apps ............................................................. page 40
Distribution Sponsor
Figure 2. SPEEDTEST.NET - 3 test measurements including Ping time, download speed and
upload speed.
WebPerformance Load Testing Software & Services - Click on ad to reach advertiser web site
Ping time: This indicates the initial time to send a message and hear back from the
application server. In some instances we call this first look or the initial reaction time of the
network for the first packets to come back to the device through the network.
Download speed: This is the speed of downloading data, so especially for browsing or
information related mobile applications such as news or video, this measurement can
significantly affect the user experience of performance.
Upload speed: This is the speed of uploading data, so depending on the characteristics of
the mobile application, this measurement can significantly affect the user experience of
performance or not at all.
When carrying out network performance tests, as usual it is important to have a controlled
environment and systematic parameter alteration. Some of the parameters in the test
environment for instance include: mobile device, mobile application (native or mobile web site),
type of interaction, time of day, etc.
We used SPEEDTEST to carry out some simple network performance tests and get a
comparison baseline. Firstly, we wanted to get some 3G network performance characteristics
with one device, the HTC One (Android 4.1). We ran the test six times. Figure 4 shows the
results.
Test cycle ping time (10ms) download speed (kbps) upload speed (kbps)
1
2
3
4
5
6
StdDev
Avg
CV
41.1
70.3
17.700
25.6
23.1
44.1
19.300
37
0.522
26
61
32
33
98
29
28
47
0.596
13
151
48.000
100
66
22
52.000
67
0.776
Figure 4: Network -3G, Device: HTC One (Android 4.1), 6 test cycles
Figure 5. Graphic: Network -3G, Device: HTC One (Android 4.1), 6 test cycles
You can see from Figure 5 that there is a high variation in the results between the test runs. In
particular the coefficient of variation (CV-standard deviation/mean) are over 50% for all
measurements. This indicates that 3G users experience extreme variation in their application
performance when accessing the network especially for upload speed.
Next, we wanted to see how this varied in different networks while keeping other variables
constant.
Test cycle ping time (10ms) download speed (kbps) upload speed (kbps)
1
2
3
4
5
6
StdDev
Mean
CV
45.8
36.8
24.9
44.9
51.5
44.1
9.3
41.3
0.225
8
12
15
14
15
9
3
12
0.250
7
13
9
8
11
13
2.6
10
0.260
Figure 6. Network -2G, Device: HTC One (Android 4.1), 6 times (test cycles)
Figure 7. Graphic: Network -2G, device: HTC One (Android 4.1), 6 times (test cycles)
As shown in Figure 6, notice that although the download speeds were significantly slower with
2G versus 3G, the variability of the results as shown in Figure 7 is less than half of 3G network
results. So although the speed is slower, the variability may impact applications that have
bursty traffic such as games. Now lets look at the WIFI results.
Test cycle
1
2
3
4
5
6
StdDev
Avg
CV
Figure 8. Network -wifi, Device: HTC One (Android 4.1), 6 times (test cycles)
Figure 9. Graphic: Network -wifi, Device: HTC One (Android 4.1), 6 times (test cycles)
Methods & Tools * Summer 2013 * Page 8
Rapise Rapid & Flexible Test Automation - Click on ad to reach advertiser web site
Figure 10. Summary-Same device HTC One (Android 4.1), different network: 2G, 3G, Wifi (on
average)
Figure 11. Graphic: Summary-Same device HTC One (Android 4.1), different network: 2G, 3G,
Wifi (on average)
Obviously, different networks have different performance but the question is how the
performance can influence user experience. Next we wanted to see how different device
influence the users experience of network performance. So we took the best performing
network (WIFI) and tested it with 3 additional devices.
Devices
965
960
upload
(kbps)
450
460
950
430
960
450
speed
Figure 12. Same network -WIFI, Different device: iPhone4S (iOS5.0), HTC One (Android4.1),
Motorola ME860 (Android 2.2)
Figure 13. Graphic: Same network -WIFI, Different device: Iphone4S (iOS5.0), HTC One
(Android4.1), Motorola ME860 (Android 2.2)
We can see it is very close. What is most interesting is that you often see advertisements for
how fast a new smartphone is. Perhaps the phone does have great performance in that it allows
users to swap between many applications quickly or that native mobile applications execute
much faster than older model phones. But in reality, there are still many mobile applications that
are web-based and not native applications. This means that much of the applications
performance and user experience will be dependent on the networks performance and as weve
shown, that can vary widely and is independent of the phone itself.
However, the network performance is still impacted by the application and the way it sends data
over the network. Although our simple tests indicated that the device is not important regarding
being influenced by network performance, different applications will send different data packet
structures to the server and these data packet structures are also treated differently by the
network.
Before testing your applications load on different networks, it is still a good idea to investigate
your users device models as different device models will send different amounts of data, even
for the same application or web site accessed. Figure 14 shows a market share as of 4Q 2012,
but it differs between different products in different countries. For example, if your application
or site is accesses mostly in a developing country, maybe the IOS percentage will lower than
indicated by aggregated statistics as shown.
Methods & Tools * Summer 2013 * Page 11
With a HAR viewer, you can examine these measurements in detail for each object. Looking at
these measurements, our previous article focused on the time to transfer from the server to the
browser of each object, hence download times in that article shown in Figure 8: Waterfall View
of time of each object downloaded which can be partially solved by caching. However, other
measurements such as time the object takes to be requested, and time to connect to the server
are more indicative of poor network performance. To examine the data, the HAR file format can
be read by many viewers, each with a different format and view of the data. The Mobitest tool
has a built in viewer that enables us to look at particular images and http requests that could be
causing the delays as shown in Figure 16.
Figure 16. Mobitest HAR Viewer showing results from iPhone4 with iOS 5.0.
As you can see, it shows each object and the load time along with other statistics shown in the
pie chart. On the pie chart, when you mouse over the different types of delays (blocked, DNS,
SSL, etc.), you can see the time delay. In this instance, we can see that the connect time is 57
ms. This is much different than just examining download speeds because the connect times
which are the time that the server establishes communication with the browser, can be
Methods & Tools * Summer 2013 * Page 13
Figure 17. Step HTTP Download Graph via Shunras NV HAR Viewer
AgileLoad Flexible Enterprise Load Testing Tool - Click on ad to reach advertiser web site
Scrum
Scrum
TinyPM Smart Agile Collaboration Tool - Click on ad to reach advertiser web site
Scrum
The Sprint Review (a.k.a. Demo)
The sprint review meeting provides an opportunity for the team to hear feedback from product
owners, peers and anyone else who attends. The more often a sprint review occurs, the more
often feedback can be provided, incrementally improving the product. If this occurs on a shorter
cycle time, the cumulative effort of the small improvements resulting from a series of frequently
held reviews will yield a better product than that of a longer cycle time. In fact, late in a project,
the team may wish to consider a move to one-week sprints to increase the opportunities for
feedback as it prepares for a production release.
The Retrospective
The retrospective is a key aspect of the inspect-and-adapt Scrum cycle. The more often a team
pauses to consider how to streamline its process, the sooner it will identify process issues,
attempt to address them and reach terminal velocity. Frequent process improvement meetings
also allow for a team to provide feedback to management on productivity drags, such as
spending time creating status reports that no one will use or creating a business requirements
document that no one will read. Not unlike the fixed political timebox of U.S. elections, the
retrospective may be used as an outlet for individuals process frustrations, not necessarily to
vote anyone out of office, but to allow people to voice their opinion.
Sprint Planning
The perception that moving to longer duration sprints will reduce pressure and provide
breathing room without a cost is a false truth. Indeed, it may provide breathing room at the
cost of team velocity. Consider the time change during Daylight Saving Time, when people
actually have one day a year with 25 hours. How do they spend their extra hour? Some may
choose to work more, others may choose to sleep or rest more, and others may choose to do
more. The point of this simple analogy is that people will adjust to fill whatever time they have
been given.
We postulate that the smaller the sprint duration, the faster the engine can run. Smaller durations
squeeze out the fat and can only run lean. Consider that if the team knows it has up to three
weeks to perform a task, it may spend time researching a better solution than its first thought
design. However, if the team only has one week, it must quickly implement what can be
accomplished in the sprint.
The Commitment
An argument for shorter duration sprints is the issue of how the team handles the absence of a
key team member. Regardless of the reason for the absence, the general rule is that the team acts
as a unit and must pick up the slack to meet its commitment. This places a significant burden on
the remaining team members for the duration of the sprint once the absence begins. In longer
duration sprints, the team has committed substantially more points than a shorter duration sprint,
and if a person is out for a portion of that longer sprint, the remaining team members must either
carry the load longer before they can resize velocity or de-scope items to which theyve
committed. Weve found that, in shorter duration sprints, when a team member is absent, teams
are more likely to complete the sprint with the original scope than de-scope it. The reason:
Teams can endure pain for a few days.
Scrum
SpiraTeam Complete Agile ALM Suite - Click on ad to reach advertiser web site
Scrum
The Unbroken Think-Stream
One consideration for longer duration sprints is that software development is, to some degree,
more art than science, and it requires a level of creativity that cannot be rushed. Certainly, it
seems obvious that if the team performs one-week sprints, it has only three actual work days
the first day is spent planning and designing, and the last day is spent on the review and
retrospective. On longer sprint durations, say four weeks, the team has 18 unbroken days for the
team think-stream. They have time to dream, be creative, identify high-risk design issues and
address them, toss out their first or even second version of an idea and restart again and again
before bringing their ultimate idea to the sprint review. This degree of creativity and the pursuit
of perfection are not to be found in deadline-driven software development.
Human Nature and Reality
The boots-on-the-ground reality is that the same thing is going to happen at the end of the threeweek iteration that happens at the end of a one- or two-week iteration: Time allocated for testing
and preparing for the sprint review will be squeezed. What weve found is that its more a
matter of the team adjusting what it can do during the iteration duration and setting expectations
appropriately among themselves than the alternative, which is trying to lengthen the iteration so
the team can finish the stories they committed to. The better solution to this point is to reduce
the amount committed to, break the stories into smaller tasks, pick up more stories
opportunistically, deliver functionality earlier in the iteration and allocate time to test and
prepare for the sprint review from the start.
Procrastination
One aspect of human nature is for people to postpone and procrastinate on work that they know
they need to do. While this must have a scientific name, lets affectionately call it college termpaper thinking. Why? The stereotypical college student who is assigned a research paper at the
start of a semester will think he doesnt need to start on it right away; the end of the semester (or
term) is many weeks away. He does other things and comes back to it about three weeks
before its due, only to realize that he is going to need more hours than are left to produce a
good paper. His procrastination will result in a lower quality paper, with less content or depth on
the topic assigned.
The same may happen with a Scrum team with a longer duration sprint. It may not feel like a
sprint if the duration is four weeks. Instead of diligently using the unbroken time for a thinkstream and following a rapid creative-destruction cycle, the team slowly starts on the stories,
building on its previous sprints work but realizing with only a few days left that what its built
is not adequate.
Visibility into Team Challenges
Professional developers are smart translators that like to solve puzzles. In the mindset of a
stereotypical developer, when a challenge is encountered in the course of developing a
component, they put all their energy into solving it. In this scenario, one possible path has been
taken many times by developers. The developer becomes consumed by the challenge and
doesnt report it as a block to her Scrum master; after all, shes smart and, in the past, has solved
more hairy challenges than this one.
Scrum
The catch is that, in a short-duration sprint cycle, the challenge must become visible to the
Scrum master. This is against the developers nature - she doesnt want to bother the Scrum
master with a non-issue. So, what happens? Often, the developer works to solve the challenge
right up to the deadline but fails to finish it per the acceptance criteria, and the product owner is
surprised that the functionality was not completed in the sprint review. There is a danger here; if
this behavior occurs in the context of a longer sprint duration, the opportunity cost will be
quantified in the form of lower velocity.
The Story Creation Debacle
Another consideration for longer duration sprints is the time it takes to flesh-out an epic into a
family of fully developed stories and document the subtasks for each. The reality is that some
topics require lots of time from the subject matter experts and may need several reviews with
the product owner, his peers or other stakeholders before the acceptance criteria for a family of
stories is ready for developers and testers to start translating that story into functionality.
This is where we need to recognize that it will take time to draft, socialize and refine stories as
the team moves through the story creation process, and we should forecast upfront that a
particular family of stories will need more than one sprint to complete. For some stories, three
weeks wont be enough. In previous projects, weve found that some story families can take up
to eight weeks to produce because of the subject matter experts and/or the complex nature of the
topic.
Agile Business Conference, London - Click on ad to reach advertiser web site
Scrum
With that said, it is not wise to move the sprint review, retrospective and metrics gathering
checkpoint just because a story author team member needs more time to finish a family of
stories. A better approach is to extend the time to create that family of stories across sprints and
provide updates at the end of each sprint as to where the group is in the process.
Another approach is to establish a checkpoint with one or more business peer reviewers that
would verify that a story is ready for development. This validation step could also act as a
measurement checkpoint for the rate of story creation, which would provide one more data point
for management and the team to understand its velocity and productivity.
Some Metrics to Consider
Lets assume for a moment that your Scrum team is struggling through two-week sprints but is
able to produce 100 story points of velocity for each sprint. They are struggling because of
pressure to complete the stories to which they committed, but theyre not working weekends to
complete them. However, the testing activities are squeezed, and the team doesnt feel it has the
proper time to prepare for the sprint review. At one sprint retrospective, a member proposes that
the team switch to three-week sprints to reduce the pressure, perform appropriate testing and
prepare for the sprint review. The real issue is that the team is committing to deliver too many
stories in one sprint, and they need to adjust the number downwards. However, lets consider
this proposal from a simple metrics perspective.
We suggest that moving to three-week sprints does not actually solve the underlying issue. Our
rationale: It is false to extrapolate that the team will now average 150 points in the new threeweek sprints. Typically, the team will drop back a little because it perceives that the pressure is
less, say, to 130 points in the three-week sprint. The team may now feel it has breathing room,
but it was bought with a 13% reduction in throughput.
In terms of velocity capital over a six-week period, if the team could average 300 points across
three two-week iterations, and if they move to two three-week iterations, the forecast is that the
team will only be able to produce 260 points. Over this timeframe, the reduction in velocity
capital will result in 40 points of less functionality or fewer defects fixed in the final product.
For a team with an average of four story points per story, that means it will complete 10 fewer
stories over a six-week period. That represents a significant difference in functionality. A
product owner would probably balk upon hearing that news.
In a baseball analogy, the difference between an average hitter and a great hitter is only one
additional hit per week. If a team can do the same that is, commit to one additional story per
week it will raise the bar and complete the project with a much better product than what an
average team would have produced.
Should the team keep up the pressure, it may be able to produce the same as it would in the twoweek sprints, but it is unlikely it will exceed that. In other words, on this point, theres little
upside to switching to three weeks but a significant potential on the downside.
Scrum
Scrum
Two Weeks: The Standard?
The two-week sprint duration (10 business days) has become the de facto industry standard.
Why?
The two-week sprint has the best balance of all the above factors. It allows for a team to have a
small amount of creativity with eight days of unbroken think-stream, and it provides a near-term
deadline that kills procrastination and forces developers challenges to the surface more quickly.
Moreover, this approach is often enough to gather feedback from the sprint review and reflect
on the process. Finally, it sets a pace for measuring checkpoints twice a month (leadership
usually likes that), keeps the pressure up and feels like a sprint.
Whats right for your project? Thats a decision youll need to make. Perhaps you are in a
situation where your team members lack experience or a key skill in a particular area, or your
team is struggling with breaking down the stories into tasks, and you conclude that two weeks is
just too short. (For a summary of various sprint lengths and their challenges, see Figure 1.) The
key with longer duration sprints is making them feel like a sprint by keeping up the pressure;
keeping them lean; making sure the team has challenged themselves; avoiding the pitfalls of
procrastination, lack of visibility into developers challenges and the absence of team members;
and allowing story creation to cross sprint boundaries.
Sprint Length Comparison
The challenge with shorter duration sprints is breaking the stories into small tasks and
reassembling them into a unit of work that will be meaningful to the product owner. Consider
this: In a one-week sprint, the team will have three productive days to design, build, test and
polish a component. Given the uncertainty in software development, this doesnt allow for much
time for recovery when the unexpected occurs, causing velocity to appear uneven across sprints.
Also if the increment produces too small a delta for the product owner to notice the update or
change from the last sprint review, then your sprints may be too short.
Methods & Tools * Summer 2013 * Page 24
Scrum
Sprinting Ahead
Consider carefully for what purpose you might deviate from what has become the two-week
standard. Note that there is a series of reasons why two weeks has become the default. You
should ask the question, if we change to a different length sprint, what problem does that
solve? Are there underlying problems, like personality or behavioral issues that are manifesting
themselves in other ways that would be best addressed in another way than changing the sprint
duration? Generally speaking, it is better to set the cadence and have the team adjust to it rather
than the other way around. No matter what sprint duration your team chooses, make sure
everyone buys in, then run it as lean as you can, and keep in mind the considerations raised in
this paper.
Copyright 2011, Cognizant. This article was originally published as a white paper by
Cognizant, a leading global provider of information technology, consulting, and business
process outsourcing services, and is being reproduced here by permission from Cognizant. For
more information, visit www.cognizant.com.
OnTime Scrum Project Management Tool - Click on ad to reach advertiser web site
Software Business
Software Business
Software Business
Over the last eight years I have collected many of these patterns. Often identifying and writing
one pattern leads to the discovery of several more. All patterns are available for download from
my website - www.allankelly.net - and 36 were published as a book in early 2012, Business
Patterns for Software Developers. In the rest of this piece Id like to discuss a few of the
patterns and how they fit together.
Same Customers, Different Product
Once your business has a relationship with your customers they will trust you, satisfied
customers have a positive impression of your company and your. Sales staff already have a
relationship with the customers and the company is in a good position both to understand their
needs and to supply them
Modern consumers are faced with a bewildering number of brands and product variations.
Choosing a trusted brand is one way to navigate the jungle.
Nor is it just individual consumers who return to existing suppliers and brand. Business
customers find it easier to buy from suppliers they have worked with before; and the promise of
a compatible product is a big plus.
So rather than continually seek out new customers for the product you have consider the
customers rather than your products as the asset. Expand your product offering so you have
more products to sell to your existing customers. Do this by focusing on the customer
This approach has the additional benefit that by deepening your relationship with the customer
not only will you sell more, the customer will get a better solution and the relationship will be
strengthened further.
Some sales will build directly on the products you have already sold sometimes called plus
one sales: more licenses for the same software, upgrades to enhanced versions new versions of
existing software, and add-on modules are all possible. The next sale could be a service: support
contracts, training and installation are highly applicable to existing products. In fact, when you
think about it there are actually four possibilities for sales, as shown in Figure 1.
Same Customer
Different Customer
Software Business
Software Business
Same Customer, Same Product is normally found with consumable products - Gillette razor
blades or HP ink jet cartridges but it could be software upgrades, I must have bough five or six
copies of Microsoft Office in my life.
When products last, like software, ways need to be found to entice the same customer to buy
more of the same product. If the customer is a large organization then it might be possible to
move from one group within the company to another selling licenses as you go. While the
paying customer might be the same the end user will be different.
For home users it might be an upgrade cycle new OS, new PC, new Office version. Although
even this might be considered a Same Customer, Different Product model depending on how
you view upgrades.
Diversification - Different Customer, Different Product is inherently risky because it is, in
effect, establishing a new business. Sometimes companies pull this off, like the way Caterpillar
extended its brand into clothing. Perhaps more often this is one jump too many, look at the way
many tobacco companies tried to move into food only to retreat later.
Same Customers, Different Product view customers, not the product, as the asset. Rather than
sell an existing product to new customers you sell existing customer a new product. When done
well this can be highly effective at low risk. Think of Oracle building on the database customer
base to sell enterprise software and middleware, or the IBM Rational developer toolset.
Nor does the different product need to be your own product. You could use the patterns Value
Added Reseller or White Label to offer products to your existing customer base under your own
name. Offering another product as a complement to your own can reduce costs and eliminate
competitive tension something described in the pattern Complementor Not Competitor.
Of course it is sometimes difficult from the outside to tell what a companys strategy actually is.
Consider Dells recent acquisition of Quest Software. This might be a diversification move
Different Customer, Different Product or attempt to sell software to existing hardware
customers, or possibly vice versa.
Homogenous and Segmented Customers
In the beginning many companies assume by conscious decision or through naivety that all
customers are homogenous. Indeed, this approach has some advantages: it reduces time to
market entry and therefore costs. By entering the market it puts the company in the best possible
position to understand what customers want and what is possible. A homogenous customers
approach has worked well for the likes of Microsoft with MSDOS and even Googles early
search product. If you consider all customers to be the same then one product is all you need to
enter the market thus keeping costs down and time short.
In the beginning companies may simply lack an understanding of potential customers.
Sometimes the best way to gain knowledge about customers is simply to get into the market.
However, sooner of later companies start segmenting their customer base so to serve customers
better, and to extract more money.
Segmenting makes sense: customers are not homogenous. Different customers want different
things, some value speed or ease of use, others value low price. Many a software development
team has been lead astray by focusing on the needs of one customer too closely and producing a
product which has little, or no, use to others.
Methods & Tools * Summer 2013 * Page 30
Software Business
The trick is to use Customer Understanding (another pattern in the book) to segment customers
into different groups and address the needs of each group separately. Segment groups are
typically defined on discernable attributes and characteristics that allow differentiation of one
group from another; another approach is to segment on the tasks to be performed. Either way,
working with definable groups avoids generalizations that do not accurately describe any one
group.
You may choose not to meet the needs of some groups if doing so would compromise the needs
of another. When resources are limited is it better to target resources than spread them thin.
Segmenting your customers will allow you to segment your market. As you decide which
customer groups to serve you will define your market position relative to your competitors. You
are also deciding whom you will not serve. In some cases you may need to extricate yourself
from some existing group to pursue your new targets.
Segmentation can help avoid situations where more attention is paid to the customer who shouts
loudest. Strategy is as much, or even more, about what you will not do, whom you will not
serve, as it is what you will do and whom you will serve.
Those you decide to serve will benefit because they will get a product that more specifically fits
their needs. A deliberate choice not to serve some groups allows you to serve others better. Subdividing your customer base will also help you spot opportunities to serve customers better.
But customer segmentation can go too far. While for customers the sheer choice of products on
offer under the same brand can be overwhelming. Last year I needed to buy a new car GPS
system, confronted with what seemed like several thousand products on Amazon I stuck with
the brand I knew, Tom-Tom, and bought the cheapest product rather than spend time
considering the merits of each product. (True, I momentarily considered a Garmin but was again
overwhelmed by product choices.)
More dramatically contrast the approach of Nokia and Apple to the phone market. Nokia
markets an amazing range of different phones. Conceivably there is a Nokia for every customer
segment indeed there might well be more than one. There comes a point were the costs of such
a diversified product range become self-defeating.
Now consider Apples approach to the same market: there is one. There was one iPhone to start
with and although Apple continues to offer older versions, and some Simple Product Variations
(another pattern) there is essentially still one iPhone.
Apple too have segmented the market but having done so they decided to only address the
premium smart phone market. Even here segmentation is limited. A quick look at Nokias
website one day in June 2012 showed four different Lumia Smartphones, six other smart phones
and at least a dozen simpler phones.
On the face of it addressing a segmented customer base with a range of products targeted at each
segment should be a more effective approach than homogenous customers. But as the Apple v.
Nokia story shows things arent always that simple.
Sequences and competitive advantage
Patterns dont exist in isolation. If one company faces a problem and solves it using the same
pattern as another it is quite likely to find the next problem is also quite similar and the
corresponding solution is also similar.
Methods & Tools * Summer 2013 * Page 31
Software Business
Figure 2 shows one such pattern sequence. The start of this sequence is the desire to reach more
customers. After segmenting the customer base the company engages Simple Product Variations
pattern maybe a range of colors products al la the iMac or iPad covers and Core Product
Only. (While Core Product Only works in some domains it doesnt have great history in the IT
world. Consider Microsoft Works, it has most of the Office functionality most users need but
has never sold well. Even Linux seldom appears on its own, it is usually the core of a
distribution or baked into a product like Android.).
Consequently the company has a Product Portfolio. In order to reach the different customer
segments and limit competition with itself the company then engages a variety of
distribution channels.
While one pattern may address one set of problems right here and now in resolving the question
new issues arise. Thus patterns tend to lead to other patterns a pattern of patterns usually know
as a pattern sequence.
Software Business
That said, for some reinventing the wheel is the competitive advantage. The way the product or
service is delivered, or the way the company works, could well be the things that make the
company a winner. The actual product may be very similar to the competition but delivery very
different. For these companies business patterns serve not as a template for what to do but rather
a description of what not to do.
Finally
The software industry, indeed the wider technology, industry doesnt stand still. As the patterns
were re-edited for Business Patterns for Software Developers it became clear that some updates
were needed. For example, Nokia was cited as an example in several patterns. In some case the
pattern and example still held. In others, the events at Nokia lead to new insights into the
business of technology.
A year after publication, nearly two years since the most of the text was complete the patterns
still stand up. I believe the patterns themselves will stand the test of time but I expect some of
the details and examples will change. I also expect that using this common languages for much
of what our industry does will allow software developers and entrepreneurs to come up with
new variations, new combinations and completely new approaches.
References
Kelly A., Business Patterns for Software Developers, 2008, John Wiley & Sons.
Git-TFS
In this article, I'll walk through some of the things that you can do with git-tfs. I assume that you
use or are familiar with TFS source control.
Git-TFS
Installing git-tfs
Before you start, you'll need to install the Team Foundation client tools (Team Explorer). You
probably already have this installed if you're working with source code in TFS. git-tfs works
with the VS2008, VS2010, and VS2012 versions of the Team Foundation client tools.
If you use the chocolatey package manager, you can simply run cinst gittfs. This takes
care of downloading git-tfs and its dependencies, and making them available at a command
prompt.
You can also download the latest release as a ZIP file. The prerequisites for git-tfs are the
.NET 4 Framework and Git (msysgit is recommended). Download the latest release of git-tfs
from git-tfs.com. Extract the ZIP file, and add the resulting directory to your PATH environment
variable. Verify that git-tfs is installed correctly by opening a new command prompt and type
git tfs --version.
The source code is available on GitHub.
Clone
Start by cloning your TFS project into a Git repository. You'll need to know the TFS project
collection URL (if your server is TFS 2010 or later) or the TFS server URL (if your server is
TFS 2008 or 2005). Git-tfs also needs to know the path in TFS that you want to clone. It can
clone any path (other than the root), so you can clone an entire TFS project, or just one
subdirectory of it. Use this command to create a Git repository in local-dir.
> git tfs
local-dir
clone
https://your-server/tfs/collection
$/Project/Path
Both clone and quick-clone produce a normal Git repository. Run git log to see the
imported commits. While you're developing in this repository, use normal Git tools to commit,
branch, etc.
Fetching new changesets
As other developers check in new source code to TFS, you'll want to fetch the changes.
> git tfs fetch
The above command will fetch changes for the current TFS server. It stores all TFS changes on
a branch named tfs/default. You can merge the changes from TFS with git merge
tfs/default.
To fetch and merge all in one command, run
> git tfs pull
Git-TFS
Share using a shelveset
If this is the first time that you're trying out git-tfs, make a commit or two in your Git repository
and try creating a TFS shelveset from git-tfs.
> git tfs shelve this-comes-from-git-tfs
This tells git-tfs to collect the changes you've made into one shelveset. You can view the
contents of the shelveset using the normal TFS tools.
This is an easy way to get started with git-tfs, because it doesn't create a permanent record (i.e. a
changeset), but you can still get a good idea of what it is doing.
Share a single changeset
Git-tfs includes two ways to convert Git commits into TFS changesets. The first is git tfs
checkin. This command will create a single TFS changeset with a squashed diff of all of your
local Git commits.
For example, consider a repository with one commit (A) that git-tfs created from a TFS
changeset (C1), and two commits (B and C) created locally with Git.
A(C1) -- B -- C
To check in the cumulative diff between A and C:
> git tfs checkin -m "made some changes"
Git-tfs can include checkin meta data. For example, to add a work item reference, use the -w
flag.
> git tfs checkin -w 1234 -m "made some changes"
> git tfs checkin -w 1234:associate -m "made some changes"
The checkin or checkintool command will add a TFS changeset (C2) and a corresponding
Git commit (D).
Methods & Tools * Summer 2013 * Page 36
Git-TFS
A(C1) -- B -- C -- D(C2)
Share all your commits
The second way to convert Git commits into TFS changesets is git tfs rcheckin. This
command will create a TFS changeset for each Git commit that you have made locally.
Git-tfs creates the checkins in a single command invocation, so it relies on information in the
commits' messages for other commit metadata. The Git commit message becomes the TFS
checkin comment. Other metadata can be provided on lines with certain keyword prefixes. For
example, a line that starts with git-tfs-work-item: specifies the work item number to link
to the new TFS changeset. See the git-tfs wiki for an example and for a list of other fields that
can be provided.
A(C1) -- B -- C
Methods & Tools * Summer 2013 * Page 37
Git-TFS
Given the previous example of one TFS commit and two local Git commits, you can run this.
git tfs rcheckin
Git-tfs creates TFS checkins from your local commits, and updates your local branch to point to
these new commits.
clone
--with-branches
https://tfs/collection
$/project
The repository that git-tfs will create is still a normal Git repository, and you should be able to
interact with TFS in the same way that you have before, with the exception that you will need to
tell git-tfs which branch you're working with more of the time. For example, to fetch changesets
for all of the TFS branches:
> git tfs fetch --all
Git-TFS
If bootstrap fails to configure the TFS connection correctly, you can configure it manually with
git tfs init. You can provide the same options to git tfs init that you would provide
to git tfs clone. For example:
> git tfs init http://server/collection $/project/folder
Conclusion
If you're using TFS and are considering Git, git-tfs can help you get started without a wholesale
conversion. If part of your team wants to collaborate with each other using Git, git-tfs can
provide a link back to the rest of the team that is using TFS. If your entire team wants to move
to Git, but you still have tooling or processes that require the use of TFS, git-tfs can provide the
link. And if you end up switching completely to Git, git-tfs makes the transition significantly
simpler.
Apache Isis
The ubiquitous language is about the whole team (both domain experts and developers)
communicating transparently using a domain model.
Ubiquitous Language
Build a common language between the domain experts and developers by using the concepts of
the domain model as the primary means of communication. Use those terms in speech, in
diagrams, in writing, when presenting.
If an idea cannot be expressed using this set of concepts, go back and extend the model. Look
for and remove ambiguities and inconsistencies.
Methods & Tools * Summer 2013 * Page 40
Apache Isis
Model-driven design is about capturing that model in a very straightforward manner in code.
Model-Driven Design
Use a straightforward and very literal way to represent the domain model in terms of software.
Changing the code means changing the mode; refining the model requires a change to the code.
But how can a software framework help? Apache Isis does so by adopting the naked objects
(NO) architectural pattern. The fundamental idea of NO is to infer both the structure and
behaviour of the domain objects from the code, allowing the end-user to interact with the
domain objects directly through a user interface generated dynamically (at runtime) from those
domain objects. Let me emphasise the and behaviour bit here. The naked objects pattern is
sometimes characterized merely as a means to build CRUD applications. And while you can
indeed build CRUD apps with an NO framework such as Isis, the real value comes from the fact
that domain object behaviour is also exposed by the framework.
For example, suppose you work for an estate management company where the lease agreements
with tenants can be based on a multitude of factors. For index-linked leases, an invoice must be
sent out each quarter and an adjustment must be made retrospectively when an index rate is
updated. The non-trivial logic to recalculate and reissue invoices can all be exposed as
behaviour on the business object. Moreover, the different calculations required for other lease
types can be invoked in the same way: polymorphic operations, and at the same abstraction
level that the domain expert thinks!
Another reason why you should consider using Isis to build your DDD app perhaps the killer
reason is the speed of development that it allows. To build an application in Isis means writing
the classes in your domain model, but it does not require you to write any UI logic. No
controllers, no view models, no HTML pages with markup, no DTOs nothing. You can build
stuff very rapidly indeed. More subtly, because it doesnt cost much in terms of time to build the
app, you're much more likely to experiment and try out other designs. Each time you iterate
youll gain greater insights into the business domain, and all the time youll be extending and
enriching your ubiquitous language.
How does Apache Isis compare to other frameworks?
Many other frameworks promise rapid application development, so how do they compare with
Apache Isis?
For many developers, the most obvious difference of Apache Isis is the absence of controllers or
views. Instead, both state and behaviour is automatically exposed in its generic object-oriented
UI.
This UI can then be customized in various ways. Isis supports a number of different viewers; the
Wicket viewer (based on Apache Wicket [2]) allows components to be registered that will
render objects in a calendar view, or in a google map, or as a chart, or whatever.
Another viewer is the RestfulObjects viewer which exposes a full REST API from the domain
object model. Using this API you can if you wish hand-craft your own UI, with Isis taking care
of the entire back-end.
Apache Isis
Jolly good. But I suspect by now you'll want to see some code. Lets see how to build an
application in Isis.
Yet another ToDo app
While the ToDo app seems to have replaced Hello World, we make no excuses for using
this domain as the basis for Isis quickstart archetype. Its lack of complexity makes it easy for
you to refactor towards your own requirements.
If you go to the Isis website then youll find instructions and screencasts describing how to run
the quickstart (Wicket/Restful/JDO) archetype [3]. All the example code and discussion that
follows relates to that app. Do run the archetype yourself and follow along.
Domain Services vs. Domain Entities
The quickstart application consists of just two domain classes. The ToDoItem entity is obvious
enough it represents a single item on your todo list while the ToDoItems class is a domain
service acting as both repository (to lookup existing ToDoItems) and as a factory (to create
new ToDoItems).
To see how Isis automatically builds a UI from the code, look at the signature of the methods in
the ToDoItems service in listing 1.
@Named("ToDos")
public class ToDoItems {
...
@MemberOrder(sequence = "1")
public List<ToDoItem> notYetComplete() { ... }
@MemberOrder(sequence = "2")
public List<ToDoItem> complete() { ... }
@MemberOrder(sequence = "3")
public ToDoItem newToDo(
@RegEx(validation = "\\w[@&:\\-\\,\\.\\+ \\w]*")
@Named("Description") String description,
@Named("Category") Category category,
@Optional @Named("Due by") LocalDate dueBy,
@Optional @Named("Cost") BigDecimal cost ) { ... }
@MemberOrder(sequence = "4")
public List<ToDoItem> allToDos() { ... }
...
}
Apache Isis
Apache Isis
We sometimes hear complaints that a programming model heavy with annotations pollutes the
domain model with UI concerns. However, the way that Isis builds up its internal metamodel is
completely extensible; you could if you wished use some other mechanism, for example reading
some external XML file.
Domain Service Implementations
So far weve only discussed the method signatures of a domain service, so lets now look at the
implementations. Listing 2 shows the newToDo() method/action (with some helper methods
inlined to simplify the discussion).
public class ToDoItems {
...
@MemberOrder(sequence = "3")
public ToDoItem newToDo(
... String description,
... Category category,
... LocalDate dueBy,
... BigDecimal cost) {
final String ownedBy = container.getUser().getName();
final ToDoItem toDoItem =
container.newTransientInstance(ToDoItem.class);
toDoItem.setDescription(description);
toDoItem.setCategory(category);
toDoItem.setOwnedBy(userName);
toDoItem.setDueBy(dueBy);
toDoItem.setCost(cost);
container.persist(toDoItem);
return toDoItem;
}
...
}
Apache Isis
public class ToDoItems {
...
private DomainObjectContainer container;
public void setContainer(DomainObjectContainer container) {
this.container = container;
}
}
Apache Isis
Once more the method delegates to the DomainObjectContainer, and (in the
doNotYetComplete() hook method) calls its allMatches() method. This returns all
instances of the specified type meeting some criteria. We call this a nave implementation of
the repository because, although easy to write, this isnt code that would scale to large volumes;
the filtering is done client-side. We trade off the speed of development against performance.
As your domain model starts to stabilize though, youll want to replace this nave
implementation with one that will scale. Apache Isis has a pluggable persistence layer, and the
implementation most commonly used for production systems is the JDO objectstore with
DataNucleus [4] as the underlying implementation. Although JDO isnt as well known as JPA,
DataNucleus is a very capable ORM; JDO is also used within Google App Engine [5].
Thus, the ToDoItemsJdo subclasses ToDoItems and overrides the repository hook methods
with implementations that delegate the querying to the database. Listing 5 shows the
corresponding method, with supporting annotations appearing on the ToDoItem entity, in
listing 6.
public class ToDoItemsJdo {
...
protected List<ToDoItem> doNotYetComplete() {
return container.allMatches(
new QueryDefault<ToDoItem>(ToDoItem.class,
"todo_notYetComplete",
"ownedBy", currentUserName()));
}
}
Apache Isis
Optional Services
In fact, there are rather more than two services registered in isis.properties; the two
discussed in the main text are the only ones that have actions that are visible in the UI.
The other services implement optional SPIs for the framework: auditing, the automatic
publication of events, and strategies for recognizing and handling exceptions. Some of these
capabilities are very powerful, but are, unfortunately, out of scope of this article.
The ToDoItemsFixtureService service provides a convenient way to install sample
(fixture) data, for prototyping with users or for testing. This service isn't intended to be
deployed to production, but when prototyping we usually use a non-persistent data configuration
(such as the JDO objectstore configured against an in-memory HSQLDB database). The service
helps us quickly set up some realistic data.
Time now to turn our attention to domain entities.
Domain Entities
While domain services only expose behaviour through actions, domain entities also hold state:
properties and collections.
In terms of code, think of a domain entity as a javabean/pojo on steroids. It uses the getters
and setters to identify the properties and collections, with any remaining public methods taken
to be actions of the entity.
For example, listing 9 sketches out the properties of the ToDoItem class:
public class ToDoItem ... {
public static enum Category { Professional, Domestic, Other }
@RegEx(validation = "\\w[@&:\\-\\,\\.\\+ \\w]*")
@MemberOrder(sequence = "1")
public String getDescription() { ... }
public void setDescription( ... ) { ... }
@javax.jdo.annotations.Persistent
@MemberOrder(name="Detail", sequence = "3")
@Optional
public LocalDate getDueBy() { ... }
public void setDueBy( ... ) { ... }
@MemberOrder(sequence = "2")
public Category getCategory() { ... }
public void setCategory( ... ) { ... }
@Hidden
public String getOwnedBy() { ... }
public void setOwnedBy( ... ) { ... }
@Disabled
@MemberOrder(sequence = "4")
public boolean isComplete() { ... }
public void setComplete( ... ) { ... }
Methods & Tools * Summer 2013 * Page 47
Apache Isis
@javax.jdo.annotations.Column(scale = 2)
@Optional
@MemberOrder(sequence = "4.1")
public BigDecimal getCost() { ... }
public void setCost(final BigDecimal cost) { ... }
@Hidden(where=Where.ALL_TABLES)
@Optional
@MultiLine(numberOfLines=5)
@MemberOrder(name="Detail", sequence = "6")
public String getNotes() { ... }
public void setNotes( ... ) { ... }
@javax.jdo.annotations.Persistent(defaultFetchGroup="false")
@Optional
@MemberOrder(name="Detail", sequence = "7")
@Hidden(where=Where.STANDALONE_TABLES)
public Blob getAttachment() { ... }
public void setAttachment( ... ) { ... }
@Hidden(where=Where.ALL_TABLES)
@Disabled
@MemberOrder(name="Detail", sequence = "99")
@Named("Version")
public Long getVersionSequence() { ... }
}
Apache Isis
Another thing you may have noticed is that every entity is identified by a title and an icon
(truncated for space in the table view). The title itself is specified either using the @Title
annotation, or, as in this case, using a title() method. This is shown in listing 10.
public String title() {
final TitleBuffer buf = new TitleBuffer();
buf.append(getDescription());
if (isComplete()) {
buf.append(" - Completed!");
} else {
if (getDueBy() != null) {
buf.append(" due by ", getDueBy());
}
}
return buf.toString();
}
Listing 10: The title of the ToDoItem is provided by the title() method
Its possible to specify the icon image using a similar mechanism, but more commonly this is
done just by naming convention. In the various screenshots the icon being rendered is in a file
ToDoItem.png.
Lets get back to looking at the rest of the ToDoItem entity though. Listing 11 shows (an
outline of) the collections (the remaining getters) and actions that make up ToDoItem.
public class ToDoItem ... {
@javax.jdo.annotations.Persistent(table="TODO_DEPENDENCIES")
@javax.jdo.annotations.Join(column="DEPENDING_TODO_ID")
@javax.jdo.annotations.Element(column="DEPENDENT_TODO_ID")
@Disabled
@MemberOrder(sequence = "1")
@Render(Type.EAGERLY)
public SortedSet<ToDoItem> getDependencies() { ... }
public void setDependencies( ... ) { ... }
@MemberOrder(sequence = "5")
@NotPersisted
@Render(Type.LAZILY)
public List<ToDoItem> getSimilarItems() { ... }
@Named("Done")
@PublishedAction
@Bulk
@MemberOrder(name="complete", sequence = "1")
public ToDoItem completed() { ... }
@Named("Undo")
@PublishedAction
@MemberOrder(name="complete", sequence = "2")
public ToDoItem notYetCompleted() { ... }
@Named("Update")
@MemberOrder(name="cost", sequence = "1")
public ToDoItem updateCost( ... ) { ... }
Apache Isis
@PublishedAction
@MemberOrder(name="dependencies", sequence = "3")
public ToDoItem add( ... ) { ... }
@MemberOrder(name="dependencies", sequence = "4")
public ToDoItem remove( ... ) { ... }
@Named("Clone")
@MemberOrder(sequence = "3")
public ToDoItem duplicate( ... ) { ... }
@Bulk
@MemberOrder(sequence = "4")
public List<ToDoItem> delete() { ... }
}
Apache Isis
After visibility/invisibility, enablement/disablement is the second type of business rules we can
apply to class members.
Finally, youll see that the description property is annotated with @Regex, a regular
expression. This is one of a handful of annotations that can validate a property making sure its
value is correct; another commonly used one is @MaxLength.
Validation is the third of the business rules that Isis lets us apply to class members.
In all we therefore have three types of rules: visibility rules, enablement rules and validation
rules. Or, if you prefer: think of them as the see it, use it, do it rules.
Declarative and also Imperative Business Rules
As well as using annotations; we can also specify business rules imperatively, using a number of
supporting methods.
For example, listing 12 fleshes out the dueBy property.
private LocalDate dueBy;
@javax.jdo.annotations.Persistent
@MemberOrder(name="Detail", sequence = "3")
@Optional
public LocalDate getDueBy() {
return dueBy;
}
public void setDueBy(final LocalDate dueBy) {
this.dueBy = dueBy;
}
public void clearDueBy() {
setDueBy(null);
}
public String validateDueBy(final LocalDate dueBy) {
if (dueBy == null) {
return null;
}
return isMoreThanOneWeekInPast(dueBy) ?
"Due by date cannot be more than one week old" : null;
}
Listing 12: Supporting methods for the ToDoItem entitys dueBy property
Both the validateDueBy() and the clearDueBy() are supporting methods for the
dueBy property; Isis matches them by naming convention. In the case of
validateDueBy(), this is called whenever the user enters a new value, prior to actually
calling the setter. If the method returns a non-null string then (as shown in figure 5) this is used
as the error message in the UI.
Apache Isis
Listing 13: Supporting methods for the ToDoItem entitys completed action
As we see in figure 6, this disable method causes the action's button to be greyed out for a
ToDoItem where its complete property is true.
Apache Isis
Apache Isis
For example, figure 7 shows this in the case of the ToDoItems newToDo action.
Listing 14: The supporting methods for the clone action that provide the defaults
Lets look at the choices supporting method, as seen in the remove action. If dependencies
have been added to a ToDoItem, it makes sense only to offer those dependencies for removal.
This is shown in figure 8.
Apache Isis
Apache Isis
}
if(toDoItem == this) {
return "Can't set up a dependency to self";
}
return null;
}
Listing 16: The ToDoItem add action method takes a reference to another entity
But the way that Isis renders this is interesting because, as shown in figure 9, the user can
specify the ToDoItem for the action by just typing its title.
Figure 9: The add actions parameters can be searched for using autocomplete
Isis provides this because the ToDoItem class is annotated with @AutoComplete annotation
specifying an action on the ToDoItems repository/domain service. This can be seen in listing
17.
@AutoComplete(repository=ToDoItems.class, action="autoComplete")
public class ToDoItem ... {
...
}
public class ToDoItemsJdo {
...
@Hidden
public List<ToDoItem> autoComplete(final String description) {
return ...
}
}
Apache Isis
Customizing the User Interface
While the UI provided by Isis is completely generic, it is still, we think, reasonably usable. But
there will be times when you want to extend it.
Isis Wicket viewer (as shown in the screenshots), provides an extensible API allowing different
renderings of any of the components on the UI, leveraging Apache Wickets own Component
interface. For example, one extension [6] automatically renders entities on a map, as per figure
10.
Apache Isis
Do remember though that theres a huge maintenance cost with bespoke UIs; as youve seen,
Isis can generate a reasonably good user interface without introducing that maintenance cost. To
decide whether a bespoke UI is justified, we can distinguish between users that are problem
solvers and those that are process followers.
Problem solvers are users with a (reasonably) deep understanding of the domain, and need a
system that allows them to work in whichever way makes sense. The domain objects enforce
business logic (don't allow themselves to be put into an invalid state), but the system doesnt
prescribe how it is used. Many enterprise apps fall into this category. Generic UIs provided by
Isis support this category of users very well.
Process followers, meanwhile, are users that follow a more narrowly defined process. This may
be because they are inexperienced with the domain, or it may be that the process is high volume,
simple, and needs optimization. These are the situations when a customized user interface
should be built. In this case the RestfulObjects viewer is a great way to provide the backend
plumbing, while you can choose your favourite UI technology for the front-end.
The dangers of custom UIs
While there are good and valid reasons for writing a custom UI to your app you should try to
defer that step to as late as possible. Jumping too prematurely to a custom UI means that
insights into the domain model can get lost. We should not be wasting time tweaking fonts;
there are more important discussions to be had.
But the more obvious danger of a custom UI is that we start writing business logic in the
presentation layer. What starts as a quick check for a non-negative number soon mushrooms
into a huge chunk of logic that should instead reside within a domain object model.
In contrast, Isis generic presentation and application layers act as a kind-of firewall, ensuring
that domain logic does not leak out of the domain. With Isis its impossible to misplace domain
logic because theres only one place to write your code: in the domain objects themselves!
Moving into Production
At some point you'll want to take your application into production. Isis apps are typically built
using Maven, resulting in a WAR file; in principle theres not a lot to do.
You will, of course, want to fully test your application. We're out of space in this article to cover
this, however you should know that Isis has a full integration testing framework (build on
JUnit), allowing end-to-end tests from the UI to the domain objects through to the database. It
even supports testing of annotations (such as @RegEx) and supporting methods (such as
disableNotYetCompleted()). The application generated by the quickstart archetype has
a full set of tests so you can check these out for yourself.
Another area to consider, weve discussed already: replacing nave implementations of your
repositories (such as the ToDoItems class) with objectstore-specific ones (ToDoItemsJdo)
that will scale.
The final aspect to consider is security. Isis integrates with Apache Shiro[7], so authentication
can be handled using Shiros own pluggable architecture. Authorization, too, can be handled by
Shiro; the only thing you need know is Isis format for permissions:
packageName:ClassName:memberName:r,w
Methods & Tools * Summer 2013 * Page 58
Apache Isis
Here memberName is the property, collection or action name, r indicates that the member is
visible, and w indicates that the member is usable (editable or invokable). Shiro allows * to be
used as a wildcard at any level, so the permissions for a given role can be very compact.
Closing Thoughts
This article should have given you a good idea of the Isis programming conventions and how
they translate into a fully working webapp, but we've really only scratched the surface of the
benefits that Isis brings. I can guarantee that youll be amazed at how productive you will find
yourself once you start to use Isis in earnest.
And even though we tout Isis killer feature as being its ability to create a UI directly from your
domain object model, that isnt really what Isis is about at all. Youll quickly discover when you
work with Isis that things like names matter very much in Isis; and names are very much the
heart of the ubiquitous language concept. Being able to quickly and cheaply rename classes and
class members significantly enhances understanding. This is why we call Isis a framework for
domain-driven design.
Its easy to get started with Apache Isis. The quickstart archetype will generate the same
application that weve discussed in this article, and youll find plenty of help on the mailing lists
[8]. I hope to see you there.
References
[1] http://isis.apache.org
[2] http://wicket.apache.org
[3] http://isis.apache.org/getting-started/quickstart-archetype.html
[4] http://datanucleus.org
[5] https://developers.google.com/appengine/docs/java/overview
[6] https://github.com/danhaywood/isis-wicket-gmap3
[7] http://shiro.apache.org
[8] http://isis.apache.org/support.html
Classified Advertising
STARWEST * September 29 - October 4, 2013 * Anaheim, CA
Discover STARWEST - the premier software testing conference that
brings
you
the
most
up-to-date
information,
tools,
and
technologies. Join industry experts and peers in the test and QA
community for a week jam-packed with learning sessions. Register
by August 2 and save up to $400 with Super Early Bird pricing,
plus mention promo code S13VW for an additional $200 off. Now
thats a rocking deal! Go to http://www.sqe.com/go?SW13MTE
SoftwareTestingMagazine.com is dedicated to present industry
news, articles, blog posts, book reviews, tools, videos and
other resources about unit testing, integration testing,
functional or acceptance testing, load or performance testing in
software development projects. Your will also find content
linked to software quality assurance, test automation and new
approaches like Behavior Driven Development (BDD) or Test Driven
Development (TDD). Go to http://www.softwaretestingmagazine.com/
METHODS & TOOLS is published by Martinig & Associates, Rue des Marronniers 25,
CH-1800 Vevey, Switzerland Tel. +41 21 922 13 00 Fax +41 21 921 23 53 www.martinig.ch
Editor: Franco Martinig
ISSN 1661-402X
Free subscription on : http://www.methodsandtools.com/forms/submt.php
The content of this publication cannot be reproduced without prior written consent of the publisher
Copyright 2012, Martinig & Associates