Object Model: why is it needed and how to describe it. Object Data Models


"I talked about how I divide a design document into Object Model And Functional Specification. I received quite a lot of questions, including the question of why I do such a division, as well as what difference between OM and Functional Specification, why not combine these two parts? I started to answer, but in the process I realized that, in fact, I began to write a separate article. If so, then I’d better write it here.

Why do we need an Object Model (OM)

Briefly - so that the project does not have this:

Don't get me wrong. I love pasta, but only as a meal.

Usually programmers like to write and talk about pasta. But it can also be in design, and how. It is extremely difficult to work with a pasty design document, and even searching by keywords does not always help. And even cross-references (in those rare cases when they are placed) do not always help, and sometimes get confusing.

Therefore, the Object Model does two important functions:

  1. Directory of game entities. Any team member can view it without delving into the jungle of design documentation and long searches in a convenient alphabetical order;
  2. Parameter inheritance structure. This is already for pros, who write not just a design document, but also form the architecture of a future project.

Now more about each of these points.

Directory

The directory allows you to separate an entity and its parameters from its functionality. This makes it possible to quickly, at a glance, understand how and what it consists of, how it is stored in the database, how it works in the game logic, and so on. This simple perception of entities allows programmers to easily understand the future architecture of the project and design how it will be created even before they start implementing it in code. Such a clear understanding can save you from rework in the future, when after a year or a year and a half it suddenly turns out that everything is not working correctly, there is not enough flexibility, it is not provided for, or it will even require a complete refactoring of 75% of the code. Of course, the OM handbook is not a magic pill, but it works great as a way to minimize such risks, provided that it is compiled correctly).

Additionally, the Directory allows game entities to be sorted by their types, while the Functional Specification sorts or describes them by functionality. For example, we have this hierarchy in OM:

  • Igor's essence
    • Item
      • Weapon
        • Sword
      • Consumables
        • Bottle

But when describing gameplay, we may have a completely different structure. For example:

  • Combat system
    • Damage calculation
    • Armor work
    • Bottles during the fight
    • Weapon
    • Steel arms
  • Craft
    • Craft bottles
    • Crafting weapons
      • Strelkovoy
      • Cold

That is, it turns out that when describing the FS, we either tell in each article what types of bottles there are, or we make a link to the description of the required entity. If this description lies somewhere in the Functional Specification and is part of, for example, a combat system - and we are describing crafting, then this is what will lead to the pasty design of the design. In most cases, such a design will lead to the same architecture (or lack thereof).

AND reverse example, if we have the entire design document sorted according to a hierarchical system of entities: when describing the combat system, it will be smeared throughout the design document.

Inheritance (pro feature)

Drawing up a design document using inheritance can make life much easier for programmers (those who use it when creating the game architecture). In addition, it brings clarity to the design documentation itself and eliminates overload with unnecessary details.

  • Game Entity
    • Item (InventoryItem)
      • Clothes (Equipment)
        • Armor

Below is how they look in the documentation (of course, in abbreviated form, 3-4 lines from OM):

Members of the GameEntity type (this is the top, most important entity in the project architecture and how it is stored in the database)
Members of the InventoryItem type
Equipment type members
Members of the Armor type

As you can see, Armor is the last entity in the example above, and has only three parameters: ArmorType, DamageReduxF, DamageReduxP. However, it inherits from the previous entity: DurabilityMax, DurabilityCurrent, Tiemype. In turn, that entity inherits: Volume, PlayMoneyPrice, realMoneyPrice, and so on until the very top.

Thus, using inheritance in the OM structure, we get rid of unnecessary work - we do not need to re-register all its parameters for each entity. We will not miss anything important and reduce the likelihood possible errors or discrepancies.

Moreover, by adding some new parameter into the upper entity, we will influence all its subentities. This greatly simplifies the work if there are, for example, a hundred subentities.

I think it’s obvious how much easier it is for programmers to understand the structure and architecture of the game.

Object-oriented analysis and design with example applications in C++ Butch Gradi

Chapter 2 Object Model

Chapter 2 Object Model

Object-oriented technology is based on the so-called object model. Its main principles are: abstraction, encapsulation, modularity, hierarchy, typing, parallelism and persistence. Each of these principles in itself is not new, but in the object model they are applied together for the first time.

Object-oriented analysis and design are fundamentally different from traditional structural design approaches: here you need to think differently about the decomposition process, and the architecture of the resulting software product largely goes beyond the concepts traditional for structured programming. The differences are due to the fact that structured design is based on structured programming, while object-oriented design is based on the methodology of object-oriented programming. Unfortunately, the term "object-oriented programming" means different things to different people. Wrench correctly predicted: “In the 1980s, object-oriented programming will occupy the same place as structured programming did in the 1970s, but everyone will like it. Every company will advertise its product as being built on this technology. All programmers will write in this style, and everyone is different. All managers will talk about it. And no one will know what it is "]. These predictions continue to come true in the 1990s.

In this chapter, we'll explore what object-oriented software development is and isn't, and how this design approach differs from others based on the seven elements of the object model listed above.

From the book Homemade and office networks under Vista and XP author Vatamanyuk Alexander Ivanovich

Chapter 5 Network interaction model and basic network protocols If you have been consistent, you have already become familiar with the basic types and topologies of networks, as well as network standards. Like any other area of ​​human life and work, all actions are

From the book ArchiCAD 11 author Dneprov Alexander G

Object Snapping Before you start looking at editing commands, pay attention to a tool that is absolutely necessary for skilled work - object snapping. Its purpose is to bind the characteristic points of the moving object to

From the ArchiCAD book. Let's start! author Orlov Andrey Alexandrovich

Object snapping Before looking at editing commands, let's pay attention to a tool that is absolutely necessary for skilled work - object snapping. Its purpose is to bind the characteristic points of the moving object to

From the book Database Processing in Visual Basic®.NET author McManus Geoffrey P

CHAPTER 4 ADO.NET Model: Data Providers Sometimes it seems that database application developers have not yet gotten used to new technology as Microsoft has proposed completely new model access to databases. This chapter focuses on the ADO.NET model,

From the book AutoCAD 2010 author Orlov Andrey Alexandrovich

Object snapping Methods for specifying point coordinates using the keyboard are not the only ones. It is usually much more convenient to specify points if you know how new objects should be located relative to existing ones. For example, if you know that the segment being created

From the book Practice and Problems of Business Process Modeling author of All sorts of E I

From the book The JavaScript Reference author Team of authors

Document Object Model It should be noted that JavaScript supports so-called external classes and objects defined by other programs. The Web page that you view in a Web browser window can be described as a collection of objects. Let's say it turns on a big one

From the book HTML 5, CSS 3 and Web 2.0. Development of modern Web sites. author Dronov Vladimir

From the book HTML 5, CSS 3 and Web 2.0. Development of modern Web sites author Dronov Vladimir

Web browser objects. Document object model DOM Objects provided by the Web browser are divided into two groups: - objects representing the Web page and elements created using various tags (paragraph, heading, table, image, etc.); - objects

From the book XSLT Technology author Valikov Alexey Nikolaevich

Chapter 3. The idea and model of the XSLT language The third chapter is devoted to the models that are used in the XSLT language. It covers the tree model of an XML document, the data model used in XSLT and XPath, variables, expressions, and a model of the transformation process itself. Can

From the book Application Development in the Linux Environment. Second edition author Johnson Michael K.

Chapter 3 The idea and model of the XSLT language

From the book VBA for Dummies by Steve Cummings

Chapter 10 Process Model The process model is one of the "trademarks" of Unix. This is the key to understanding access rights, the relationships between open files, signals, job control, and most of the other low-level concepts covered in this book. Linux adapts more

From the book How to make money on photography on the Internet author Zyomko Olga

What is an object model? As already mentioned, VBA objects exist in hierarchical dependence on one another. In addition to having their own properties, methods, and events, objects at higher levels of the hierarchy serve as containers for one or the whole

From the book Programming in Java author Vyazovik Nikolay Alexandrovich

Chapter 8 Model and Shooting Props Once you have an idea of ​​what equipment you will need to use during the shooting process, you can begin to consider what exactly is involved. this process should be checked. Since you are

From the book HTML, XHTML and CSS 100% author Kvint Igor

8. Lecture: Object model in Java This lecture is a slight deviation from the consideration of the technical features of Java and is mainly devoted to the study of key properties of the Java object model, such as static elements, abstract methods and classes, interfaces,

From the author's book

10.4. Document Object Model (DOM) The standard set of objects in an HTML document, their properties and how to access them are determined by the Document Object Model (Document Object Model, abbreviated as DOM). DOM allows you to manage all elements on a web page, change their properties and

The object model of the system describes the structure of the objects that make up the system, their properties, operations and relationships with other objects.

The object model should reflect those concepts and objects of the real world that are important for the system being developed. It reflects, first of all, the pragmatics of the system being developed. Pragmatics is expressed in the use of terminology application area related to the use of the system being developed.

Object is a concept, abstraction, or any other thing with clearly defined boundaries that makes sense in the context of the applied problem being considered. Examples of objects: window, central bank, school No. 42, Petr Sidorov, case No. 7461, savings book, etc.

Introducing objects has two purposes:

Understanding of the applied problem (problem);

Introduction of the basis for its implementation on a computer.

The purpose of developing an object model is to identify and describe the objects that collectively make up the designed system, as well as to identify and indicate various dependencies between objects. This process represents the decomposition of a system (problem) into objects - a creative process and poorly formalized.

All objects of the system can have their own properties that characterize them, which distinguish one object from another. For example, the object “apple” can be characterized by color, shape, weight, taste, etc. A relation of identity can be established between objects. Then two objects satisfying this relation are considered the same (identical) and belong to the same class.

All objects of the same class are characterized by the same sets of properties (attributes). However, the grouping of objects into classes is determined not by sets of properties, but by semantics. So, for example, the objects “Stable” and “Horse” can have the same attributes: “Price” and “Age”. Moreover, they can belong to the same class, if they are considered in the problem simply as a product, or to different classes, which is more natural.

Combining objects into classes allows you to introduce abstraction into the problem and consider it in a more general formulation. A class has a name (for example, horse) that refers to all objects of that class. In addition, the class contains the names of attributes (properties) that are defined for objects. In this sense, the description of a class is similar to the description of a structure (record) type. Moreover, each object has the same meaning as an instance of the structure (variable or constant of the corresponding type).

Example of the ACCOUNT class

It should be recalled that this stage of system design does not imply the use of any object-oriented programming language. This, in particular, is expressed in the fact that at this stage only those properties of objects that make sense in reality should be considered.

The properties of objects are related to the features of the overall implementation of the project. For example, if you know that you will use a database in which each object has a unique identifier, then include this identifier among the object's attributes on at this stage do not do it. The fact is that by introducing such properties, we limit the possibilities of implementing the system. Thus, by introducing a unique identifier of an object in the database as an attribute, at the very beginning of design we refuse to use DBMSs that do not support such an identifier.

You can perform some operations on an object. For example, “Check”, “Withdraw”, “Place” for objects of the “Account” class or “Open”, “Read”, “Close” for objects of the “File” class, etc.

Operation - is a function (or transformation) that can be applied to an object. All objects of the same class use the same instance of each operation (that is, increasing the number of objects of a certain class does not lead to an increase in the amount of loaded program code).

The same operation can, generally speaking, be applied to objects of different classes. This operation is called polymorphic because it can take different forms for different classes. For example, for objects of the vector and complex number classes, you can define the + operation; this operation will be polymorphic, since the addition of vectors and the addition of complex numbers are essentially different operations.

Each operation corresponds method - implementation of this operation for objects of this class. Thus, an operation is a specification of a method, a method is an implementation of an operation. For example, in the file class the operation “Print” (print) can be defined. This operation can be implemented by different methods: (a) “Print binary file”, (b) “Print text file", etc. Logically, these methods perform the same operation, although they are implemented by different code fragments.

Each operation always has one implicit argument - the object to which it is applied. In addition, the operation can have other arguments - properties (parameters). These additional arguments characterize the operation and are in no way related to the choice of method.

A method is associated only with a class and an object. (Some object-oriented languages, such as C++, allow the same operation with a different number of arguments, and by using one or another number of arguments, we practically select one of the methods associated with such an operation. At the stage of preliminary design of the system, it is more convenient to consider these operations are different, giving them different names so as not to complicate the design).

The values ​​of some properties of an object can only be accessed by operations on that object. Such properties are called private.

So, to specify a class of objects, you need to specify the name of this class, and then list its properties and operations (or methods).

Data dependencies can be established between objects. These dependencies express connections or relationships between classes of specified objects.

Dependencies between classes are two-way: all classes in the dependency have equal rights. This is true even in cases where the name of the dependency seems to introduce direction into this dependency. Such misunderstandings can be avoided if dependencies are identified not by names, but by the names of the roles of the classes that make up the dependency.

In programming languages, dependencies between classes (objects) are usually implemented using references (pointers) from one class (object) to another. Representing dependencies using references reveals the fact that a dependency is a property of a pair of classes, and not just one of them, i.e. Addiction is a relationship. Note that although dependencies between objects are bidirectional, they do not need to be implemented as bidirectional in programs. You should leave links only in those classes where it is necessary for the program. When designing a system, it is more convenient to operate not with objects, but with classes.

Dependencies, like classes, can have their own properties. For example, when organizing user access to a file, “Access Permission” is a property of the “Available” dependency. Note that access permission is associated with both the user and the file, and cannot be an attribute of either the user or the file individually.

Sometimes dependencies that have many properties are represented using classes. In databases, such dependencies are represented by temporary tables, organized while working with the database.

Generalization And inheritance allow us to identify analogies that determine the multi-level classification of objects. Thus, in graphic systems there may be classes that determine the depiction of various geometric shapes: points, lines (straight lines, circular arcs and curves defined by splines), polygons, circles, etc.

Generalization, for example, allows us to select the class “One-dimensional figures” and consider the classes “Straight”, “Arc” and “Spline” to be subclasses of the class “One-dimensional figures”, and the class “One-dimensional figures” to be a superclass of the classes “Straight”, “Arc” and “ Spline". If we accept the agreement that the properties (attributes) and operations of the superclass are valid in each of its subclasses (they say that these properties and operations are inherited by subclasses), then the same properties and operations of the classes “Straight”, “Arc” and “Spline” ( subclasses) can be placed in the “One-dimensional figures” class (superclass).

It is easy to see that the relationships “Subclass - superclass” (generalization) and “Superclass - subclass” (inheritance) are transitive. In this case, the properties and operations of each superclass are inherited by its subclasses of all levels (the same operations are taken out of brackets, as it were). This greatly simplifies and shortens the description of classes.

It is advisable to adhere to the following rules of inheritance:

Operations that use property values ​​but do not change them must be inherited by all subclasses;

All operations that change property values ​​must be inherited in all their extensions;

All operations that change the values ​​of bounded properties or properties that define dependencies must block in all their extensions (for example, the X-dimension operation is natural for the ellipse class, but must block in its circle subclass);

Inherited operations can be refined by adding additional actions.

By following these rules, which, unfortunately, are rarely supported by object-oriented programming languages, you can make the program you are developing more understandable, easier to modify, and less susceptible to influence. various errors and oversights.

Multiple inheritance allows a class to have more than one superclass, inheriting the properties (attributes and operations) of all its superclasses. A class that has multiple superclasses is called a union class.

In object-oriented design, each object can be considered a variable or constant of a structural type. Therefore, a set of objects can be considered as a set of interrelated data, i.e. something very similar to a database. Therefore, the application of database concepts is often useful in object-oriented analysis and object-oriented design of application software systems.

The object-oriented approach is based on a set of principles called the object model. The main principles are

  • - abstraction;
  • - encapsulation;
  • - modularity;
  • - hierarchy.

These principles are the main ones in the sense that without them the model will not be object-oriented. In addition to the main ones, we will name three additional principles:

  • - typing;
  • - parallelism;
  • - preservation.

By calling them optional, we mean that they are useful in the object model, but not required.

Abstraction

Humans have developed extremely effective technology for coping with complexity. We abstract ourselves from it. If we are unable to completely recreate complex object, then you have to ignore not very important details. As a result, we are dealing with a generalized, idealized model of the object.

For example, when studying the process of photosynthesis in plants, we focus on chemical reactions in certain cells of the leaf and do not pay attention to other parts - cuttings, veins, etc.

Abstraction highlights the essential characteristics of some object that distinguish it from all other types of objects, and thus clearly defines its conceptual boundaries from the point of view of the observer.

Abstraction focuses attention on the external features of an object and allows you to separate the most significant behavioral features from the unimportant. This separation of meaning and implementation is called an abstraction barrier. The establishment of one or another barrier to abstraction gives rise to many different abstractions for the same object or phenomenon of the real world. Abstracting to a greater or lesser extent from various aspects manifestations of reality, we are at different levels of abstraction.

For example, consider system unit computer. A user using a computer to type text does not care what parts this block consists of. For him it's a box white with buttons and floppy disk capacity. It abstracts away concepts such as "processor" or " RAM". On the other hand, the programmer, writing program in machine codes, the abstraction barrier is much lower. He needs to know the structure of the processor and the commands understood by it.

Another additional principle is useful, called the principle of least surprise. According to him, an abstraction should cover all the behavior of an object, but no more and no less, and should not introduce surprises or side effects that lie outside its scope.

For example, we need to use a data structure similar to a stack (with access carried out according to the rule "first in, last out"), but we need to check for the presence of some element in the "stack". If we call this data structure a stack and present it to an outside programmer, he will be very surprised to notice an “extra” operation.

All abstractions have both static and dynamic properties. For example, a file as an object requires a certain amount of memory per specific device, has a name and content. These attributes are static properties. The specific meanings of each listed properties are dynamic and change during the use of the object: the file can be enlarged or reduced, its name and contents can be changed.

We will call a client any object that uses the resources of another object, called a server. We will characterize the behavior of an object by the services it provides to other objects and the operations it performs on other objects. This approach focuses on the external manifestations of the object and implements the so-called contract programming model. This model is as follows: external manifestation object is considered from the point of view of its contract with other objects, in accordance with this its internal organization(often - in interaction with other objects). The contract records all obligations that the server object has to the client object. In other words, this contract defines the object's responsibilities—the behavior for which it is responsible.

Each operation provided for by a contract is uniquely determined by its signature - a list of formal parameter types and a return value type. Full set The operations that a client can perform on another object, together with the correct order in which those operations are called, is called a protocol. The protocol reflects everything possible ways, by which an object can act or be affected. Thus, the protocol completely determines the external behavior of the abstraction.

Example. In a hydroponics greenhouse, plants are grown in a nutrient solution without sand, gravel or other soil. Managing the operating mode of a greenhouse installation is a very responsible matter. It depends both on the type of crops grown and on the stage of cultivation. A number of factors need to be controlled: temperature, humidity, lighting, acidity and nutrient concentration. On large farms, to solve this problem they often use automatic systems, which control and regulate these factors. The goal of automation here is to achieve compliance with the cultivation regime with minimal human intervention.

One of the key abstractions in this problem is the sensor. Several types of sensors are known. Everything that affects the yield must be measured. Thus, sensors are needed for water temperature, air temperature, humidity, acidity, lighting and nutrient concentration.

From an external point of view, a temperature sensor is an object that is capable of measuring the temperature where it is located. Temperature is a numerical parameter that has a limited range of values ​​and a certain accuracy and means a number of degrees Celsius.

The location of the sensor is some uniquely defined place in the greenhouse, the temperature in which you need to know. There are probably few such places. For a temperature sensor, it is not the location itself that is important, but only the fact that this sensor is located in this particular place.

Let's look at the elements of implementing our abstraction in C++.

typedef float Temperature; // Temperature in Celsius

typedef unsigned int Location; // A number that uniquely defines

// sensor position

Here, the two type definition operators Temperature and Location introduce convenient aliases for the simplest types, and this allows us to express our abstractions in domain language. Temperature is a floating-point numeric data type for recording temperatures. Location values ​​indicate locations where temperature sensors can be located.

Let's look at the responsibilities of a temperature sensor. The sensor must know the temperature at its location and report it upon request. The client can perform the following actions in relation to the sensor: calibrate the sensor and receive the current temperature value from it. Thus, the "Temperature Sensor" object has two operations: "Calibrate" and "Current temperature".

