[ fromfile: antipatterns.xml id: antipatterns ]
AntiPattern is a term first coined by [Koenig95] to describe a commonly used programming practice that has proved to be ineffective, inefficient, or otherwise counterproductive. Several antiPatterns arose as solutions to recurring problems and have been picked up and passed on by students and other inexperienced programmers. There is an informative and evolving article on this subject in Wikipedia that organizes and briefly describes a substantial number of antiPatterns. Discussing examples of antiPatterns may help programmers avoid such pitfalls. Following is a small selection of named antiPatterns from the Wikipedia article.
Software design antiPatterns
Input kludge: Failing to specify and implement the handling of possibly invalid input.
Interface bloat: Making an interface so powerful and complicated that is hard to reuse or implement.
Race hazard: Failing to see the consequence of different orders of events.
Object-oriented design antiPatterns
Circular dependency: Introducing unnecessary direct or indirect mutual dependencies between objects or software modules.
God Object: An object that has too much information or too much responsibility. This can be the result of having too many functions in a single class. It can arise from many situations, but often happens when code for a model and view are combined in the same class.
Programming antiPatterns
Hard coding: Embedding assumptions about the environment of a system in its implementation.
Magic numbers: Including unexplained numbers in algorithms.
Magic strings: Including literal strings in code, for comparisons, as event types etc.
Methodological antiPatterns
Copy and paste programming: Copying and modifying existing code without creating more generic solutions.
Reinventing the (square) wheel: Failing to adopt an existing, adequate solution and, instead, adopting a custom solution (which performs much worse than the existing one).
In Figure 7.3, Customer
includes member functions for importing and exporting its individual data members in XML format.
getWidget()
provides a special GUI widget that the user can use to enter data from a graphical application.
In addition, there are friend functions for input/output via iostream
.[60]
This class is a model because it holds onto data and represents some abstract entity.
However, this class also contains view code because of the createWidget()
and getWidget()
member functions.
In addition, it contains serialization code specific to particular I/O streams.[61]
That is too much responsibility for a data model.
This is an example of the Interface Bloat antiPattern (and perhaps a few others also).
The problems that interface bloat can lead to become immediately apparent when you implement other data model classes such as Address
, ShoppingCart
, Catalog
, CatalogItem
, etc.
Each of them would also need these methods:
createWidget()
importXML()
exportXML()
operator<<()
operator>>()
This could lead to the use of Copy-and-Paste programming, another antiPattern.
If you ever change the data structure, corresponding changes would need to be made to all presentation and I/O methods.
Bugs are likely to be introduced when maintaining this code.
If Customer
were reflective, meaning that it had the ability to determine useful things about its own members (e.g., How many properties? What are their names? What are their types? How can they be loaded/stored? What are the child objects?), then you could define a generic way to read and write objects that would work for Customer
and any other similarly reflective class.
Chapter 12 discusses an example that shows how to write more general-purpose code with reflection.
[60] Friends are discussed in Section 2.6.
[61] Serialization is the process of converting an object's data to a form that permits the data to be stored in a file or transmitted across a network so that it can later be used to reconstruct the object. Section 7.4.1 discusses the Serializer Pattern.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |