Une question pour les experts de la POO. - page 52

 

J'ai regardé à travers mon nouveau prisme, un hybride de POO et de noyau, les systèmes d'objets décrits dans les programmes, et j'ai failli me crever le cerveau. Tout d'abord, j'ai jeté un nouveau regard sur mes systèmes d'interface graphique. A travers tous ces objets-paramètres, objets-états, objets-événements et handlers. Comme l'interface graphique et sa technologie me sont familières, tout semblait assez clair, mais le système est très complexe. Une masse de paramètres, de mappings et de gestionnaires. Je suis arrivé à la conclusion que de tels systèmes ne peuvent pas apparaître par eux-mêmes. Et la sélection naturelle n'a aucun pouvoir ici.

Voici pourquoi :

Chaque paramètre peut avoir un nombre n de paramètres dérivés. Disons qu'une modification de X peut générer une infinité de paramètres dérivés à partir des valeurs de ce X à un moment donné.

Chaque paramètre dérivé doit avoir un gestionnaire et un lien vers d'autres paramètres. Aucun paramètre n'existe par lui-même. Le lien est obligatoire.

Le couplage peut être différent, et par conséquent une variété de manipulateurs - filtres, correcteurs, transducteurs - peut apparaître.

Les événements qui peuvent être considérés comme significatifs pour les systèmes sont indéfiniment nombreux. Chacun d'entre eux possède ses propres propriétés, liens et gestionnaires. Les variations sont innombrables.

Ainsi, sans concept, aucun système ne peut voir le jour. (Très probable).

On ne sait pas exactement comment la vie sur Terre est apparue...

 

Voici un autre exemple :

Considérons un système permettant de déplacer une fenêtre avec des contrôles sur un graphique.

  • Nous prenons deux paramètres - x et y - de l'objet "curseur". À partir de ces objets, créez deux objets paramètres dérivés qui stockeront la différence entre les valeurs actuelles et passées de x et y. (Les objets paramètres ne sont pas de simples variables, ce sont des objets avec leurs propres propriétés).
  • Nous créons un objet Handler pour les objets Parameter qui va (1) gérer les valeurs x et y, en récupérant leur différence entre les valeurs actuelles et passées lors de l'événement de manipulation de la fenêtre, qui est écrit dans les propriétés du Handler, (2) écrire la différence dans les paramètres dérivés lors du même événement.
  • Créez un objet de liaison entre les objets paramètres dérivés et les objets paramètres x,y de chaque objet fenêtre, qui sera utilisé pour leur transmettre des valeurs.
  • Après le liant d'objet, nous créons un autre objet Handler, qui doit prendre la valeur des paramètres d'objet x et y de chaque objet fenêtre et y ajouter une valeur allant sur le liant.

Ainsi, avec ce système, nous pouvons changer les coordonnées d'une fenêtre et de ses objets au moment où sa poignée est saisie par le curseur. Pour déplacer le tout, nous devons l'associer aux fonctions du gestionnaire ObjectSetInteger qui modifient la position de l'objet MT sur le graphique.

Il s'agit de la mise en œuvre d'une seule fonction de l'interface graphique en reliant des blocs système spéciaux - paramètres d'objet, gestionnaires d'objet, etc...

Construire un tel système dans le noyau n'est pas un peu plus facile (ou peut-être même plus difficile) que d'écrire du code normal sans tout transformer en objet. Mais, je vais continuer à creuser...


ZS. J'ai oublié d'ajouter que pour déplacer la fenêtre, il faut aussi "fabriquer" un Event Object, qui verrouille la poignée de la fenêtre et le mouvement du curseur. Et cet objet événement, connectez-le au gestionnaire d'objet des valeurs x,y du curseur (qui écrit la différence dans les paramètres dérivés), et il ne fonctionnerait que sur le signal de cet événement.

Et pour chaque objet d'événement, vous devez créer un gestionnaire d'objet et le lier à celui-ci.

Chaque gestionnaire d'objet possède ses propres propriétés, dont les valeurs sont utilisées par celui-ci lorsqu'il travaille avec des paramètres ou des événements. Il doit donc y avoir un modèle, sinon vous vous embourbez dans la création de tout).

 
Реter Konow:

Voici un autre exemple :

