CSC/ECE 517 Fall 2009/wiki2 19 aa: Difference between revisions
Line 179: | Line 179: | ||
[[Example]] | [[Example]] | ||
Once again, we will use the example of the banking system. This time, let’s look at the process of a withdrawal request. | Once again, we will use the example of the banking system. This time, let’s look at the process of a withdrawal request. | ||
During the design phase of the [http://en.wikipedia.org/wiki/Software_development_lifecycle software lifecycle], the development team would find candidate objects used to implement a role within the banking application. One such role would be a withdrawal procedure which could be implemented by the candidate object WithdrawalProcedure. [http://en.wikipedia.org/wiki/Crc_cards CRC] (Class, Responsibility, Collaboration) cards are used to describe each of the candidates. There are a few different ways those cards could be structured. One way is to place the name of the candidate object at the top of the card with a list of responsibilities on the left and a list of collaboration objects on the right. | During the design phase of the [http://en.wikipedia.org/wiki/Software_development_lifecycle software lifecycle], the development team would find candidate objects used to implement a role within the banking application. One such role would be a withdrawal procedure which could be implemented by the candidate object WithdrawalProcedure. [http://en.wikipedia.org/wiki/Crc_cards CRC] (Class, Responsibility, Collaboration) cards are used to describe each of the candidates. There are a few different ways those cards could be structured. One way is to place the name of the candidate object at the top of the card with a list of responsibilities on the left and a list of collaboration objects on the right. |
Revision as of 15:45, 9 October 2009
Survey of “Driven Development” Methodologies
It seems that the discipline of software engineering has been inundated with methodologies with names ending in “driven development” or “driven design”. Each of the methodologies asserts that it is important for a developer to be driven by a specific concept as he/she designs a software system. Some of the methodologies are totally new and others simply supply new names to ideas that have been around for years. None of the methodologies present a perfect way to design code. Each of them has its own niche in the software community.
In this wiki, we will explore the following subset of the “driven development” methodologies:
- Test Driven Development (TDD)
- Behavior Driven Development (BDD)
- Model Driven Development (MDD)
- Domain Driven Development (DDD)
- Responsibility Driven Development (RDD)
A brief overview of each methodology is given along with its strengths and weaknesses. As a conclusion, we will discuss when each methodology should be put into practice.
Test Driven Development
Despite the name, Test Driven Development (TDD) is not about testing. It is a design process. [4] That process is focused on writing unit tests first and then writing the application code that will cause the test to pass. TDD is described using four simple steps:
- Write a test and watch it fail.
- Write code that will cause the test to pass.
- Rerun the test and watch it succeed.
- Repeat.
- Loose or low coupling
- High cohesion
- Virtually bug-free code
- Can be used in conjunction with all other “driven development” methodologies
- Ensures that all code has a test that validates its correctness which produces an overall trust of the code [6]
- Code implementation time is typically shorter. The tests help to eliminate defects early which will decrease the amount of debugging necessary before implementation. [6]
- More code is required due to the unit tests [6]
- Difficult to use for UI code or code that works with databases or certain network configurations [6]
- Tests can become a maintenance overhead [6]
- Less quality assurance activities may be put into place based on a false sense of security in the code [6]
- Tests may still include gaps or blind spots since the developer that writes the tests is also writing the code that the tests are working on [6]
All examples in this article will be based on a banking transaction. A bank is requesting a new application that would allow tellers to create new checking or savings accounts, process a transaction like a withdrawal, or close an account.
For TDD, the developer may start by writing a test that assumes that an object called CheckingAccount receives a non-zero deposit when it is created.
public class BankAppTest extends TestCase {
public void testCheckingAccountInitialDepositNotZero() { try { CheckingAccount checkingAccount = new CheckingAccount(0.00); fail(“Zero dollar initial deposit should throw an exception.”) } catch(ZeroDepositException zde) { //This is the correct action so the test should pass } }
}
The developer would then run the test and see that it would fail due to the fact that no code has been written for the object CheckingAccount. Next, it is time to write just enough code to cause the test to pass.
public class BankingOnline {
public static void main(String args[]){ }
}
public class CheckingAccount {
public CheckingAccount(float initialAmount) { if (initialAmount <= 0) throw new ZeroDepositException(“Initial Deposit”); }
}
public class ZeroDepositException implements Throwable {
public ZeroDepositException(String inMessage) { super(inMessage + “ cannot be zero!”); }
}
Another run of the test should find that it succeeds. Repeat the process until all features have been developed.
Behavior Driven Development
Behavior Driven Development (BDD) is the process of designing software by creating objects that accomplish certain behaviors expected of the system. “Each element of code provides some aspect of behavior which, in collaboration with the other elements, provides the application behavior.” [3] During the design phase of the software lifecycle, system behavior is described using “should” statements. Then, those statements are further defined using the words Given, When, and Then. [3] For example,
Given a checking account, When a customer opens the account, Then the initial deposit should be greater than zero.
BDD is basically an extension of Test Driven Development. Dave Astels says that BDD is “what you are doing already if you are doing Test Driven Development very well.” [4] BDD redefines some of the terms as well as the focus of TDD in its early adoption. For example, TDD was focused on writing tests that would verify the state of an object. BDD should still use TDD because development is still driven by writing “tests” first. However, the tests should verify that an expected behavior occurred rather than verifying the state of an object after a segment of code has been executed.
BDD takes an outside-in approach to designing a system. Typically, the UI is the first part of the system that is written. If the prototypes are accepted as behaving appropriately, then developers move forward to create objects that collaborate with the UI and so on. Therefore, one system feature is fully developed before continuing to another feature.
- “. . . creates more harmony between the user story practices from Scrum and Test Driven Development practices from XP.” [5]
- Increases “. . . fluidity between analysis and design”. [5]
- Focuses on behaviors that add value to the business
- Could lead to tight coupling of various objects since one feature is developed at a time.
Example
Back to the banking application . . . we will use the Given, When, Then example given above:
Given a checking account, When a customer opens the account, Then the initial deposit should be greater than zero.
The developer would begin by creating the UI to allow the banker to open a new checking account for a customer. Before any code is written, the UI would be described using “should” statements.
- The banking application should have a main screen with buttons for opening a new account, processing a transaction, and closing an account.
- Clicking the “Create New Account” button should bring up a new screen that will ask the banker what type of account is to be created – checking or savings – as well as the initial deposit for the account.
- Entering zero for the initial deposit should display an error message once the banker exits the initial deposit field.
Software code would be created to accomplish the behavior described by each “should” statement. A prototype would be presented to the end-user with the purpose of gaining acceptance of the behavior(s) exhibited.
Model Driven Development
Model Driven Development (MDD) is the process of designing a software system where the focus is put on producing models for a given domain. System specifications are described in the form of models which are developed through extensive communication between the development team and the business experts. The models are considered effective if both the end-user and the development team can understand them. [9] Objects are then developed based on the models.
- Buy-in from the end-user for the system design is easier to gain because of the work put into having them be able to thoroughly understand the models prior to developing the system
- Design is more thorough because the end-user or business experts as well as system architects are intricately involved in the system design from the ground up.
- Helps to reduce risk because areas of risk are discovered early in the development process
- Model development is highly dependent on a specified toolset and typically requires being locked-in to a specific vendor.
- One object often has a relationship with many other objects which create numerous dependencies.
Example
In order to design the banking application we have used thus far, MDD developers would create a set of models that would provide a picture of the system to be created. That picture could be described graphically or with text. Here’s an example of one type of model that could be created using Unified Modeling Language (UML):
Similar to BDD, once the models have been accepted by both developers and business experts, software code would be created to accomplish the behavior described by each model.
Domain Driven Development
Domain Driven Development (DDD) is the process of designing software by concentrating on thoroughly understanding the domain in which the product will live. Some example domains are shipping, banking, academia, and health care. DDD is all about avoiding the problem of having many objects that talk to many other objects which produces a lot of dependencies. [7] Such a problem is one of the weaknesses of Model Driven Development. As a matter of fact, DDD is based on MDD in that models are used to design a system. However, those models are based on an intricate knowledge of the domain or business logic. So, DDD forces the developer to thoroughly learn the domain and then incorporate it into the code. That process helps bridge the gap between business experts and developers. The basics of DDD are not much different than what has been used for years in standard Object Oriented Design. However, one of the major differences is the practice of forming that distinct or ubiquitous language that is shared between business experts and software developers. [7]
- The core model is clean and aides in maintainability of the software [7]
- Code is test-friendly and goes hand-in-hand with TDD http://www.infoq.com/interviews/jimmy-nilsson-domain-driven-design [7]]
- Can be applied to different development languages or platforms [7]
- Translations between domain model and infrastructure should not be done by hand and all languages do not have good tools to automate that process [7]
- Should not be used on complex legacy systems [8]
Example
Once again we go back to the banking example . . .
First, the development team would have conversations with the business experts seeking to fully understand the details of business processes and rules of the bank requesting the software. Some such rules that may be discovered are as follows:
- A checking account cannot be created without first establishing a savings account.
- A savings account balance cannot ever go below $10.
- A savings account withdrawal request would be denied if the balance after the withdrawal was less than $10.
Those domain details would be incorporated into the remaining design of the software system. They would also drive how the system behaves and the responsibilities managed by each object produced.
Responsibility Driven Development
Responsibility Driven Development (RDD) is the process of designing software by developing objects based on their roles and responsibilities in the system. During the design phase of a system, candidate objects are identified by the concepts mentioned repeatedly. Most often, those candidate objects will be passive. Responsibilities are defined by making the candidate objects active. [1]
- Loose or low coupling
- High cohesion
- Flexible applications that are easily changed when requirements change [2]
- Intelligent objects that do more than hold data [2]
- Code reuse is not as prevalent since roles and responsibilities are not typically shared among applications. In contrast, some of the collaboration objects may be readily reused.
Once again, we will use the example of the banking system. This time, let’s look at the process of a withdrawal request. During the design phase of the software lifecycle, the development team would find candidate objects used to implement a role within the banking application. One such role would be a withdrawal procedure which could be implemented by the candidate object WithdrawalProcedure. CRC (Class, Responsibility, Collaboration) cards are used to describe each of the candidates. There are a few different ways those cards could be structured. One way is to place the name of the candidate object at the top of the card with a list of responsibilities on the left and a list of collaboration objects on the right.
Once all candidates have been established, the code can be written to implement each candidate.
public class WithdrawalProcedure {
private BankAccount account; . . . public WithdrawalProcedure(BankAccount inAccount) { account = inAccount; } . . . public void start(Transaction transaction) { account.process(transaction); } . . .
}
So now what?
Now that we have supplied an overview of each of the methodologies, we need to look at when it is appropriate to use them. Test Driven Development can and should be used in combination with all of other the methodologies mentioned above. It is a solid way of creating a software system that can be trusted once it is released into a production environment. Domain Driven Development can also be used in combination with all of the other methodologies. It is always beneficial to thoroughly understand the domain for a given system and then allow those details to drive the way that objects are defined whether that is focused on behavior, models, or responsibilities. However, Domain Driven Development is not necessarily a good fit when a given system does not contain complex business logic. The remaining methodologies do not necessarily have a given situation in which one should be used in place of another. The only methodology that has a situation that would make it less attractive to use is Model Driven Development. Since MDD is focused on creating models that the end-user or business expert fully understands, it may not be useful to use Model Driven Development for projects where the business expert is not interested in being an intricate part of the development cycle. Those situations are rare, but they do exist.
Links
- Responsibility Driven Design with Mock Objects
- A Brief Tour of RDD
- Wikipedia – Behavior Driven Development
- Beyond Test Driven Development – Behaviour Driven Development
- Behavior Driven Development
- Wikipedia - Test Driven Development
- Jimmy Nillson on Domain Driven Design
- Eric Evans on the State of DDD
- Wikipedia – Model Driven Development