Transactions


The COMMAND pattern has another common use, one we will find useful in the payroll problem: the creation and execution of transactions. Imagine, for example, that we are writing the software that maintains a database of employees (see Figure 21-4). Users can apply a number of operations to that database, such as adding new employees, deleting old employees, or changing the attributes of existing employees.

Figure 21-4. Employee database


A user who decides to add a new employee must specify all the information needed to successfully create the employee record. Before acting on that information, the system needs to verify that the information is syntactically and semantically correct. The COMMAND pattern can help with this job. The command object acts as a respository for the unvalidated data, implements the validation methods, and implements the methods that finally execute the transaction.

For example, consider Figure 21-5. The AddEmployeeTransaction contains the same data fields that Employee contains, as well as a pointer to a PayClassification object. These fields and object are created from the data that the user specifies when directing the system to add a new employee.

Figure 21-5. AddEmployee transaction


The Validate method looks over all the data and makes sure that it makes sense. It checks it for syntactic and semantic correctness. It may even check to ensure that the data in the transaction is consistent with the existing state of the database. For example, it might ensure that no such employee already exists.

The Execute method uses the validated data to update the database. In our simple example, a new Employee object would be created and loaded with the fields from the AddEmployeeTransaction object. The PayClassification object would be moved or copied into the Employee.

Physical and Temporal Decoupling

The benefit this give us is in the dramatic decoupling of the code that procures the data from the user, the code that validates and operates on that data, and the business objects themselves. For example, one might expect the data for adding a new employee to be procured from a dialog box in a GUI. It would be a shame if the GUI code contained the validation and execution algorithms for the transaction. Such a coupling would prevent that validation and execution code from being used with other interfaces. By separating the validation and execution code into the AddEmployeeTransaction class, we have physically decoupled that code from the procurement interface. What's more, we've separated the code that knows how to manipulate the logistics of the database from the business entities themselves.

Temporal Decoupling

We have also decoupled the validation and execution code in a different way. Once the data has been procured, there is no reason why the validation and execution methods must be called immediately. The transaction objects can be held in a list and validated and executed much later.

Suppose that we have a database that must remain unchanged during the day. Changes may be applied only during the hours between midnight and 1 A.M. It would be a shame to have to wait until midnight and then have to rush to type all the commands in before 1 A.M. It would be much more convenient to type in all the commands, have them validated on the spot, and then executed later, at midnight. The COMMAND pattern gives us this ability.




Agile Principles, Patterns, and Practices in C#
Agile Principles, Patterns, and Practices in C#
ISBN: 0131857258
EAN: 2147483647
Year: 2006
Pages: 272

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net