Considérons un système permettant de déplacer une fenêtre avec des contrôles sur un graphique.

  • Nous prenons deux paramètres - x et y - de l'objet "curseur". À partir de ces objets, créez deux objets paramètres dérivés qui stockeront la différence entre les valeurs actuelles et passées de x et y. (Les objets paramètres ne sont pas de simples variables, ce sont des objets avec leurs propres propriétés).
  • Créez un objet Handler pour les objets Parameter qui (1) traitera les valeurs x et y, en récupérant leur différence entre les valeurs actuelles et passées lors de l'événement de manipulation de la fenêtre, qui est écrit dans les propriétés du Handler, (2) écrira la différence dans les paramètres dérivés lors du même événement.
  • Créez un objet de liaison entre les objets paramètres dérivés et les objets paramètres x,y de chaque objet fenêtre, qui sera utilisé pour leur transmettre des valeurs.
  • Après le liant d'objet, nous créons un autre objet Handler, qui doit prendre la valeur des paramètres d'objet x et y de chaque objet fenêtre et y ajouter une valeur allant sur le liant.

Ainsi, avec ce système, nous pouvons changer les coordonnées d'une fenêtre et de ses objets au moment où sa poignée est saisie par le curseur. Pour déplacer le tout, nous devons l'associer aux fonctions du gestionnaire ObjectSetInteger qui modifient la position de l'objet MT sur le graphique.

Il s'agit de la mise en œuvre d'une seule fonction de l'interface graphique en reliant des blocs système spéciaux - paramètres d'objet, gestionnaires d'objet, etc...

Construire un tel système dans le noyau n'est pas un peu plus facile (ou peut-être même plus difficile) que d'écrire du code normal sans tout transformer en objet. Mais, je vais continuer à creuser...


ZS. J'ai oublié d'ajouter que pour déplacer la fenêtre, il faut aussi "fabriquer" un Event Object, qui verrouille la poignée de la fenêtre et le mouvement du curseur. Et cet objet événement, connectez-le au gestionnaire d'objet des valeurs x,y du curseur (qui écrit la différence dans les paramètres dérivés), et il ne fonctionnerait que sur le signal de cet événement.

Et pour chaque objet-événement, vous devez créer un gestionnaire d'objet et le connecter à celui-ci.

Chaque gestionnaire d'objet a ses propres propriétés et les valeurs qu'il utilise lorsqu'il travaille avec des paramètres ou des événements. Il faut donc qu'il y ait un modèle, sinon vous vous embourbez dans la création de tout cela).

Difficile. D'une difficulté injustifiée.
L'objet principal d'un formulaire, à l'intérieur duquel se trouvent les autres objets de ce formulaire, est le seul à recevoir des coordonnées. La modification d'une coordonnée quelconque change la position de l'objet principal du formulaire. Les autres objets de ce formulaire reçoivent simplement des coordonnées relatives qui déterminent leur emplacement dans le formulaire. Tous les objets ont leur propre ordre dans le formulaire, et sont réorganisés dans cet ordre. Chaque objet contient une liste de ce qu'il contient. La référence à la liste des contenus permet de commander chaque contenu à un décalage. Ainsi, en donnant une commande de déplacement à l'objet formulaire, la chaîne est automatiquement passée pour déplacer tout le contenu du formulaire. C'est-à-dire que seul le formulaire est décalé, et tout le reste est automatiquement décalé. Nous n'avons pas besoin de donner à chaque objet du formulaire une commande de décalage par lui-même.
Nous faisons cela pour un seul objet. Tous les autres vont le répéter. Quelle que soit la complexité d'un objet de formulaire, une seule commande de décalage sera transmise à tout le contenu de ce formulaire dans une avalanche.
Tout est fait une seule fois. Et puis tout se fera à la chaîne.
 
Artyom Trishkin:
Compliqué. Injustement compliqué.
L'objet principal d'un formulaire, à l'intérieur duquel se trouvent les autres objets de ce formulaire, est le seul à recevoir des coordonnées. La modification d'une coordonnée quelconque change la position de l'objet principal du formulaire. Les autres objets du formulaire reçoivent simplement des coordonnées relatives qui déterminent leur position dans le formulaire. Tous les objets ont leur propre ordre dans le formulaire, et sont réorganisés dans cet ordre. Chaque objet contient une liste de ce qu'il contient. La référence à la liste des contenus permet de commander chaque contenu à un décalage. Ainsi, en donnant une commande de déplacement à l'objet formulaire, la chaîne est automatiquement passée pour déplacer tout le contenu du formulaire. C'est-à-dire que seul le formulaire est décalé, et tout le reste est automatiquement décalé. Nous n'avons pas besoin de donner à chaque objet de formulaire une commande de décalage par lui-même.
Nous faisons cela pour un seul objet. Tous les autres vont le répéter. Quelle que soit la complexité d'un objet de formulaire, une seule commande de décalage sera transmise à l'ensemble du contenu de ce formulaire en une avalanche.
Tout est fait une seule fois. Et puis tout se fera à la chaîne.

