📜 ⬆️ ⬇️

OOP in 1C do it yourself. How to simulate your classes and objects, and why it is needed

image

I want to talk about how I use object-oriented programming in 1C. Rather his imitation, because there is no such possibility in the built-in language itself. Nevertheless, the ability to create logically independent, self-contained, self-contained code fragments (and even with data encapsulated in them) is very useful.

After all, they can be:
')
- re-use within the same project;
- easily and simply (without thinking) to transfer from one project to another;
- transfer to someone else, or put on the Internet for general use as an independent means of solving a specific task, which, accordingly, can also be easily copied and pasted into your own project by someone;
- having a class, you can create several objects at once (build arrays, collections, lists, etc.);
- some other advantages that I don’t know about ...

This article will demonstrate the techniques for imitating OOP using procedural-oriented 1C language.

The essence of the problem


As is known, the built-in language 1C does not fully support OOP. There are standard built-in platform classes with their own fields, properties, and methods. You can create objects of these classes:

 =  ; 

and use them as they do in ordinary universal programming languages. However, you cannot define and implement your own classes in the embedded language. In principle, we can say that the 1C platform does not support object-oriented programming.

Moreover, I heard from several 1C specialists that such support is completely unnecessary. But these were exactly “1C programmers”, i.e. people who have always been engaged in development only for the 1C platform, and not for the computer, and are not familiar with the classic "Computer Science". Those who have been developing in standard universal languages ​​and have become accustomed to the capabilities of the PLO, when faced with the 1C platform, often experience strong inconvenience from the inability to build the architecture of their program and generally express their thoughts, their vision of the task, as an object model. Instead of OOP, the embedded language suggests returning to structured programming, which is also curtailed in comparison with the classical variants (for example, Pascal and C languages). There is no possibility to create several modules of a general form (without forms) in one or another configuration object. This is very important if, for example, you do external processing (so as not to become attached to a specific configuration, or you simply do not want to make changes to the typical configuration itself and remove it from support) and accordingly no part of the processing can be made into “common modules”, - All functionality needs to be placed in one single processing module. There is no possibility to connect specific modules inside another module ( uses of # or #include clause).

 Uses , ; #include .; 

However, this article is not about modules.

So, how can you implement at least some of the main paradigms of OOP using structured programming?

With polymorphism and type properties

 property MyVar: Integer read GetMyVar write SetMyVar; 

nothing will come of it (they can also be made, in fact, but syntactically it will look too sophisticated, ugly and therefore inconvenient and not obvious in application). About access control ( private , protected , public ) will also have to forget. But encapsulation and inheritance (in public access mode) can be done pretty well.

The essence of the decision


The idea is generally not new, and it can be learned, for example, in the architecture of such a powerful super-project from the Unix world, like the GTK + graphic library. This library is implemented in C language, but nevertheless, in fact, its architecture is object-oriented (see the example of initializing the GTK + library from the above Wikipedia article - it will be clear from it what is meant). The ability to implement OOP by means of a language that OOP does not support lies in the adoption of special agreements on the coding of sources.

What is a class? A class is a definition of data and methods of their processing “in one bottle”. And an object is essentially a dynamically created data set that is implicitly passed as a parameter to class methods so that methods can process this same data. And if the language tools, data and methods stuff into a "one bottle" does not work, then we use for this conditional add-on language features - coding conventions (Code Conventions).

We will use structures as a storage of object fields (in C, this is the built-in data type, in 1C, the built-in class is a hash table).

  =  ; . («1», 0); . («2», “”); … . («N»,  ); 

We will use procedures and functions as methods, using the following naming conventions:

  _(, …);  _(, …); 

As can be seen, instead of implicitly passing a pointer parameter to a set of fields of an object, it is passed explicitly by the 1st parameter. Next comes the usual set of method parameters.

Consider the following example:

Sample Post Office Class
 //////////////////////////////////////////////////////////////////////////////// //    //      . // // : // . // : //    //  _()  //       ,   //    ,  , //   ,       //  ,    , // ..    ( )  //   .  =  ; //    .("", ); //    .("", _()); //     ;  //   . // // : //  -      //  -   ,    // : // () -     //  _(, )  //    = _(); //    . = ; _Assign(., );  ;  //    -  . // // : //  -    //  _()  //           1. //       -  . // :     . _(.);  //     . // // : //  -    // : // () -     //  _()   = . + ", " + _(.);  ;  //////////////////////////////////////////////////////////////////////////////// //    //      . // // : // . // : //    //  _()   =  ; //    .("", ); //   .("", ); //   .("", ); //   .("", ); //    ;  //   . // // : //  // : // () -     //  _()  //    = _();  ;  //    -  . // // : //  -    //  _()   //    . // // : //  -    //  -   //  -   //  -   //  -   //  _(, , , , )  . = ; . = ; . = ; . =   //    . // // : //  -    // : // () -    //  _()   = . + ", " + ". " + . + ", " + ". " + . + ", " + ". " + .;  ;  //     2   1. //    1  . // // : // 1 -     // 2 -    -  //  _Assign(1, 2)  1. = 2.; 1. = 2.; 1. = 2.; 1. = 2.  


This was an example of encapsulation. Inheritance looks a little more clumsy.

Classes: Line, Straight, Circle
 //////////////////////////////////////////////////////////////////////////////// //    //      . // // : // . // : //    //  _()   =  ; //    .("X1", 0); // X-  .("Y1", 0); // Y-   ;  //   . // // : // X1, Y1 -   ()   // : // () -     //  _(X1, Y1)  //    = _(); //    .X1 = X1; .Y1 = Y1;  ;  //    -  . // // : //  -    //  _()   //   . // // : //  -    // X1, Y1 -   ()   //  _(, X1, Y1)  .X1 = X1; .Y1 = Y1;  //   . // // : //  -    // : // () -   //  _()   0; //  -         //////////////////////////////////////////////////////////////////////////////// //    -   . //      . // // : // . // : //    //  _()   = _(); //    .("X2", 0); // X-   .("Y2", 0); // Y-    ;  //   . // // : // X1, Y1 -     // X2, Y2 -     // : // () -     //  _(X1, Y1, X2, Y2)  //    = _(); //    _(, X1, Y1, X2, Y2);  ;  //    -  . // // : //  -    //  _()   //   . // // : //  -    // X1, Y1 -     // X2, Y2 -     //  _(, X1, Y1, X2, Y2)  _(, X1, Y1); .X2 = X2; .Y2 = Y2;  //   . // // : //  -    // : // () -   //  _()  //       X X = .X2 - .X1; //       Y Y = .Y2 - .Y1; //       = Sqrt(X*X + Y*Y);  ;  //////////////////////////////////////////////////////////////////////////////// //    () -   . //      . // // : // . // : //    //  _()   = _(); //    .("R", 0); //    ;  //   . // // : // X, Y -    // R -   // : // () -     //  _(X, Y, R)  //    = _(); //    _(, X, Y, R);  ;  //    -  . // // : //  -    //  _()   //   . // // : //  -    // X, Y -    // R -   //  _(, X, Y, R)  _(, X, Y); .R = R;  //   . // // : //  -    // : // () -   //  _()   = 2*3.14*.R;  ;  


Naturally, there are no virtual methods and polymorphism here. Only redefinition of the methods of the same name in descendants. They are again the same from the point of view of development logic.

Summary.


As we can see, the described method of creating source codes in 1C language expands the possibilities of code fragments written in this way in terms of visibility, universality and portability.

In further publications, I plan to talk about some useful things (you can say, tools) that you can immediately take and use in my 1C programs. Their code will be issued just in the form of such classes.

Download the texts of the examples discussed in the article (processing for 1C 8.2) here .

Good luck to all. See you.

PS: In the process of preparing this article, I came across a description of a similar approach on the portal Infostart . It was written, it seems in 2012, about the same time that I began to use this method. Since there are significant differences in this article (the author proposes to unify the method call and access to class properties through wrapper functions, which seems to be more technological, but in my opinion less obvious), I decided to publish my own version of the technology.

Source: https://habr.com/ru/post/271731/


All Articles