struct TemperatureSensor (

Temperature curTemperature; // current temperature in

// sensor location

Location loc; // sensor location

void calibrate(Temperature actualTemperature); // calibrate

Temperature currentTemperature(); // current temperature

This description introduces new type TemperatureSensor. The important thing here is that, firstly, the data and the functions that change it are combined together in one description and, secondly, we do not work directly with the data, but change it through the appropriate functions.

Objects of this type are entered in the same way as variables of standard types:

TemperatureSensor TSensors; // array of one hundred objects of type

// TemperatureSensor

Functions declared within a declaration are called member functions. They can only be called on a variable of the appropriate type. For example, you can calibrate the sensor like this:

TSensors. calibrate(0.); // sensor number 3 is calibrated

Because the name of the object on which the member function is called is implicitly passed to it, the function argument lists do not contain an argument of type TemperatureSensor that specifies the specific sensor to operate on. This object can be explicitly accessed within a function using the this pointer. For example, in the body of the calibrate function you can write one of two equivalent operators

this -> curTemperature = actualTemperature;

The central idea of ​​abstraction is the concept of invariant. An invariant is a logical condition whose value (true or false) must be preserved. For each operation of an object, you can specify preconditions (i.e., invariants assumed by the operation) and postconditions (i.e., invariants that the operation satisfies).

Let's look at the invariants associated with the currentTemperature operation. The precondition includes the assumption that the sensor is installed in right place in a greenhouse, and the postcondition is that the sensor returns a temperature value in degrees Celsius.

Changing an invariant violates the contract associated with the abstraction. If the precondition is violated, then the client does not honor its obligations and the server cannot complete the task correctly. If the postcondition is violated, then the server has violated its obligations, and the client can no longer trust it.

To test conditions, the C++ language provides special means in the assert.h library.

If any condition is violated, an exception is raised. Objects can raise exceptions to prevent further execution of an operation and alert other objects to the problem, which in turn can take over to catch the exception and deal with the problem.

C++ has a special exception handling mechanism that is context sensitive. The context for raising an exception is a try block. If an exception occurs when executing statements inside a try block, control is transferred to exception handlers, which are specified by the catch keyword and are located below the try block. Syntactically, a catch handler looks like a function declaration with one argument without specifying the return type. For one try block, several handlers can be specified, differing in the argument type.

An exception is raised by specifying keyword throw with an optional expression argument. The exception will be handled by calling the catch handler whose parameter type matches the type of the throw argument. If there are nested try blocks (for example, due to nesting of function calls), the handler of the deepest block will be used. If a handler matching the type of the throw argument is on this level will not be found, the current function will be exited and searched in a try block with a smaller nesting depth, etc. After the exception is handled, control is transferred to the statement following the catch handler descriptions.

Example. Consider a stack implemented using a fixed-length array.

int stack; // no more than one hundred elements on the stack

int top=-1; // number of available element

void push (int el) (

if(top == 99) throw (1); // check for overflow

else stack[++top] = el; // push the element onto the stack

if(top == -1) throw (0); // check for emptiness

else return stack; // pop an element from the stack

try( // trial block

catch(int error)(. . .) // if error = 0, then the stack is empty;

// if error = 1, then the stack is full

Now we have everything necessary concepts to describe the process of building an object model. This process includes the following steps:

· definition of objects and classes;

· preparation of a data dictionary;

· determination of dependencies between objects;

· determination of object attributes and connections;

· organization and simplification of classes when using inheritance;

· further research and improvement of the model.

2.2.1. Definition of classes. Analysis of external requirements for the designed PS makes it possible to determine objects and classes of objects associated with the applied problem that this system must solve. All classes must be meaningful in the application domain in question; classes associated with computer implementation, such as list, stack, etc. should not be administered at this stage.

You need to start by identifying possible classes from the written statement of the applied problem ( terms of reference and other documentation provided by the customer). It should be borne in mind that this is a very difficult and responsible stage of development, since the future fate of the project largely depends on it.

When identifying possible classes, you should try to identify as many classes as possible, writing down the name of each class that comes to mind. In particular, each noun appearing in the preliminary statement of the problem can have a corresponding class. Therefore, when identifying possible classes, each such noun is usually associated with a possible class.

· redundant classes: if two or more classes express the same information, only one of them should be retained;

· irrelevant(not directly related to the problem) classes: for each possible class name, it is assessed how necessary it is in the future system (this is often very difficult to assess); irrelevant classes are excluded;



· ill-defined(from the problem point of view) classes(see clause 2.3.1);

· attributes: some nouns correspond more to attributes rather than classes; such nouns, as a rule, describe the properties of objects (for example, name, age, weight, address, etc.);

· operations: some nouns are more likely to be operation names rather than classes (e.g. telephone_call is unlikely to denote any class);

· roles: Some nouns define the names of roles in the object model (for example, owner, driver, boss, employee; all of these names are associated with roles in various object dependencies of the person class);

· implementation structures: names more associated with programming and computer hardware should not be compared to classes at this stage, since they do not reflect the features of the designed PS; examples of such names: subroutine, process, algorithm, interrupt, etc.

After eliminating the names of all unnecessary (superfluous) possible classes, a preliminary list of classes that make up the designed system will be obtained.

2.2.2. Preparing the data dictionary. Individual words have too many interpretations. Therefore, it is necessary to prepare at the very beginning of design data dictionary, containing clear and unambiguous definitions of all objects (classes), attributes, operations, roles and other entities considered in the project. Without such a dictionary, discussing the project with fellow developers and system customers is meaningless, since everyone can interpret the terms discussed in their own way. For an example of a dictionary, see paragraph 2.3.2.

2.2.3. Definition of dependencies. At the next stage of building an object model, dependencies between classes are determined. First of all, attributes that are explicit links to other classes are excluded from classes; such attributes are replaced by dependencies. The point of this replacement is that dependencies represent an abstraction at the same level as classes, and therefore do not have a direct impact on future implementation (a reference to a class is just one way to implement dependencies).

In the same way that the names of possible classes were obtained from the nouns found in the preliminary statement of the application problem, the names of possible dependencies can be obtained from verbs or verb phrases appearing in the specified document. This is how they usually describe: physical position (follows_behind, is_part, is_contained), directed action (leads_to_movement), communication (talks_to), belonging (has, is_part), etc. An example of isolating explicit and implicit verb phrases from a preliminary formulation of a specific applied problem is discussed in section 2.3.3.

You should then remove unnecessary or incorrect dependencies using the following criteria:

· dependencies between excluded classes must be excluded or reformulated in terms of the remaining classes (see clause 2.3.3);

· irrelevant dependencies and implementation dependencies must be excluded (see clause 2.3.3);

· actions: the dependency should describe the structural properties of the application domain, and not unimportant events (see clause 2.3.3);

· training dependencies: most of the dependencies between three or more classes can be decomposed into several binary dependencies, using qualifiers if necessary (see section 2.3.3); in some (rare) cases such decomposition cannot be carried out; for example, the trenary dependence “The professor is teaching a course in room 628” cannot be decomposed into binary ones without loss of information;

· derived dependencies: it is necessary to exclude dependencies that can be expressed through other dependencies, since they are redundant (see section 2.3.3); when excluding redundant (derived) dependencies, you need to be especially careful, since not all duplicating dependencies between classes are redundant; in some cases, other dependencies allow us to establish only the existence of another derived dependence, but do not allow us to establish the multiplicity of this dependence; for example, in the case shown in Fig. 2.36, the company has many employees and owns many computers; Each employee is provided with several computers for personal use; in addition, there are computers common use; the dependency multiplicity provided_for_use cannot be inferred from the dependencies serves and owns; Although derived dependencies do not add new information, they are often convenient; in these cases they can be indicated on the diagram by marking them with a slash.

Rice. 2.36. Non-redundant dependencies

Having removed redundant dependencies, you need to clarify the semantics of the remaining dependencies as follows:

· misnamed dependencies: they should be renamed so that their meaning becomes clear (see clause 2.3.3);

· role names: you need to add role names where necessary; the role name describes the role played by the corresponding class in a given dependency from the point of view of another class participating in that dependency; if the role name is clear from the class name, it can be omitted (see section 2.3.3);

· qualifiers: By adding qualifiers where necessary, we introduce elements of context, which allows us to achieve unambiguous identification of objects; qualifiers also make it possible to simplify some dependencies by reducing their multiplicity;

· multiplicity: it is necessary to add designations for the multiplicity of dependencies; It should be remembered that the multiplicity of dependencies may change in the process of further analysis of system requirements;

· unaccounted dependencies must be identified and added to the model.

2.2.4. Attribute clarification. At the next stage, the attribute system is clarified: class attributes are adjusted, new attributes are introduced, if necessary. Attributes express the properties of objects of the class in question, or determine their current state.

Attributes usually correspond to nouns; for example, car_color (object property), cursor_position (object state). Attributes, as a rule, have little effect on the structure of the object model.

You should not try to define as many attributes as possible: a large number of attributes complicates the model and makes it difficult to understand the problem. It is necessary to enter only those attributes that are relevant to the designed application system, omitting random, unimportant and derived attributes.

Along with object attributes, it is also necessary to enter attributes of dependencies between classes (relationships between objects).

When specifying attributes, they are guided by the following criteria:

· Replacing attributes with objects. If the presence of some entity is more important than its value, then it is an object; if the value is more important, then it is an attribute: for example, a boss is an object (it doesn’t matter who the boss is, the main thing is that someone is), salary is an attribute ( its significance is very significant); city ​​is always an object, although in some cases it may seem that it is an attribute (for example, city as part of a company address); in cases where you want city to be an attribute, you should define a dependency (say, located) between the classes firm and city.

· Qualifiers. If the value of an attribute depends on a specific context, it should be made a qualifier (see section 2.3.4).

· Names. Names are usually better matched by qualifiers than by object attributes; in all cases when a name allows one to select from objects of a certain set, it should be made a qualifier (see section 2.3.4).

· Identifiers. Object identifiers are associated with their implementation. In the early stages of design they should not be considered as attributes.

· Link Attributes. If some property characterizes not the object itself, but its relationship with another object (objects), then this is an attribute of the connection, and not an attribute of the object.

· Internal values. Attributes that define only the internal state of an object, invisible outside the object, should be excluded from consideration.

· Unimportant details. It is recommended to omit attributes that do not affect the execution of most operations.

2.2.5. Organizing a class system using inheritance. Next, you need to try to find superclasses for the introduced classes. This is useful because it clarifies the structure of the model and makes subsequent implementation easier. The example is discussed in paragraph 2.3.5.

2.2.6. Further research and improvement of the model. Only in very rare cases does the constructed object model immediately turn out to be correct. The model must be researched and debugged. Some errors can be found when examining a model without a computer, others - when interpreting it together with dynamic and functional models on a computer (these models are built after the object model has already been built).

Here we will look at techniques for computer-free search and correction of errors in the object model. They are based on external signs that can be used to find errors in the model; these signs can be combined into the following groups.

Signs of a missing object (class):

· asymmetry of connections and generalizations (inheritance); to fix the error you need to add the missing classes;

· mismatch between attributes and operations of a class; to correct the error, it is necessary to split the class into several other classes, so that the attributes and operations of the new classes correspond to each other;

· an operation has been detected that does not have a satisfactory target class; To fix the error, you need to add the missing target class;

· several dependencies with the same names and purposes were found; To fix the error, you need to generalize and add the missing superclass.

Signs of an unnecessary (superfluous) class:

· lack of attributes, operations and dependencies of a certain class; To correct the error, you need to consider whether such a class should be excluded.

Signs of missing dependencies:

· there are no access paths to operations; To fix the error, you need to add new dependencies that provide the ability to service the corresponding requests.

Signs of unnecessary (superfluous) dependencies:

· redundant information in dependencies; to correct the error, it is necessary to exclude dependencies that do not add new information, or mark them as derived dependencies;

· there are not enough operations crossing the dependency; To correct the error, you need to consider whether such a dependency should be excluded.

Signs incorrect placement dependencies:

· role names are too broad or too narrow for their classes; To fix the error, you must move the dependency up or down the class hierarchy.

Signs of incorrect attribute placement:

· there is no need to access an object by the values ​​of one of its attributes; To fix the error, you need to consider whether you need to introduce a qualified dependency.

Examples practical application For the described symptoms, see paragraph 2.3.6.

Example object model

Let's consider the process of building an object model for a banking service system in the process of analyzing requirements and preliminary design of this system. To build an object model of the system under consideration, we need to complete all the steps listed in paragraph 2.2.

2.3.1. Definition of objects and classes. In clause 1.3, the task is formulated and a diagram of the banking service network is shown (Fig. 1.3). By analyzing this statement of the problem, it is possible to identify possible classes by matching them with the nouns mentioned in its preliminary formulation; This results in the following list of possible class names (in alphabetical order):

We examine this list, excluding class names from it in accordance with the recommendations of paragraph 2.2.1:

· redundant classes: It is clear that client and user mean the same concept; for the banking system it is more natural to leave the client class;

· irrelevant classes: such a class is the price class (it is not directly related to the operation of the banking network);

· ill-defined classes: such classes are record_keeping_service and security check (these services are part of the posting), system (in our case it is not clear what this is), banking_network (the entire PS will serve the banking network);

· attributes: transaction data, account data, money (meaning real money given to the client by a cashier or ATM, or accepted by the cashier), receipt (issued to the client along with the money) is more natural to have as attributes;

· implementation structures express names such as software_software and access; they should also be excluded from the list of possible class names.

After eliminating all unnecessary names of possible classes, we obtain the following list of classes that make up the designed banking system (these classes are presented in Fig. 2.5):

2.3.2. Preparing the data dictionary. Here is a part of the data dictionary containing definitions of the classes used in the project.

ATM (ATM) is a terminal that allows the client to make his own transactions using his card for identification. ATM (ATM) interacts with the customer to receive necessary information for posting, sends posting information to the central_computer so that it checks it and subsequently uses it when performing posting and issues money and a receipt to the client. It is assumed that the ATM (automated teller machine) does not need to operate independently of the network.

A bank is a financial organization that holds accounts for its customers and issues cards authorizing access to accounts through an ATM (automated teller machine) network.

Card - a plastic card issued by a bank to its client, which authorizes access to accounts through the ATM (ATM) network. Each card contains a bank code and card number, encoded in accordance with national standards for bank cards. The bank_code uniquely identifies the bank within the consortium. The card_number determines the accounts to which the card has access. The card does not necessarily provide access to all customer accounts. Each card can only be owned by one customer, but multiple copies may exist, so consideration should be given to simultaneous use the same card from different ATMs (ATMs).

A cashier is a bank employee who has the right to make transactions from cash terminals, as well as accept and issue money and checks to customers. Transactions, money and checks that each cashier works with must be recorded and correctly accounted for.

Cash_terminal - the terminal from which the cashier makes transactions for clients. When the cashier accepts and issues money and checks, the POS terminal prints receipts. The POS terminal interacts with the bank_computer to check and complete the posting.

Client is the holder of one or more bank accounts. The client may consist of one or more individuals or organizations. The same person holding an account in another bank is treated as a different client.

Bank_computer is a computer owned by the bank that interacts with the ATM (ATM) network and the bank's own cash_terminals. The bank may have its own internal computer network to process invoices, but here we are only considering the bank_computer that communicates with the ATM network.

Consortium is an association of banks that provides work ATM networks(ATMs). The network transmits bank transactions to the consortium.

Posting is a single integrated request to perform a certain sequence of operations on the accounts of one client. It has been assumed that ATMs (automated teller machines) only dispense money, but they should not exclude the possibility of printing checks or accepting money and checks. We would also like to ensure the flexibility of the system, which in the future will provide the ability to simultaneously process accounts from different clients, although this is not required yet. The various operations must be properly balanced.

Account - a single bank account over which postings are made. Accounts may be various types; a client can have several accounts.

Central_computer - a computer owned by a consortium that distributes transactions and their results between ATMs (ATMs) and bank_computers. The central_computer checks bank codes but does not post.

2.3.3. Definition of dependencies. Following the recommendations of paragraph 2.2.3, we distinguish explicit and implicit verb phrases from the preliminary statement of the problem and consider them as names of possible dependencies. From the formulation of the problem of the banking network (see section 1.3), the following expressions can be extracted:

Verb phrases (explicit and implicit):

Banking network includes cashiers and ATMs

Consortium distributes results of transactions via ATM

Bank owns bank computer

Bank computer supports accounts

Bank owns cash terminals

Cash terminal interacts with bank computer

Cashier enters posting to the invoice

ATM's interact With central computer during wiring

Central computer interacts with bank computer

ATM accepts card

ATM communicates with user

ATM issues cash

ATM prints receipts

System regulates shared access

Bank provides software

Consortium comprises banks

Consortium owns central computer

System provides logging

System provides safety

Clients have cards

Card provides access to the account

In the bank serve cashiers

Then we exclude unnecessary or incorrect dependencies using the criteria formulated in paragraph 2.2.3:

· dependencies between excluded classes: the following dependencies are excluded: Banking network includes cashiers and ATMs (banking_network class excluded), ATM prints receipts (receipt class excluded), ATM issues cash (class money excluded), System provides logging transactions (record_keeping_service class excluded), System provides security of account management (class security_service excluded), Banks provide software (class software_software excluded);

· irrelevant dependencies and implementation related dependencies: dependency "System" regulates shared access" is excluded as implementation related;

· actions are described by dependencies such as "ATM accepts card" and "ATM communicates with the user"; we exclude these dependencies;

· training dependencies: addiction "Cashier" enters posting on the account" is decomposed into two binary dependencies "Cashier enters wiring" and "Wiring refers to account". Dependency "ATM"s interact with the central computer during wiring" is expanded into "ATM"s interact with central computer" and "Wiring begin with ATM";

· derived dependencies: dependency "Consortium" distributes ATM's are a consequence of the Consortium dependencies owns central computer" and "ATM"s interact with a central computer."

By removing redundant dependencies, we get the following list of dependencies:

Bank owns bank computer

Bank computer supports accounts

Bank owns cash terminals

Cash terminal interacts with bank computer

Cashier enters wiring

Wiring refers to account

ATM's interact with central computer

Wiring begins with ATM

Central computer interacts with bank computer

Consortium comprises banks

Consortium owns central computer

Clients have cards

Card provides access to the account

In the bank serve cashiers

Let us clarify the semantics of the remaining dependencies as follows:

· let's rename incorrectly named dependencies so that their meaning becomes clearer; so dependency Computer_bank supports it is more convenient to replace the accounts with the Bank dependency holds accounts.

· role names may not be used, since they are clear from the names of the classes involved in the dependency, such as for the ATM dependency interact with a central computer;

· unaccounted dependencies: Wiring begins from cash_terminal, Clients have Accounts, Posting registered card should be added to the model.

Once the dependencies have been clarified, an initial version of the object diagram can be compiled. For the problem under consideration, it will have the form shown in Fig. 2.37.

Rice. 2.37. First version of the object diagram for the banking network

2.3.4. Attribute clarification. Applying the criteria formulated in clause 2.2.4, we obtain:

The card contains the bank_code and card_code; they can be considered attributes of objects of the card class, but it is more convenient to use them as qualifiers, since the bank_code ensures the choice of bank, reducing the multiplicity of the consortium - bank relationship; for a similar use of card_code, you need to add the Bank dependency issues cards, the qualifier of which will be card_code.

After making the above changes, the diagram will take the form shown in Fig. 2.38.

2.3.5. Organizing a class system using inheritance. In the example under consideration, it is natural to define superclasses for objects that define various terminals: cash_terminal and ATM (ATM), and for objects that define transactions: cashier_transaction and remote_transaction (from an ATM).

Having made the appropriate changes, we obtain the object diagram shown in Fig. 2.39.

Rice. 2.38. Object diagram for a banking network after specifying attributes and adding qualifiers

Rice. 2.39. Object diagram for banking taking into account inheritance

2.3.6. Further improvement of the model. The card acts in two entities: as a registration unit in the bank (passbook), which provides the client with access to his accounts, and as a data structure with which ATM works. Therefore, it is convenient to split the card class into two classes: registration_card and card; the first of these classes provides the client with access to his bank accounts, and the second defines the data structure with which ATM works.

It is convenient to imagine the posting class as an aggregation of change classes, since posting is an agreed upon sequence of making changes to accounts and other banking documents; When working with bank documents, three types of changes are considered: withdrawal, placement and request.

It is natural to combine the bank class with the computer_bank class, and the consortium class with the central_computer class.

Rice. 2.40. Final view of the object diagram for the banking network

After making the above changes, the object diagram will take the form shown in Fig. 2.40. This completes the construction of the object model of the preliminary design stage. Further refinements of the object model will be carried out at the next phases of the system lifecycle.

Isolation of subsystems

2.4.1. The concept of a subsystem. So, the PS is a set of interdependent objects. Each object is characterized by a set of attributes, the values ​​of which determine the state of the object, and a set of operations that can be applied to this object. When developing a software system, it is convenient to assume that all attributes of objects are closed (that is, they are not accessible outside the object, and in order to find out the value of an attribute of another object in an object, or change it, it is necessary to use one of the public operations of this object, if, of course, such an operation is defined). Object operations can be either public or private.

Thus, each object has a strictly defined interface, i.e. a set of public operations that can be applied to this object. All objects of the same class have the same interface. The interface of a class (and, consequently, of each object of this class) is specified by a list of signatures of its open (public) operations (and methods that implement them); signatures of closed operations are not included in the interface of objects of the corresponding class.

The system object model specifies the set of interdependent objects that make up the system, and therefore defines the set of interfaces available within the system. All data processing capabilities within the system (i.e., in each object that is part of the system) are determined by this set of interfaces, which defines internal environment(or Wednesday) systems.

Along with the internal environment of the system, it is possible to determine its external environment. It is determined by the functions (operations) implemented as part of the system software(those. operating system, programming systems, various editors, DBMS, etc.), as well as in other application systems and libraries used in conjunction with the system. Objects and operations that make up the external environment of the system can also be accessed within the system. To keep this in mind, we could add another object to the object model whose interface would represent the environmental capabilities used in the system (such an interface usually represents only a part of the external environment's capabilities). But this would not be entirely accurate, since the external environment is realized not by one, but by several objects. On the other hand, inside the system there is no reason to consider the structure of its external environment. The way out of this contradiction is to introduce another entity into consideration - a subsystem.

Subsystem is a set of objects and subsystems that provide some functionality and interact with each other in accordance with their interfaces. Subsystem interface represents subset combining the interfaces of all objects and subsystems that make up this subsystem. A subsystem may include one or more interdependent objects and/or subsystems.

The set of interfaces of objects (and subsystems), which together constitute a certain subsystem, constitutes internal environment this subsystem. Each subsystem must include an environment subsystem representing external environment this subsystem. The environment subsystem for the banking service system, considered as an end-to-end example, is shown in Fig. 2.41. The environment subsystem interface determines in which software environment the designed system will operate and what capabilities of this environment will be used during its operation (this is important when there is a need for modification or replacement individual components environment).

Note that the environment subsystem represents only the interface of the banking service system with its external environment. The external environment of the banking service system consists of several subsystems and libraries, and an object model can also be developed for it, which can also contain the system being developed (in this object model it will be one of the subsystems).

The object model of the banking service system and its system (external) environment can also be depicted in the form of an object diagram (however, this object diagram will not include objects, but only subsystems; each subsystem is depicted on the diagram as a rectangle with double vertical sides). The dependencies between the subsystems depicted in this object diagram (Fig. 2.42) reflect the interaction of the designed banking system and the corresponding subsystems during the operation of the system. This determines the requirements of the designed system for its system environment.

Rice. 2.41. Object diagram of the banking network, which indicates the interface with the system environment

Rice. 2.42. Object diagram of a banking network and its system environment

The introduction of the concept of a subsystem and the ability to include subsystems in the object model along with objects (classes) defines the hierarchical structure of the object model and allows the use of the OMT methodology when designing quite complex software systems containing big number various objects and classes.

2.4.2. Interfaces and environments. Objects and subsystems that make up a subsystem more than high level, we will call components the last one. As already noted, for each component that is part of the subsystem object model, its interface, i.e. a set of open (public) operations that can be applied to this component (object or subsystem).

Object Interface is defined by the interface of the corresponding class and is specified by a list of signatures of its public operations (methods). Subsystem interface is defined through the interfaces of its constituent objects and subsystems as follows: an operation can be included in the interface of a subsystem if this subsystem contains an object (subsystem) whose interface contains this operation. Interfaces are described in an interface description language IDL (Interface Definition Language).

All data processing capabilities within the subsystem (i.e., in each component included in its composition) are determined by a set of interfaces of its components, which determines internal environment of the subsystem.

If for some subsystem it turns out that none of its components contains an operation that it is desirable to include in its interface, an object that implements such an operation can be added to its composition. Such an object is called interface object. Interface objects allow you to coordinate the external interface of a subsystem with its external environment, i.e. with interfaces of other objects and subsystems, which, together with the subsystem in question, constitute a higher-level subsystem.

Let us explain the introduced concepts using the example of a banking service system. In its composition, one can distinguish the bank subsystem (in fact, the system will have several copies of the bank subsystem - one for each bank included in the consortium). In this case, the object model of the system will take the form shown in Fig. 2.43.

Rice. 2.43. Object diagram of the banking network after highlighting the bank subsystem

At the same time, the external interfaces of the bank and environment subsystems, together with the interfaces of the ATM and consortium objects, form the internal environment of the banking service system. Its external environment is shown in Fig. 2.42; it consists of the external interfaces of various software systems used in the banking system (the figure shows only a part of these systems), and its own external interface.







2024 gtavrl.ru.