C'est vrai.

La liaison entre les paramètres dérivés contenant la différence x,y du curseur et les objets de formulaire (qui sont dans la chaîne) a un gestionnaire au milieu qui peut effectuer une connexion en série aux paramètres x,y de chaque objet de formulaire. En d'autres termes, la liaison des paramètres via le gestionnaire de connexion série permet de remplacer la liaison de chaque objet de formulaire par des paramètres dérivés passant des valeurs de différence x,y. J'y pensais aussi.

Dans mon interface graphique, le déplacement de la fenêtre est implémenté dans une fonction qui fait ce qui suit :

(1) Contrôleur d'événement pour l'événement de clic de la poignée de fenêtre

(2) Déplacement du curseur

(3) Calcul de la différence entre les coordonnées du curseur actuel et les coordonnées du curseur passé

(4) Parcourir les objets de la fenêtre et modifier leurs coordonnées en ajustant la différence de position du curseur.

(5) Appel de l'ObjectSetInteger pour déplacer l'МТ-objet de la forme fenêtre (canvas) le long du graphique de la distance donnée.


Ainsi, l'implémentation dans la fonction est correcte. La mise en œuvre au moyen de gestionnaires d'objets, de paramètres d'objets et de liaisons d'objets semble maladroite dans ce contexte. Mais, creusons un peu...

 
Реter Konow:

C'est exact.

Le mappage entre les paramètres dérivés contenant la différence x,y du curseur et les objets de formulaire (qui sont dans la chaîne) a un gestionnaire au milieu qui peut effectuer une connexion série aux paramètres x,y de chaque objet de formulaire. C'est-à-dire que la liaison des paramètres via le gestionnaire de connexion série permet de remplacer la liaison de chaque objet de formulaire par des paramètres dérivés passant les valeurs de différence x,y. J'y pensais aussi.

Dans mon interface graphique, le déplacement de la fenêtre est implémenté dans une fonction qui fait ce qui suit :

(1) Contrôleur d'événement pour l'événement de clic de la poignée de fenêtre

(2) Déplacement du curseur

(3) Calcul de la différence entre les coordonnées du curseur actuel et les coordonnées du curseur passé

(4) Parcourir les objets de la fenêtre et modifier leurs coordonnées en ajustant la différence de position du curseur.

(5) Appel de l'ObjectSetInteger pour déplacer l'МТ-objet de la forme fenêtre (canvas) le long du graphique de la distance donnée.


Ainsi, l'implémentation dans la fonction est correcte. La mise en œuvre par le biais de gestionnaires d'objets, de paramètres d'objets et de liaisons d'objets semble maladroite dans ce contexte. Mais, creusons un peu...

Oui, car il n'est pas nécessaire de séparer ces gestionnaires de l'objet. La classe qui renvoie les coordonnées du curseur peut être rendue statique - elle sera disponible pour toutes les classes du programme, et l'obtention des coordonnées et la réponse à celles-ci doivent être implémentées dans chaque objet. Mais seul l'objet principal du formulaire doit appeler ces gestionnaires. Ensuite, pour tous les autres objets du formulaire, il suffit de spécifier de nouvelles coordonnées et de redessiner. L'objet formulaire contient une liste de tous ses objets. L'objet formulaire a défini la modification de ses coordonnées - il fixe de nouvelles valeurs à ses coordonnées, parcourt sa liste d'objets et appelle des méthodes pour fixer les coordonnées de chaque objet de sa liste. En même temps, chaque objet suivant fait la même chose lorsque ses coordonnées changent : il consulte sa liste d'objets et leur ordonne de changer leurs coordonnées. Les objets des listes sont classés dans l'ordre où ils sont dessinés (séquence Z). En d'autres termes, chaque objet possède sa propre méthode de modification des coordonnées, mais elle est mise en œuvre de la même manière - elle parcourt la liste de tous les objets "amis" et appelle la même méthode pour chacun d'eux. Ainsi, en appelant cette méthode une fois pour l'objet principal du formulaire, nous lançons automatiquement un changement de coordonnées pour tous les objets du formulaire. Une fois que tous les objets "propres" de l'objet formulaire ont été traités, la méthode redraw chart de l'objet formulaire est invoquée, qui est la même pour tous les objets modifiés.

 
Artyom Trishkin:

...

Il s'agit de la vue standard OOP du mécanisme de déplacement de la fenêtre. Je vais vous en montrer un autre. Pour ce faire, faites le vide dans votre esprit pendant une seconde et suivez juste ma pensée.

  1. Imaginez une matrice. Les dimensions sont indéfinies. Peut-être qu'il est infini, peut-être qu'il ne l'est pas. Ça n'a pas d'importance.
  2. La matrice est initialisée avec des zéros. Les zéros représentent le vide. C'est-à-dire que la matrice est vide.
  3. Dans le vide de la matrice, quelque chose d'autre que le vide est apparu. C'est un zéro remplacé par une valeur. Peu importe ce que c'est.
  4. Nous voyons cette valeur dans la matrice vide et disons "c'est un paramètre". C'est-à-dire, pas la valeur elle-même - mais la cellule dans laquelle elle apparaît. La cellule est honorée du titre et appelée paramètre - c'est-à-dire la "capacité" contenant la valeur.
  5. Le paramètre exige immédiatement de nous sa définition. C'est comme s'il disait : "Je suis un paramètre, et j'ai une personnalité ! Où sont mes propriétés ? !". Et nous n'avons pas d'autre choix que d'ajouter au paramètre ses propriétés, qui sont aussi des paramètres avec leurs propres valeurs. Nous les mettons à côté et nous avons une chaîne - un paramètre et ses propriétés. Nous disons "nous avons créé un paramètre Objet !".
  6. Ensuite, le paramètre " dit ", " Où sont les autres paramètres ? ". Pourquoi suis-je le seul ?" Et puis on crée quelques paramètres supplémentaires dans le vide de la matrice, pour que le "premier né" ne s'ennuie pas. Bien entendu, chacun des nouveaux paramètres déclare son individualité et exige des propriétés comme porteurs. Ainsi, des chaînes de paramètres se développent, parmi lesquelles on trouve les "premiers-nés" et leurs propriétés. Nous disons "Nous avons créé les Objets Paramètres !".
  7. Maintenant, dans le vide de la matrice, nous avons plusieurs paramètres avec les chaînes de leurs propriétés. Mais chacun d'entre eux "crie" l'insignifiance de son existence. Chacun d'eux est seul. Ensuite, nous décidons de lier les paramètres pour qu'ils ne soient pas "ennuyés". Pour ce faire, nous créons des paramètres spéciaux qui servent de liens entre d'autres paramètres. Ils sont également constitués de chaînes de propriétés. Maintenant, les paramètres du premier né sont liés les uns aux autres par le chaînage des paramètres. Tout le monde est heureux ! Nous disons : "Nous avons créé des objets liés à des paramètres !".
  8. Mais il s'avère ensuite que les paramètres primaires veulent communiquer et se transférer des valeurs par le biais de liaisons, mais les liaisons permettent de transférer des valeurs (langage des paramètres), mais pas de les traduire. Et comme ils sont seuls, les paramètres ne comprennent que leur langage, ce qui signifie qu'il existe une "barrière linguistique" entre les paramètres et qu'ils ont besoin de nous pour la résoudre.
  9. Pour résoudre le problème de la "communication des paramètres", nous n'avions pas assez de mappings, il nous fallait une traduction. Cela signifie que les valeurs transmises entre les paramètres doivent être converties, en tenant compte des propriétés de chaque paramètre. Certains d'entre eux comprennent des valeurs comprises entre 1 et 10, d'autres entre (-5) et (-105). Certains fonctionnent avec des nombres fractionnaires, d'autres avec des puissances. Par conséquent, nous concluons que nous avons besoin de "traducteurs", c'est-à-dire de gestionnaires de valeurs qui prennent en compte les propriétés des paramètres. Nous créons des objets Handler spéciaux et les insérons dans les mappages de paramètres. Les objets de traitement des valeurs "traduisent" les valeurs transmises entre les paramètres en utilisant les propriétés des paramètres qu'ils transmettent et reçoivent, ainsi que leurs propres propriétés. Nous disons - "Nous avons créé des objets Handler ! Maintenant, les paramètres peuvent communiquer librement !".
  10. Les paramètres des premiers-nés communiquaient et communiquaient et ils en ont eu assez. J'en ai marre. Puis ils ont décidé qu'ils ne communiqueraient que lors d'occasions spéciales - enfin, lorsque l'un d'entre eux obtient une valeur incroyable. Mais il s'est avéré que nous devions garder un œil sur la valeur, comme un enfant, sans relâche. Les paramètres du premier né nous ont demandé de réfléchir à un "système de surveillance" qui signalerait les variations inhabituelles afin qu'ils ne s'en inquiètent pas. Nous avons donc fait un moule des valeurs auxquelles nous devions réagir et nous y avons ajouté un gestionnaire spécial, ce qui a donné lieu à un "objet événement". Nous l'avons connecté à chaque paramètre et ils commencent à communiquer entre eux en utilisant les signaux des objets d'événement. Nous avons donc créé "Object-events".

C'est la fin de l'histoire...

Nous avons regardé la matrice de l'extérieur et nous avons été surpris ! "Nous avons créé un système d'objets !")

ZS. Remarquez que tout peut être créé dans un tableau-matrice. Et la matrice est le noyau. Et les entités qui s'y trouvent - les vrais objets. Et des paramètres, et des événements, et des liaisons, et des propriétés, et des gestionnaires. Il existe d'innombrables systèmes qui peuvent être construits dans le noyau à partir de ces éléments de base.

 

Une suite factice...

11. D'une manière ou d'une autre, les paramètres du premier-né ont décidé de suivre une mode. Ils ont découvert qu'il existe une propriété équitable quelque part dans la matrice, et un certain espace dans la nouveauté. Ils disent qu'il a trois propriétés. Les "dimensions" sont appelées. Ces propriétés ont une gamme de valeurs supposément infinie et, en prime, elles donnent un autre "paramètre-temps". Les paramètres sont arrivés à la foire et ont pris les propriétés x,y,x_size,y_size. Ils disent qu'ils veulent faire une coquille dans l'espace. Et ils ont pris des couleurs. Ils sont revenus et ont commencé à habiller les nouvelles propriétés. Ils ont modélisé et modélisé des enveloppes spatiales jusqu'à ce qu'ils en aient assez. Ils ont connu une croissance énorme, puis se sont effondrés... Puis ils ont mis des couleurs sur eux-mêmes et se sont détendus. Ils ont commencé à réfléchir à ce qu'ils allaient faire ensuite. Et puis ils ont regardé la boîte de propriété du temps. Voyons ce que c'est... Ils l'ont ouvert, l'ont attaché à eux, mais ils n'ont pas calculé les valeurs et en un instant il s'est évaporé dans le vide. Après tout, le temps est un paramètre avec lequel il faut faire très attention...

 
Реter Konow:

Une suite factice...

11. D'une manière ou d'une autre, les paramètres du premier-né ont décidé de suivre une mode. Ils ont découvert qu'il existe une propriété équitable quelque part dans la matrice, et un certain espace dans la nouveauté. Ils disent qu'il a trois propriétés. Les "dimensions" sont appelées. Ces propriétés ont une gamme de valeurs supposément infinie et, en prime, elles donnent un autre "paramètre-temps". Les paramètres sont arrivés à la foire et ont pris les propriétés x,y,x_size,y_size. Ils disent qu'ils veulent faire une coquille dans l'espace. Et ils ont pris des couleurs. Ils sont revenus et ont commencé à habiller les nouvelles propriétés. Ils ont modélisé et modélisé des enveloppes spatiales jusqu'à ce qu'ils en aient assez. Ils ont connu une croissance énorme, puis se sont effondrés... Puis ils se sont colorés et se sont détendus. Ils ont commencé à réfléchir à ce qu'ils allaient faire ensuite. Et puis ils ont regardé la boîte de propriété du temps. Voyons ce que c'est... Ils l'ont ouvert, l'ont attaché à eux, mais ils n'ont pas calculé les valeurs et en un instant il s'est évaporé dans le vide. Après tout, le temps est un paramètre avec lequel il faut faire très attention...

Et les dix premiers n'étaient pas sérieux ?

Pour ma part, je ne peux pas lire sans rire.

 
Artyom Trishkin:

...

Toute cette "objectivité" est très déroutante, n'est-ce pas... Il faut faire attention avec ça. Nikolai Semko avait raison sur la proximité du génie et de la schizophrénie. Il est possible de "devenir fou". Il y a certaines choses qu'il vaut mieux ne pas comprendre. Certaines portes, doivent toujours être fermées à notre conscience. Comme le disait un film, - "le parasite le plus dangereux est une idée. Une fois dans le cerveau, il est impossible de le faire sortir." La matrice dont je parlais est dangereuse pour l'esprit. Il est facile de s'y perdre et de s'y perdre à jamais. Soyons prudents.)))

 
La représentation des systèmes dans la Matrice donne une nouvelle perspective sur leurs structures, mais je n'ai pas vu d'allusion à la facilitation de la création de systèmes. Sans parler de tout "développement personnel". C'est sacrément intéressant de regarder les systèmes de cette façon, mais pas plus que ça. Je ne vois pas de développement personnel ou même un soupçon de développement personnel. Par conséquent, laissons le divin à Dieu. L'auto-développement des systèmes ne peut être atteint ni par l'approche OOP standard, ni par la mienne.