A programação orientada a objetos (OOP) é um conceito projetado para facilitar o desenvolvimento de sistemas complexos, introduzindo novos conceitos mais próximos do mundo real do que linguagens de programação funcionais e procedurais. Como a Wikipedia escreve, "a linguagem humana comum como um todo reflete a ideologia da OOP, começando com encapsular a idéia de um objeto na forma de seu nome e terminando com o polimorfismo de usar a palavra em sentido figurado, que acaba desenvolvendo a expressão da representação através do nome do objeto para um conceito - classe de pleno direito".

Mas, do ponto de vista de todos que se depararam com essas abstrações, depois que as linguagens processuais clássicas não ficaram mais claras, parece que o oposto estava ainda mais confuso.
Por outro lado, existem notações gráficas do programa que não estão próximas da linguagem humana, mas são muito mais compreensíveis do que qualquer código, não como OOP. É possível que isso seja mais claro para mim, estragado por uma educação em engenharia, mas há muitas pessoas como eu e este texto para os mesmos físicos mimados que não entendem abstrações altas.
Aqui, por exemplo, há uma descrição real na notação gráfica do algoritmo de controle da válvula de gaveta da NPP:
Figura 1. Exemplo de um programa de controle de NPP em notação gráficaÀ esquerda estão os sinais de entrada, à direita estão os comandos.
Parece-me que mesmo uma criança pode ler esse algoritmo:
- Se a bomba estiver ligada por 60 segundos e a vazão for menor que 10, abra a válvula de recirculação.
- Se a bomba estiver ligada, dê o comando para abrir dentro de 5 segundos as válvulas 001 e 002.
- Se a taxa de fluxo for maior que 20 e a bomba estiver ligada, dentro de 5 segundos para enviar à válvula do obturador 003 um comando para fechar.
Quando eu era estudante, trabalhei meio período criando uma biblioteca de componentes para o Delphi e estava familiarizado com o OOP em primeira mão. Então, quando me deparei com programas reais de controle de usinas nucleares, fiquei muito surpreso por não haver abstração, encapsulamento e, perdoe meu polimorfismo de Deus, apenas recomendações de C puro e MISRA C que foram cortadas pelas regras para que tudo seja confiável , portátil e seguro.
O pico de corte de C na minha prática foi FIL, para sistemas de controle de reatores RBMK. Nele, as funções foram pré-escritas em C, compiladas e depois chamadas com base em um arquivo de texto, onde foram descritas na linguagem FIL. Como resultado, foi possível chamar apenas um conjunto de funções limitado, mas cuidadosamente testado e depurado. E tudo isso em nome da segurança e confiabilidade.
Mas, ao mesmo tempo, o sistema de controle do reator e o sistema de controle da NPP como um todo são apenas os casos em que os princípios da OOP devem ser aplicados a todo o seu potencial. De fato, existem muitos equipamentos similares - válvulas, bombas, sensores, tudo é facilmente classificado, existem objetos prontos que correspondem a equipamentos reais. Parece que aqui está - use POO, classes, herança, abstração e polimorfismo. Mas não, você precisa de C puro e esses são requisitos de segurança.
E então - ainda mais interessante. De fato, o programa para gerenciar a usina nuclear não é elaborado pelo programador, mas pelo tecnólogo - apenas ele sabe o que e quando fechar, abrir, ligar e o mais importante - ele sabe quando desligar a canoa, para não cair. E o programador deve implementar cuidadosamente tudo isso no código C. E melhor ainda, que não haveria programador, e o próprio tecnólogo desenhou os algoritmos tecnológicos dos programas de controle em forma gráfica, gerou automaticamente o código C e o carregou no equipamento de controle. Os padrões internacionais de segurança recomendam isso: nesse caso, um programador - como um violinista - não é necessário. Ele introduz apenas erros e distorções adicionais na implementação dos pensamentos do tecnólogo.

