|
|
|
Can Good Object-Oriented Design include Data-Aware Controls?The following discusses components used in development with Delphi and C++Builder, but the principles discussed apply in general to the use of data-aware controls as provided in any development environment. There have been many discussions about whether it is permissible or advisable to use data-aware controls in a properly designed object-oriented project. Many argue they must not be used, that they violate various principles of OO design and are a practical source of problems as a result. Many seem to think that data-aware controls directly access the database in some way and thus can bypass business logic. This would be a serious flaw and would indeed invalidate their use in a good OO design. But this has never been true, data-aware controls have no power, on their own, to do such a thing. Data-aware controls are actually very passive and simply inform their (built-in) datalink class when something happens. It is the datalink class that transports the data back and forth between the actual controls and the data source. The datalink class performs the role that must be performed in any case and it is primarily the logic in this class that must be re-invented by those who reject the use of data-aware controls. Moving data between controls and a data source in no way compromises an OO design because data sources (i.e. TDatasource) do not directly connect to a database and have absolutely no knowledge of the ultimate source or destination of the data that passes through them. Their only role is to provide a single point of connection for any number of individual data-aware controls. That single point of connection is to any descendant of the TDataset class. All the classes to this point are actually very well thought-out designs and, far from violating OO principles, they very much uphold those principles in terms of abstraction and data hiding, low coupling and cohesion (that their design could be even better given newer language features such as interfaces does not invalidate the positive aspects of their original design). This leads us to one last level, the TDataset class. This is the class that actually talks to a database. Well actually TDataset itself does not, but it is designed with this capability in mind so that descendant classes can be developed that actually talk to specific databases. TQuery and TTable are TDataset descendants that talk to the Borland Database Engine. TIBDataset is a TDataset descendant designed to talk directly to the Interbase API. Thus it is only at this level where we reach a point of physical connection with a database. On its own, TDataset is still not a problem; it is also a well-designed and very powerful abstraction and ultimately lies at the base of even those OO designs that forbid the use of data-aware controls. After all, not too many would wish to re-invent the functionality and abstraction provided by the TDataset class, and there is no need to. Where then is the problem?There is indeed a problem, but the problem does not lie at any one single level among the classes discussed above. The blame heaped upon the poor, misunderstood data-aware controls is terribly misplaced. The problem lies in the routing of data. The argument that data-aware controls have any direct coupling or dependency on the database those controls are reflecting only has validity when they are, via their data source, hooked up to a dataset that is connected to an actual database. Even then any blame put on the data-aware controls is misplaced since their nature and behavior does not change, but only the route data takes to get to them and to get back to the database. The exact issue is this: If data can move between data-aware controls and a database without part of their route being directly through a set of business objects that have full control over the data being moved, then the design, no matter how good otherwise, can rightly be considered compromised. Unless the business objects are inherently part of the conduit, then it is possible to get around them. So what is the solution?First and foremost, sacrificing data-aware controls is not it. This is treating the symptoms instead of the disease. It can be argued that, because all the classes discussed, especially TDataset, provide ample events and properties, business classes can adequately enforce control over the data through these means. For some projects this may be enough and thus justifiable. But this solution requires the business classes to operate on the terms provided by the existing TDataset, et al, classes. They, in a sense, sit on the side and exert control as best they can as the data flows by them. Ideally, it is the business classes that set the terms and the other classes are subject to them. The obvious way to achieve this is for the business classes to hide datasets behind their abstraction. By doing this it is not possible for data-aware controls, and potentially presentation layer (GUI) logic, to make an end-run around the business logic (by having their data sources hooked directly to those datasets). The presentation layer’s only source of data becomes the business classes themselves thus making the business classes a central pillar of the design. If datasets are hidden from the view of data sources, then it seems data-aware controls must be sacrificed!There are three solutions to this I will discuss:
SummaryExisting data-aware controls are perfectly compatible with well-designed object-oriented systems. The scorn placed on them by many has been misplaced; the real problem is the routing of data; data-aware controls hooked to datasets that have actual database connections is the problem since this allows data to flow around business logic instead of through it. But it is a problem solved easily by making your business classes responsible for creating the datasets seen by the presentation layer.
By: Wayne Niddery of Logic Fundamentals Inc.www.logicfundamentals.com |