OOP 대 절차 프로그래밍 - 페이지 10

 
Реter Konow :
예, 이 블록에는 둘 다 있습니다. 그러나 저를 믿으십시오. 광범위한 작업을 해결하기 때문에 최대한 보편적으로 압축됩니다.

옵션이 거의 없는 경우 if 및 스위치를 사용하여 해결할 수 있습니다.

 

그리고 왜 아무도 "함수에 대한 포인터가 있는 절차적 프로그래밍 대 함수에 대한 포인터가 없는 절차적 프로그래밍"이라는 주제에 대해 논쟁하기로 결정하지 않았습니까?

 
Dmitry Fedoseev :

옵션이 거의 없는 경우 if 및 스위치를 사용하여 해결할 수 있습니다.

요점은 코드에서 수많은 작업의 솔루션을 압축하기 위해 수행해야 하는 작업입니다. 요점은 코드의 보편화로, 추가 구문 기술과 쉘은 치명적입니다. 힘든 일이지만 불필요한 모든 것을 없애고 새로운 차원에 도달하면서 발전할 수 있게 해줍니다.
 

Реter Konow :
1. Дело в работе которую нужно провести чтобы сжать в коде решения огромного количества задач.

2. 요점은 코드의 보편화로, 추가 구문 기술과 쉘은 치명적입니다. 힘든 일이지만 불필요한 모든 것을 없애고 항상 새로운 높이에 도달하도록 개발할 수 있습니다.


1. 쉽고 간단하게 할 수 있다면 왜 이 일을 합니까? 쉽게 할 수 있는 일을 왜 어렵게 만드는가?

2. OOP를 사용 하면 보편화가 치명적이지는 않지만 자연스럽게 부담되지 않는 기회가 됩니다.

 
Dmitry Fedoseev :

1. 쉽고 간단하게 할 수 있다면 왜 이 일을 합니까? 쉽게 할 수 있는 일을 왜 어렵게 만드는가?

2. OOP를 사용 하면 보편화가 치명적이지는 않지만 자연스럽게 부담되지 않는 기회가 됩니다.

우리는 이 논쟁을 오랫동안 계속할 수 있습니다. 100 후행 과제의 예에서 나는 이 해결 방법에 대한 나의 태도를 보였다. 엉뚱하게 정해진 과제는 해결이 아니라 바로잡아야 한다고 생각합니다. OOP가 자신의 능력이 약한 사람들이 문제를 올바르게 설정하고 효과적으로 해결하는 데 도움이된다면 계속 돕게하십시오. 그러나 문제 해결을 시작하기 전에 작업을 최적화하는 사람들에게는 OOP가 필요하지 않을 수 있습니다.

 
Реter Konow :

우리는 이 논쟁을 오랫동안 계속할 수 있습니다. 100 후행 과제의 예에서 나는 이 해결 방법에 대한 나의 태도를 보였다. 엉뚱하게 정해진 과제는 해결이 아니라 바로잡아야 한다고 생각합니다. OOP가 자신의 능력이 약한 사람들이 문제를 올바르게 설정하고 효과적으로 해결하는 데 도움이된다면 계속 돕게하십시오. 그러나 문제 해결을 시작하기 전에 작업을 최적화하는 사람들에게는 OOP가 필요하지 않을 수 있습니다.


코딩을 많이 하지 않았을 것입니다(아마도). OOP는 신선한 공기를 마시는 것과 같습니다.

기본적으로 사람들은 자기 계발을 목적으로 하지 않고 흥미를 위해 코딩을 하지 않지만 이것이 그들의 일이고 이 일에서 결과가 중요합니다.

 
Dmitry Fedoseev :

편의성 면에서는 옆에 있지 않지만 성능 면에서는 포인터만 있으면 충분합니다.

그리고 편리함은 상대적인 개념입니다.


Dmitry는 물론 OOP를 사용 하면 성능이 약간 저하됩니다. 그러나 이것들은 몇 퍼센트에 불과합니다.

그러나 OOP는 프로그래머 생산성을 어떻게 향상시킵니다!