Qual foi minha surpresa quando descobri que os tecnólogos e designers da NPP, independentemente dos programadores, desenvolveram e usaram com sucesso a programação orientada a objetos e até mesmo em notações gráficas, mas o código resultante atende totalmente aos requisitos de segurança e não contém artefatos da metodologia OOP .
De fato, se você observar o código que é gerado a partir do circuito na Figura 1, veremos C puro sem nenhuma classe lá.
Por exemplo, a tabela de entrada do algoritmo:
state_vars->kbaalgsv0_out_1_ = kba31ap001_xb01; state_vars->kbaalgsv0_out_4_ = kba31cf001_xq01;
Apenas atribuindo variáveis.
Qualquer bloco é descrito como o cálculo da saída por entrada, levando em consideração os parâmetros especificados na lista de constantes. Por exemplo, o bloco "Mais" se parece com isso no código:
locals->v5_out_0_ = state_vars->kbaalgsv0_out_4_ > consts->kbaalgsv3_a_;
A saída do bloco é o resultado da comparação do sinal de entrada com um valor em uma constante.
Assim, em outros blocos, as variáveis locais das variáveis de entrada são calculadas sequencialmente e, no final do ciclo do programa, as variáveis são gravadas nas variáveis de saída.
if((action==f_InitState)||(action==f_GoodStep)||(action==f_RestoreOuts)){ kba31ey001_yb01 = locals->v8_out_0_; kba31ey001_yb11 = state_vars->kbaalgsv9_out_0_; kba31ey001_yb12 = state_vars->kbaalgsv12_out_0_; kba31ey001_yb02 = locals->v13_out_0_; };
Onde estão as aulas aqui, você pergunta?
Toda a metodologia relacionada ao POO está em nomes de variáveis. Parece que isso poderia estar no nome da variável? E pode haver um abismo inteiro. Por exemplo, o nome da variável é kba31ap001_xb01, apenas uma variável no código C que atende ao requisito para o nome das variáveis. No entanto, para um engenheiro de design, é algo como isto: “Compartimento do reator, sistema industrial de abastecimento de água, primeira bomba, partida”. Toda essa mágica de conversão acontece graças ao maravilhoso sistema de codificação alemão (Kraftwerk-Kennzeichensystem) KKS, citação:
“Esse sistema de classificação de codificação é projetado para usinas de energia e tem um grande potencial e também leva em consideração os recursos do hardware do microprocessador livremente programável.
Juntamente com a marcação de equipamentos tecnológicos, órgãos executivos (válvulas de fechamento, segurança, válvulas de fechamento, etc., mecanismos auxiliares), pontos de medição, unidades de montagem, dispositivos de automação, edifícios e estruturas, o sistema KKS permite a marcação de algoritmos e programas de vários tipos e finalidades (algoritmos de processamento para parâmetros tecnológicos medidos, sinalização, regulação automática, proteções tecnológicas, controle lógico: bloqueios, ABP, programas passo a passo, - cálculo de t indicadores hniko-económicas e Diagnóstico do equipamento tecnológico), entrada, saída e sinais de intermediários de algoritmos e programas, gravações em vídeo de todos os níveis são exibidos em terminais de vídeo, cabos, etc ... "
Mas o mais interessante na última parte do nome é _xb01 , que é especificado através do sublinhado. Se você observar a base de sinal do projeto de gerenciamento, veremos aulas ali compreensíveis e familiares para todos que, uma vez, em algum lugar e em algum lugar, estavam interessados em OOP (veja a Figura 2).
Figura 2. Um exemplo de uma estrutura de base de sinal para um sistema de controle de usina nuclear.Temos classes ou tabelas, na figura esta é a coluna "Categorias". Por exemplo, "KD1", que possui uma tabela de sinais padrão, campos da classe Limite superior de medição, limite inferior de medição, leitura do sensor , etc. É uma abstração.
E também há uma implementação dessa classe - um sensor específico, por exemplo, TK21F02B1, localizado no circuito, como você pode imaginar pelo nome, no “compartimento do reator, sistema industrial de abastecimento de água, na primeira bomba” e o fato de ser um sensor de fluxo está neste título, mas não é preciso.
E esta instância desta classe possui sinais específicos e seus valores, no processo do programa, e eles podem ser acessados pelos nomes dos campos da classe. Por exemplo, uma leitura do sensor é indicada pela variável TK21F02B1_XQ04.
Neste ponto, podemos dizer, espere, isso não é OOP, ou mesmo não OOP, é apenas uma estrutura de dados, está no padrão C. E onde está o encapsulamento dos métodos na classe? O processamento de dados deve estar na classe, então esse será o método OOP real kosher.
Vamos ver como a sub-rotina de controle de confiabilidade do sensor se parece em forma gráfica. A Figura 3 é uma parte do circuito de processamento de sinal:
Figura 3. Um exemplo de um programa de processamento de sinal.Pode-se observar que na sub-rotina de processamento são utilizados os nomes de variáveis TK21F02B1_XQ04, formados de acordo com as regras do KKS e com base na tabela de campos da classe. No exemplo acima, as leituras do sensor são calculadas em porcentagem TK21F02B1_XQ03, de acordo com os valores definidos dos campos da instância da classe, como TK21F02B1_Xmin e TK21F02B1_Xmax.
Se nos voltarmos para o código gerado a partir desse esquema, veremos uma atribuição simples de um valor a uma variável, C puro e sem vantagens e POO.
state_vars->su100v12_out_0_ = tk21f02b1_ai;
E atribuição do resultado do cálculo, também como uma atribuição simples de uma variável (com verificação da validade do número, para não abandonar o sistema se recebermos um erro como resultado do processamento do sinal)
if(isfinite(locals->v63_out_0_)){ tk21f02b1_xq04 = locals->v63_out_0_; };
E em que momento aparece a união desses campos da classe de métodos de processamento? De fato, estou familiarizado com duas opções para esse foco. Agora vamos analisar um deles. (A segunda opção é analisada aqui .. )
Vamos ver como o bloco no qual o circuito do programa de processamento está localizado é configurado no diagrama (veja a Fig. 4).
Temos um circuito no qual colocamos blocos de um submodelo de uma linguagem de programação gráfica; dentro desses blocos existe um circuito gráfico, parte do qual é mostrado na Figura 3, um programa para processar sinais de sensores.
Nas propriedades desse bloco, vemos os campos do banco de dados de sinais e uma lista suspensa que contém sinais já existentes no banco de dados, instâncias da classe, sensores específicos desse tipo. Basta escolher o sensor desejado, uma instância da classe pelo nome e um milagre acontece. No esquema, todos os blocos de leitura e gravação recebem nomes do tipo TK21F02B1_XQ03 , (nome do sensor da instância da classe + nome do campo).
Agora, ao gerar o código C, todas as variáveis receberão os valores do sensor desejado. E o programador não é necessário, o tecnólogo fez tudo sozinho ao desenvolver o esquema na linguagem de programação gráfica para o algoritmo de controle da NPP.
Figura 4. Um exemplo de configuração de um circuito de processamento de sensor.Para atribuir os nomes, um script de automação especial é usado no ambiente de design do sistema de controle, aproximadamente o mesmo da Figura 5. Todos os blocos de leitura no diagrama recebem nomes que consistem no nome do objeto e no nome do campo na classe (consulte a Fig. 5).
Figura 5. Configurando o nome das variáveis nos blocos de leitura.É claro que, de maneira semelhante, um número ilimitado de opções de processamento de sinal pode ser criado, essencialmente métodos para a classe na metodologia OOP. Da mesma forma, eles podem ser formados para o sensor, somando-os quando exibidos nos quadros de vídeo do sistema SCADA ou, por exemplo, no processamento de procedimentos para alterar as configurações. Um diagrama é criado em forma gráfica, salvo como um bloco e usado, se necessário.
Resumindo: nas linguagens de programação gráfica, os métodos OOP também são usados e são benéficos. E depois de gerar o código fonte dos programas de controle, todos os artefatos da metodologia OOP desaparecem e permanecem limpos C, seguros, confiáveis e verificados.
É claro que essa aplicação de ferramentas de automação, além de acelerar o desenvolvimento, também pode reduzir significativamente o tempo de desenvolvimento, o número de erros nos programas de controle.