1. Implementing business objects. Classes that encapsulate business rules are the basis of true object-oriented programming. In this article, we will cover all aspects of programming and question some of our usual ways of writing Delphi programs. The basic concept behind these design methods is encapsulation: designing a set of classes with clearly defined interfaces (methods) that have methods to operate on their properties. This concept will be used throughout the entire program and has a strong impact on how data is saved and presented. I would like to introduce readers to Francis Glassborow's article on C++. Although the languages are different, excellent class design concepts are independent of language. Most programs written in Delphi today are not object-oriented. Just because there is an object model in the language and uses original or new classes, this does not mean that the program is truly object-oriented. Code reuse ends when third-party controls are dragged onto windows, but interdependencies between windows and units proliferate rapidly. (!!!) If you want to change the basis of the program in the future (such as switching to a different database or going from a two-tier structure to a three-tier structure) it will be seriously hindered or expensive. If the program is truly written in an object-oriented manner, it will be very convenient rather than restrictive. Of course, writing such a program requires improvement of concepts, and there is a lack of productivity at the beginning. Most development teams are unwilling to do this or consider it. I hope that through this article I will show you how to write better programs. The result is a system that is more reliable, easy to maintain, consistent in style, flexible, reusable, and runs better than programs written in traditional ways. Especially for large programs, programs whose code is clear and truly object-oriented will require fewer maintenance resources than the same program written in a traditional way. The greater reliability of object-oriented programs comes from the fact that data and operations are encapsulated in well-defined classes. The compiler enforces the correct classes, methods, and properties in the code through powerful type checking, and there should be no possibility of misunderstanding the intent of the code if a future change affects the entire program. When classes are used correctly, the relationships between them are self-evident, and most of the code is really focused on the meat of the program, rather than thinking about details like how data is persisted. Simplicity and consistency throughout the code will significantly improve the maintainability of the program. As we will see, extensive use of class inheritance increases productivity and reliability, and enhances consistency. These consistencies are reflected in the code shown, including the behavior of the classes, how data is stored, and how the user interface presents the data. Since most of the functionality is provided in the base classes, you can fundamentally change your program by quickly changing their behavior. (For example, the user interaction interface is changed from a window-driven form to based on HTML) These base classes can be designed to be independent of the program, so that a second similar program will immediately get a boost in productivity. A good set of base classes can provide a significant improvement of up to 50% for a modest program in terms of time, expense, and reliability. The first thing to emphasize is that switching to true object-oriented development is not a trivial matter. For the first time, you should ensure that you have experienced assistance, or the program is small and there is no urgent delivery deadline; it should also be noted that an object-oriented (OO) The solution is not to dictate which classes should be used and which classes should not be used in the program. If a company develops its own visual controls, or uses third-party visual controls, core classes. The first step in designing any object-oriented program is to consider which classes are necessary. This is an absolutely fundamental step, subject to the technical guarantees of various other developments, since mistakes in the early stages will be expensive to correct. When designing our classes, we generally strive to achieve low coupling and high cohesion - classes are as independent as possible, but can be combined in some powerful way. One way to achieve this goal is to divide classes into different categories according to the different roles they play in their programs. Correct selection of these roles will result in a cohesive set of classes. There is a consistent basic principle in the design of the role of classes: dividing the responsibilities of the class into presentation, application and persistent storage of data (typically in a database). Although this is the same as the partitioning of three-tier database programs, it is important to note that this partitioning concept can be implemented in a variety of environments: from single-chip programs to distributed multi-tier programs. The group of classes that make up the application logic is responsible for the most difficult work, such as responding to requests for user actions and processing data. Some classes in this layer represent real-world entities and are modeled by the system. These classes are often called "business classes" or "problem domain classes". They form a vital part of any object-oriented program, and because other classes will support these classes in some way, they become the focus of all developers. Identifying which business objects are present in a particular program is generally a matter of experience and instinct, although there is an entire discipline (or art?) to this process. The advantages of object orientation over traditional techniques such as SSADM(1) are present throughout the analysis, design and The process of maintaining entities: Each business object can be represented through object-oriented analysis (OOA), object-oriented design (OOD), and object-oriented programming (OOP). We will explore some techniques for identifying suitable business targets later. First we assume that the following processes have been completed. The intercommunication of classes between different layers (presentation, application and persistence) is clearly defined and interconnected. The relationship between these classes is shown in Figure 1. The arrows in the figure show that classes in the same layer can call methods in another class. This picture also shows that the classes of the presentation layer (user interface) can operate the application layer or other classes in the user interface. The application layer (business objects) can operate the classes of the application layer and call the methods of the persistence layer. The persistence layer only responds to the application layer. request. Business Objects To demonstrate how business objects are implemented, we will next see a simplified program with inventory, customer, and order entities (a company provides a certain amount of goods, and customers buy these goods). Our initial analysis determined that three business objects were required to represent these entities. There will be three classes in our Delphi program: TStockItem, TCustomer and Torder. The public interfaces of these classes are shown in Listing 1. It should be pointed out here that the characteristics of these classes are exposed to the outside through properties (PRoperty): this is a simple and beneficial class design and controls external access through properties. Also, these properties should be in the published area of the class (for reasons that will be mentioned later) and be assigned appropriate default values. Although these property qualifications are only used when streaming classes, they give each property an appropriate initial value and make the code more self-describing. First Class Framework In the initial stages of developing the program, we have identified and implemented three business objects. These three objects play a common role: representing real-world entities in some way. Therefore we want them to have similar properties and appropriate levels to real-world entities. We will give each object a common base class called TPDObject (Problem Domain object). Over time we will add public methods and properties to this class, and TPDObject will continue to be extended. It should be noted that TPDObject should not (never) have any elements related to a specific application. As a program-independent class it is placed in an independent unit and forms the basis of the framework: a set of classes that can be reused in many programs. In the future, our framework will be greatly expanded to form base classes that provide important program-independent functions and can be quickly used in specific systems. Our TStockItem, TCustomer and Torder are customized objects for specific systems from TPDObject. TMyAppPDObject is an inherited class of TPDObject. Although its implementation part is empty, it is a good demonstration; if we add certain elements to a specific program and affect all problem domain classes in the program, like this The class hierarchy should be more appropriate. The initial code for the framework is listed in the listing. Class TPDObject also only provides a read-only attribute ID, its type is TobjectID. This attribute gives each object an identifier: we will consider two instances of the same type and ID to be the same object. Here the ID is intentionally declared as its own type to avoid being directly assigned to a value of another standard type. The type of TobjectID was not specifically chosen: here I chose integer, which may also be a specialized class in certain cases. Although using classes as IDs seems to be a more pure object-oriented approach, based on the fact that classes in our problem domain will be created and released thousands of times during the running of the program, in order to avoid the extra load when creating and releasing objects, I did not do this. (As a purist I include TobjectID in TPDObject as a composite object). In the code there are a pair of functions that convert strings to our object identification types, and a constant that serves as the initial value when no assignment is made. There are many classes where object identification is mentioned: some say that all business objects should be given an identification (even a GUID) that is not repeated within the program when they are created. In fact, being able to distinguish between different objects in a given context is what is really important, and keeping this simple will have obvious performance and storage space benefits. Questions about specifications: In order to strengthen some design concepts and practices when designing class frameworks, I will ask some questions and ask readers to think about the basic principles behind them. I mentioned that true object-oriented design does not prohibit the use of specific classes, but there is one important exception. What is this exception (the answer is in Figure 1) ((( Listing 1 - An application-specific Problem Domain unit (abridged) )))unit ProblemDomain;interfaceuses Framework;type TMyAppPDObject = class (TPDObject) end; TStockItem = class (TMyAppPDObject ) published property Name: String; property QuantityInStock: Cardinal default 0; property TradePrice: Currency; property RetailPrice: Currency; end; TCustomer = class (TMyAppPDObject) … ; TOrder = class (TMyAppPDObject) … ;implementationend.((( End Listing 1 )))((( Listing 2 - An application-independent Framework unit )))unit Framework;interfaceconst NotAssigned = 0; type TObjectID = type Integer; TPDObject = class private FID: TObjectID; public property ID: TObjectID read FID default NotAssigned; end;function StrToID (Value: String): TObjectID;function IDToStr (Value: TObjectID): String;implementation…end.((( End Listing 2 )))(1) SSADM (Structured Systems Analysis & Systems Design) was established in 1981 The British Government's Central Computer and Telecommunications Agency (CCTA); website: http://www.ccta.gov.uk ) developed software analysis and design standard methods. Philip Brown is a systems design consultant and active developer, presenter, and trainer. He'll promote the benefits of strong OO techniques to deliver better applications given any opportunity. You can contact him at [email protected].