여기 내 프로젝트 중 하나의 작은 예가 있습니다. 인식 속도를 위해 줄였습니다. 사실, 거기에는 여전히 많은 것들이 있습니다.

 using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

예를 들어 모든 API가 클래스로 구성된 .NET을 사용합니다.

.NET 패러다임이 정말 마음에 듭니다. 그런데 C#으로 Visual Studio에서 직접 작성할 수 있는 우수한 cAlgo 터미널이 있습니다.

 
Alexey Volchanskiy :

Dmitry는 물론 OOP를 사용 하면 성능이 약간 저하됩니다. 그러나 이것들은 몇 퍼센트에 불과합니다.

옵션이 적으면 줄어들지만 많으면 유리합니다.

가장 중요한 것은 OOP에서 속도는 옵션의 수에 의존하지 않는다는 것입니다. 그리고 절차적 프로그래밍에서는 머리 위에 천장이 있습니다.

 

글쎄, 그들은 망했다 ...

예, 인터페이스 할당, 상속 계층 구조 구성, 가상 함수 선언 및 순전히 절차적 스타일로 OOP 스타일에서 모든 작업을 해결할 수 있다는 것은 분명합니다. 모든 작업을 하나로 묶을 수도 있습니다. 거대한 기능.

문제는 지원의 편의성과 효율성이다.

MT에서 가장 OOP에 적합한 곳은 주문 시스템입니다. 개인적으로 "위치" 및 "위치 구성 요소" 가상 인터페이스가 있습니다. "포지션"은 MT4의 주문 집합 또는 MT5 포지션의 집합입니다. "포지션 구성 요소"는 단일 주문 또는 단일 MT5 포지션(헤지 또는 네팅)입니다.

다음은 실제 인터페이스 파일입니다( Peter Konow , 코드 양과 비교하여 주석 수를 추정할 수 있으며 일부 미묘함을 기억하지 못한다는 사실을 발견할 때 주기적으로 거기에 추가합니다. 내가 정기적으로 무엇을 잊어버리는지 가정해 봅시다. 실제 개체는 "위치 구성 요소"입니다. 나는 이것을 기억할 필요가 없습니다 - EA는 인터페이스에 따라 구성 요소와 함께 작동하며 이 인터페이스 뒤에 실제로 무엇이 있는지는 중요하지 않습니다. 하지만 수정할 때 이 항목으로 돌아가야 합니다. - 따라서 이 파일의 첫 번째 주석이 필요한 경우가 많습니다.

 // СTradePositionI переносимый интерфейс торговой позиции 

// Позиция состоит из компонент-наследников интерфейса CTradePosComponentI
// 
// Реально для МТ4 имплементацией интерфейса является объект CMT4PositionInfo, для МТ5 - объект CMT5PositionInfo
// CMT4PositionInfo представляет из себя массив объектов CMT4OrderInfo, наследников интерфейса CTradePosComponentI.
// Фактически это массив МТ4-ордеров.
// CMT5PositionInfo представляет из себя массив объектов CMT5PositionInfoCore, наследников интерфейса CTradePosComponentI.
// Объект CMT5PositionInfoCore не имеет прямого аналога в МТ5-терминах, это два массива ордеров и сделок, а также структура данных,
// имеющуая идентификатор позиции (m_lPosID или POSITION_IDENTIFIER), тикет магик, вид позиции, и так далее, по аналогии с МТ4-ордером,
// фактически, массивы ордеров и сделок - это аналоги ордеров и сделок обычной неттинговой МТ5-позиции, а структура данных - относится
// к хеджевой позиции, и имеет аналог МТ4-ордера. 
//
// Реально при запросе у позиции компоненты CTradePosComponentI в МТ4 мы получаем указатель на ордер (класс CMT4OrderInfo),
// а в МТ5 - на ядро позиции (класс CMT5PositionInfoCore) 



#include <MyLib\DebugOrRelease\DebugSupport.mqh>
#include <MyLib\Common\MyObject.mqh>
#include <MyLib\Common\CurSymEnum.mq5>
#include <MyLib\Common\TrendEnums.mqh>
#include <MyLib\Trade\TradePosComponentI.mqh>

class CTradePositionI: public CMyObject
{
public :
   void CTradePositionI() {    SetMyObjectType(MOT_TRADE_POSITION_I); };
   virtual void ~CTradePositionI() {};
   
   // Выбор существующей позиции. 
   // Указывается магик и символ, по которому выбираются действующие ордера.
   // Если ulMagic = 0 - выбираются все позиции по всем магикам.
   // Если ECurrencySymbol = CS_UNKNOWN - выбираются все позиции по всем символам
   // Если ECurrencySymbol = CS_CURRENT - запрашивается функция Symbol(), и выбираются все позиции по этому символу
   // Возвращает число компонент позиции внутри позиции (может быть нулевым если позиции нет) или WRONG_VALUE в случае ошибок
   // Каждая фабрика (наследник CEAPartsFactoryT) имеет одну позицию, которая на каждом CEAPartsFactoryT::OnRefresh()
   // обновляется в соответствии с магиком и рабочим символом фабрики. 
   virtual int Select( ulong ulMagic = 0 ,ECurrencySymbol csSymbol = CS_CURRENT) = 0 ;

   virtual uint GetTotalComponents() const = 0 ;   // Получение общего числа компонент
   virtual uint GetNumOfComponentsOnDirection( ENUM_POSITION_TYPE etDirection) const = 0 ; // Получение числа компонент указанного направления (если tdDirection = TD_FLAT - то всех компонент)  и интерфейс отдельной компоненты
   virtual CTradePosComponentI* GetComponent( uint uiComponentIdx) const = 0 ;
   
   // Расширенный интерфейс
   
   // Функция исследует позицию, и возвращает ее направление:
   // Если все компоненты - лонги, то вверх.
   // Если все компоненты - шорты, то вниз.
   // Если компонент нет - то флет. 
   // Если компоненты обоих типов, то смотрим на флаг bFlatIfBoth. 
   // Если этот флаг установлен - то возвращаем флет.
   // Если этот флаг сброшен - то смотрим на флаг bConsiderVolume.
   // Если этот флаг установлен - то сравниваем общие объемы лонгов и шортов. Если сброшен - сравниваем количество лонгов и шортов.
   // Каких позиций (или объемов) больше - то направление и возвращаем. 
   // Если позиций (или объемов) одинаково - возвращаем флет.
   // NOTE !!! Функция не проверяет магик и символ компонент !
   virtual ETrendDirection GetDirection( bool bFlatIfBoth = true , bool bConsiderVolume = true ) const = 0 ;
   
   // Функция ищет внутри позиции компоненту с указанным тикетом. 
   // В случае, если ее нет - возвращается false.
   // Если компонента найдена - возвращается true, и uiComponentIdx устанавливается на индекс компоненты внутри позиции.
   virtual bool FindComponentByTicket( long lTicket, uint &uiComponentIdx) const = 0 ;
};

무역 구성 요소 인터페이스 파일은 다음과 같습니다(위에서 이미 제공했지만 반복하겠습니다.

 // СTradePositionComponentI переносимый интерфейс компоненты торговой позиции 

#include <MyLib\DebugOrRelease\DebugSupport.mqh>
#include <MyLib\Common\MyObject.mqh>
#include <MyLib\Common\CurSymEnum.mq5>
#include <MyLib\Common\EnumsMT5ForMT4.mqh>

// CTradePosComponentI - компонента позиции. Имеет определенный магик, определенный символ, определенный тикет.  
// Для МТ4 компонента позиции - это МТ4-ордер.
// Для МТ5 компонента позиции - это МТ5-позиция (одна для каждого символа при неттинге, и много для каждого символа при хедже).

class CTradePosComponentI: public CMyObject
{
public :
   void CTradePosComponentI() {    SetMyObjectType(MOT_TRADEPOS_COMPONENT_I); };
   virtual void ~CTradePosComponentI() {};
   
   // Основной интерфейс
   virtual long                GetTPCTicket()       const = 0 ;
   virtual long                GetTPCMagic()         const = 0 ;
   virtual ECurrencySymbol    GetTPCSymbol()       const = 0 ;
   virtual ENUM_POSITION_TYPE GetTPCType()         const = 0 ;
   virtual datetime            GetTPCOpenTime()     const = 0 ;
   virtual double              GetTPCVolume()       const = 0 ;
   virtual double              GetTPCOpenPrice()     const = 0 ;
   virtual double              GetTPCStopLoss()     const = 0 ;
   virtual double              GetTPCTakeProfit()   const = 0 ;
   virtual string              GetTPCCommentary()   const = 0 ;
   
   virtual bool                IsTPCInUnloss() const { if (GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE ) return ( false ); if (GetTPCType() == POSITION_TYPE_BUY ) { if (GetTPCStopLoss() >= GetTPCOpenPrice()) return ( true ); } else { if (GetTPCStopLoss() <= GetTPCOpenPrice()) return ( true ); }; return ( false ); };
   virtual double              GetTPDistance() const { if (GetTPCTakeProfit() == 0 || GetTPCTakeProfit() == EMPTY_VALUE ) return ( EMPTY_VALUE ); if (GetTPCType() == POSITION_TYPE_BUY ) return (GetTPCTakeProfit() - GetTPCOpenPrice()); return (GetTPCOpenPrice() - GetTPCTakeProfit());  };
   virtual double              GetSLDistance() const { if (GetTPCStopLoss() == 0 || GetTPCStopLoss() == EMPTY_VALUE ) return ( EMPTY_VALUE ); if (GetTPCType() == POSITION_TYPE_BUY ) return (GetTPCOpenPrice()- GetTPCStopLoss()); return (GetTPCStopLoss() - GetTPCOpenPrice());  };
};

class CHistoryPosComponentI: public CTradePosComponentI
{
public :
   void CHistoryPosComponentI() {    SetMyObjectType(MOT_HISTORYPOS_COMPONENT_I); };
   virtual void ~CHistoryPosComponentI() {};

   virtual datetime            GetTPCCloseTime()     const = 0 ;
   virtual double              GetTPCClosePrice()   const = 0 ;
   virtual double              GetTPCProfit()       const = 0 ;   // Возвращает профит по исторической позиции
   
   virtual bool                IsProfitClosePrice() const = 0 ;   // Возвращает true, если цена зарытия отличается от цены открытия в прибыльную сторону   
   
   // Возвращает профит исторической позиции для случая, когда бы ход цены (в сторону профита) был бы равен dPriceMove, а лот был бы единичным.
   // Функция используется для расчета лота для такой же позиции с нужным ходом цены 
   // Рекомендуется отнимать от цены двойной спред.
   virtual double              CalculateOneLotProfit( double dPriceMove) const = 0 ;  
  
};

이러한 인터페이스에 따르면 실제 및 과거 주문 모두에 대해 MT4 및 MT5 주문 시스템을 모두 구현했습니다.

직위를 요청한 Expert Advisor는 이 인터페이스를 수신하며 MT4 및 MT5 주문 작업의 차이점을 전혀 고려할 필요가 없습니다. 또한 새 주문 유형이 추가되거나 작업 순서가 변경되면 Expert Advisor에 대해 아무 것도 변경되지 않고 새 주문 유형의 클래스만 추가되고 이 인터페이스도 지원합니다.

이 시스템은 헤지 계정이 도입되었을 때 매우 합리적인 것으로 판명되었습니다. 전문가들은 전혀 변하지 않았습니다.

Peter Konow , MT4와 MT5의 주문 유형이 다른 문제를 어떻게 해결합니까?

새로운 유형의 계정이 도입되면(헤지 및 상계 외에) - 한 곳에서 어떤 변경이 필요합니까?

내 생각에, 정말로, 당신이 편지의 모든 코드를 기억하고 이 또는 저 줄이 1년 전에 당신의 코드에 쓰여진 이유를 쉽게 말할 수 있다면, 실제로 이 모든 OOP 종소리와 휘파람은 단지 불필요한 제스처일 뿐입니다. 아무도 필요하지 않습니다.

OOP는 코드를 수정할 때 모든 것을 멀리 기억할 때 정확히 필요합니다. OOP를 사용하면 블록을 서로 분리하여 주어진 순간에 사용 가능한 엔터티 집합을 프로그램의 특정 위치로 제한할 수 있습니다.

 
George Merts :

글쎄, 그들은 망했다 ...

1. 예, 인터페이스 할당, 상속 계층 구조 구성, 가상 함수 선언 및 순수 절차적 스타일로 OOP 스타일에서 모든 작업을 해결할 수 있다는 것은 분명합니다. 모든 작업을 고정할 수도 있습니다. 하나의 거대한 기능으로.

문제는 지원의 편의성과 효율성이다.

2. MT에서 - OOP에 가장 적합한 곳은 주문 시스템이다. 개인적으로 "위치" 및 "위치 구성 요소" 가상 인터페이스가 있습니다. "포지션"은 MT4의 주문 집합 또는 MT5 포지션의 집합입니다. "포지션 구성 요소"는 단일 주문 또는 단일 MT5 포지션(헤지 또는 네팅)입니다.

3. 여기 실제 인터페이스 파일이 있습니다( Peter Konow , 코드 양에 비해 주석 수를 추정할 수 있습니다. 또한 일부 미묘함을 기억하지 못하는 사실이 발견되면 주기적으로 거기에 추가합니다. 어떤 실제 객체가 나타내는지 정기적으로 잊어버리기 나는 이것을 기억할 필요가 없습니다 - EA는 인터페이스에 따라 구성 요소와 함께 작동하며 이 인터페이스 뒤에 실제로 있는 것은 중요하지 않습니다. 나는 종종 이 파일의 첫 번째 주석이 필요합니다):

거래 구성 요소 인터페이스 파일은 다음과 같습니다(위에서 이미 제공했지만 반복하겠습니다.

이러한 인터페이스에 따르면 실제 및 과거 주문 모두에 대해 MT4 및 MT5 주문 시스템을 모두 구현했습니다.

직위를 요청한 Expert Advisor는 이 인터페이스를 수신하며 MT4 및 MT5 주문 작업의 차이점을 전혀 고려할 필요가 없습니다. 또한 새 주문 유형이 추가되거나 작업 순서가 변경되면 Expert Advisor에 대해 아무 것도 변경되지 않고 새 주문 유형의 클래스만 추가되고 이 인터페이스도 지원합니다.

이 시스템은 헤지 계정이 도입되었을 때 매우 합리적인 것으로 판명되었습니다. 전문가들은 전혀 변하지 않았습니다.

4. Reter Konow , MT4와 MT5의 주문 유형이 다른 문제를 어떻게 해결합니까?

새로운 유형의 계정이 도입되면(헤지 및 상계 외에) - 한 곳에서 어떤 변경이 필요합니까?

내 생각에, 정말로, 당신이 편지의 모든 코드를 기억하고 이 또는 저 줄이 1년 전에 당신의 코드에 쓰여진 이유를 쉽게 말할 수 있다면, 실제로 이 모든 OOP 종소리와 휘파람은 단지 불필요한 제스처일 뿐입니다. 아무도 필요하지 않습니다.

OOP는 코드를 수정할 때 모든 것을 멀리 기억할 때 정확히 필요합니다. OOP를 사용하면 블록을 서로 분리하여 주어진 순간에 사용 가능한 엔터티 집합을 프로그램의 특정 위치로 제한할 수 있습니다.

1. 전적으로 동의합니다. 차이점은 어떤 방식으로든 문제를 해결하는 효율성에만 있습니다.

2. 나는 주문 시스템으로 많은 일을 하지 않았고, 지금은 그 구성에 어떤 기술적인 문제도 보이지 않는다. 그럴 수도 있겠지만 특정 작업이 필요하고 OOP 없이 얼마나 효과적으로 해결할 수 있는지 명확해질 것입니다.

3. 주어진 코드 예제(내 관점에서)는 단순히 가독성 측면에서 끔찍합니다. 너무 많은 주석이 필요하고 왜 그 내용을 잊어버리는지 놀랄 일이 아닙니다. 죄송하지만 주관적인 첫인상입니다. 그것은 일종의 소름 끼치는 일입니다.

다음은 제어 세부 정보의 색상을 결정하는 함수인 내 코드의 가독성에 대한 예입니다.

 int Цвет_детали( int Окно, int Деталь_полотна, int Ячейка_состояния, int GAC = 0 )
{
 int Alfa;
 int Цвет_детали;
 int Конечный_цвет;
 int Непрозрачность_детали;
 //--------------------------------------------------------------------------
 int Элемент                     =  G_CORE[Окно][Деталь_полотна][_MAIN_ELEMENT];
 int Состояние_детали            =  G_CORE[Окно][Элемент][_CURRENT_STATE]; 
 int Категория_детали            =  G_CORE[Окно][Деталь_полотна][_OBJECT_CATEGORY];
 int Подкатегория_детали         =  G_CORE[Окно][Деталь_полотна][_OBJECT_SUBCATEGORY];
 int Составной_элемент           =  G_CORE[Окно][Деталь_полотна][_OBJECT_IN_ELEMENT_NUMBER];
 int Тип_элемента                =  G_CORE[Окно][Деталь_полотна][_OBJECT_GROUP];
 int Тип_детали                  =  G_CORE[Окно][Деталь_полотна][_SUB_ELEMENT_GROUP];
 int Элемент_под_курсором        =  G_CORE[Окно][Элемент]       [_ELEMENT_POINTED];
 int Состояние_элемента          =  G_CORE[Окно][Элемент]       [_CURRENT_STATE];
 int Пиксель_детали              =  G_CORE[Окно][Деталь_полотна][_PIXEL_INDEX];
 int Канвас_детали               =  G_CORE[Окно][Деталь_полотна][_DROWING_CANVAS];
 int Пиксель_канваса_детали      =  G_CORE[Окно][Канвас_детали][_PIXEL_INDEX];
 int Состояние_канваса_детали    =  G_CORE[Окно][Канвас_детали][_CURRENT_STATE];
 int Ячейка_состояния_канваса    =  G_CORE[Окно][Канвас_детали][_NEUTRAL_STATE];
 //-------------------------------------
 int Цвет_пикселя_канваса_детали =  STANDART_GROUPS[Ячейка_состояния_канваса + 3 + Пиксель_канваса_детали* 2 ];
 //-------------------------------------
 if (
       (Состояние_элемента == _NEUTRAL_BLOCKED || Состояние_элемента == _ACTIVATED_BLOCKED)
    && (Тип_элемента == BUTTON || Тип_элемента == TB_BUTTON || Тип_элемента == H_TAB || Тип_элемента == V_TAB || Тип_элемента == VIEW_BOX) 
   )
   {
     if (Тип_детали != _VIEW_BOX_VR_SCROLL_BAR && Тип_детали != _VIEW_BOX_HR_SCROLL_BAR)
      {
       Alfa = 255 + GAC;
       if (Alfa < 0 )Alfa = 0 ;      
       return ( ColorToARGB (Цвет_пикселя_канваса_детали,Alfa));
      }
     if (Тип_детали == _VIEW_BOX_VR_SCROLL_BAR || Тип_детали == _VIEW_BOX_HR_SCROLL_BAR)
      {
       Alfa = 255 + GAC;
       if (Alfa < 0 )Alfa = 0 ;        
       return ( ColorToARGB ( clrLightGray ,Alfa));
      }   
   }
 //-------------------------------------
 if (!Состояние_элемента)Состояние_элемента = _NEUTRAL_STATE;
 //-------------------------------------
 int Цвет_пикселя           = Данные_пикселя[Пиксель_детали][Цвет];
 int Непрозрачность_пикселя = Данные_пикселя[Пиксель_детали][Непрозрачность];
 //-------------------------------------
 if (G_CORE[Окно][Деталь_полотна][_CUSTOM_BACKGROUND_COLOR]  && Состояние_элемента == _NEUTRAL_STATE) 
   {
    Цвет_детали = G_CORE[Окно][Деталь_полотна][_CUSTOM_BACKGROUND_COLOR];
   } 
 //-------------------------------------
 if (!G_CORE[Окно][Деталь_полотна][_CUSTOM_BACKGROUND_COLOR] || Состояние_элемента != _NEUTRAL_STATE) 
   {
    Цвет_детали = Данные_пикселя[Пиксель_детали][Цвет];
   } 
 //-------------------------------
 if (G_CORE[Окно][Деталь_полотна][_ELEMENT_POINTED]) 
   {
     if (
          (ТИП_ЭЛЕМЕНТА ==  C_HEADER && МЕНЯЕМАЯ_ШИРИНА_СТОЛБЦОВ) 
       || (((Тип_элемента == _C_CELL || Тип_элемента == _D_CELL)   && G_CORE[Окно][Деталь_полотна][_R_HEADER] == РЯД_В_ФОКУСЕ) && ТАБЛИЦА_ИНТЕРАКТИВНА)
       || ((Тип_элемента == _CELL    || Тип_элемента ==  R_HEADER) && ТАБЛИЦА_ИНТЕРАКТИВНА)
      )
      { if (Тип_элемента == _C_CELL && ТАБЛИЦА_ИНТЕРАКТИВНА) Alert ( __FUNCTION__ , "  Деталь_полотна   " ,Деталь_полотна);
       Цвет_детали = C'210,224,237' ;
      }
     //------------------------------------------------
     if (ТИП_ЭЛЕМЕНТА == _SIMPLE_BUTTON) if (Состояние_элемента == _NEUTRAL_STATE)Цвет_детали = C'250,250,250' ;
     //------------------------------------------------ 
     if (ТИП_ЭЛЕМЕНТА == TS_BUTTON)
      {
       Цвет_детали =   C'210,224,237' ;
       Непрозрачность_детали = 100 ;
       Alfa = Непрозрачность_детали + GAC;
       if (Alfa < 0 )Alfa = 0 ;    
       Конечный_цвет = ColorToARGB (Цвет_детали,Alfa);
       //--------------------------------------------------------------------------
       return (Конечный_цвет);
      } 
     //------------------------------------------------  
     if (Тип_элемента == M_CHECKBOX)
      {
       Цвет_детали = C'210,224,237' ;
      }
     //------------------------------------------------ 
   }    
 //--------------------------------------------------------------------------
 if (!G_CORE[Окно][Деталь_полотна][_CUSTOM_BACKGROUND_TRANSPERANCY]) Непрозрачность_детали = Данные_пикселя[Пиксель_детали][Непрозрачность];
 else Непрозрачность_детали = G_CORE[Окно][Деталь_полотна][_CUSTOM_BACKGROUND_TRANSPERANCY];
 //--------------------------------------------------------------------------
 if (
       Тип_детали == CHECKBOX 
    || Тип_детали == RADIO_BUTTON 
    || Тип_детали == DROP_LIST 
    || Тип_детали == EDIT_BOX 
    || Тип_детали == SPIN_EDIT 
     // 
    ||(( /*Тип_детали == TV_ITEM ||*/ Тип_детали == TV_CHECKBOX
    || Тип_детали == G_FOLDER
    || Тип_детали == TV_MENU)  && (Составной_элемент == BASE_SUB_ELEMENT || (Составной_элемент == BASE_SUB_ELEMENT_2 && Состояние_детали != _ACTIVATED_HIGHLIGHTED && Состояние_детали != _NEUTRAL_HIGHLIGHTED)))
   )
   {
    Цвет_детали = Цвет_пикселя_канваса_детали;  
    Непрозрачность_детали = 255 ;
   }
 //--------------------------------------------------------------------------
 //Определение цвета ползунка на различных событиях.
 //--------------------------------------------------------------------------
 if (Категория_детали == _SCROLL_BAR_HANDLE && ((КАТЕГОРИЯ_ОБЪЕКТА == _SCROLL_BAR_HANDLE || КАТЕГОРИЯ_ОБЪЕКТА == _SCROLL_BAR || КАТЕГОРИЯ_ОБЪЕКТА == _SCROLL_BAR_BUTTON) || СОБЫТИЕ_ИНТЕРФЕЙСА == _SCROLLER_EVENT))
   {
     if ((КАТЕГОРИЯ_ОБЪЕКТА == _SCROLL_BAR_HANDLE && Деталь_полотна == ОБЪЕКТ) || (СОБЫТИЕ_ИНТЕРФЕЙСА == _SCROLLER_EVENT && Подкатегория_детали == _VERTICAL_SCROLL_BAR_HANDLE))
      {
       if (СОБЫТИЕ_ИНТЕРФЕЙСА == _OBJECT_POINTED || СОБЫТИЕ_ИНТЕРФЕЙСА == _OBJECT_RELEASED)      Цвет_детали = C'166,166,166' ; 
       if (Ползунковая_прокрутка) Цвет_детали = C'96,96,96' ; //|| СОБЫТИЕ_ИНТЕРФЕЙСА == _SCROLLER_EVENT 
      } 
     //--------------------------  
   if (СОБЫТИЕ_ИНТЕРФЕЙСА == _OBJECT_POINTED || СОБЫТИЕ_ИНТЕРФЕЙСА == _OBJECT_RELEASED ||  СОБЫТИЕ_ИНТЕРФЕЙСА == _OBJECT_LEFT_CLICKED || Кнопочная_прокрутка)
      {
       if (КАТЕГОРИЯ_ОБЪЕКТА == _SCROLL_BAR && Деталь_полотна == ОБЪЕКТ + 2 )Цвет_детали = C'200,200,200' ;  
       //-------------------------- && Деталь_полотна == ОБЪЕКТ - 3 && Деталь_полотна == ОБЪЕКТ - 1
       if (
             КАТЕГОРИЯ_ОБЪЕКТА == _SCROLL_BAR_BUTTON 
          && (
               (
                  (ПОДКАТЕГОРИЯ_ОБЪЕКТА == _SBUB && Подкатегория_детали == _VSBH)
               || (ПОДКАТЕГОРИЯ_ОБЪЕКТА == _SBDB && Подкатегория_детали == _VSBH)
               ) 
              ||   
               (
                  (ПОДКАТЕГОРИЯ_ОБЪЕКТА == _SBLB && Подкатегория_детали == _HSBH)
               || (ПОДКАТЕГОРИЯ_ОБЪЕКТА == _SBRB && Подкатегория_детали == _HSBH)
               )               
             )
             
         )
         { //Alert(__FUNCTION__,"  Деталь_полотна   ",Деталь_полотна,"  Непрозрачность_детали   ",Непрозрачность_детали);
          Цвет_детали = C'200,200,200' ; 
         } 
      }
    }  
 //--------------------------------------------------------------------------
// 
 Alfa = Непрозрачность_детали + GAC;
 if (Alfa < 0 )Alfa = 0 ;    
 Конечный_цвет = ColorToARGB (Цвет_детали,Alfa);
 //--------------------------------------------------------------------------
 return (Конечный_цвет);
}
//--------------------------------------------------------------------------

보시다시피 여기에서는 주석이 거의 필요하지 않습니다. 내 모든 코드는 이 스타일로 작성되었습니다. 그러므로 나는 그를 아주 잘 알고 있으며 그가 어떤 키를 가지고 있더라도 그를 기억합니다.


제 생각에는 문제 해결 시스템에 일종의 결함이 있습니다. 작업 자체는 수정처럼 명확하고 정확해야 하므로 솔루션도 마찬가지입니다. 솔루션이 모호하고 "시스템 자체가 매우 합리적인 것으로 나타났습니다"(270kb 코드에서 합리성이 무엇입니까?!)라는 단어로 정의된 경우 이는 작성자가 시스템 작동 방식을 대략적으로 이해하고 있음을 의미합니다. 그리고 풀이에 불필요한 문법과 본질의 끔찍한 종소리와 휘파람에 의해 그는 끝까지 이해를 방해합니다.

솔루션이 효과적이려면 불필요한 요소가 차단되어야 하고 문제가 완벽하게 명확해야 합니다.

사유: