OOP vs prosedürel programlama - sayfa 10

 
Реter Konow :
Evet, bu blokların her ikisi de var. Ama inan bana - çok çeşitli görevleri çözdükleri için maksimum ve evrensel olarak sıkıştırılırlar.

Birkaç seçenek varsa, ifs ve anahtarlarla geçebilirsiniz.

 

Ve neden hiç kimse "işlevlere işaretçiler ile prosedürel programlamaya karşı işlevlere işaretçiler olmadan prosedürel programlama" konusunu tartışmaya karar vermedi?

 
Dmitry Fedoseev :

Birkaç seçenek varsa, ifs ve anahtarlarla geçebilirsiniz.

Mesele şu ki, kodda çok sayıda görevin çözümünü sıkıştırmak için yapılması gereken iş. Buradaki nokta, ek sözdizimsel tekniklerin ve kabukların basitçe ölümcül olduğu kodun evrenselleştirilmesidir. Zor bir iştir, ancak gereksiz her şeyden kurtulur ve yeni zirvelere ulaşırken gelişmenize izin verir.
 

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

2. Önemli olan, ek sözdizimsel tekniklerin ve kabukların basitçe ölümcül olduğu kodun evrenselleştirilmesidir. Zor bir iştir, ancak gereksiz her şeyden kurtulur ve her zaman yeni zirvelere ulaşarak gelişmenize izin verir.


1. Kolay ve basit bir şekilde yapabiliyorsanız neden bu işe yarıyor? Kolayca yapılabilecek bir şeyi neden zorlaştıralım?

2. OOP kullanırsanız , evrenselleştirme ölümcül değildir, ancak doğal, yükü hafifleten bir fırsat haline gelir.

 
Dmitry Fedoseev :

1. Kolay ve basit bir şekilde yapabiliyorsanız neden bu işe yarıyor? Kolayca yapılabilecek bir şeyi neden zorlaştıralım?

2. OOP kullanırsanız , evrenselleştirme ölümcül değildir, ancak doğal, yükü hafifleten bir fırsat haline gelir.

Bu tartışmayı uzun süre devam ettirebiliriz. 100 takip görevi örneğinde, bu çözme yöntemine karşı tavrımı gösterdim. Aptalca belirlenmiş görevlerin çözülmemeli, düzeltilmesi gerektiğini düşünüyorum. OOP, problemlerini doğru bir şekilde belirleme ve etkili bir şekilde çözme yeteneklerinde daha zayıf olanlara yardımcı oluyorsa, onlara yardım etmeye devam etmesine izin verin. Ancak, görevleri çözmeye başlamadan önce optimize eden kişiler için OOP'ye ihtiyaç duyulmayabilir.

 
Реter Konow :

Bu tartışmayı uzun süre devam ettirebiliriz. 100 takip görevi örneğinde, bu çözme yöntemine karşı tavrımı gösterdim. Aptalca belirlenmiş görevlerin çözülmemeli, düzeltilmesi gerektiğini düşünüyorum. OOP, problemlerini doğru bir şekilde belirleme ve etkili bir şekilde çözme yeteneklerinde daha zayıf olanlara yardımcı oluyorsa, onlara yardım etmeye devam etmesine izin verin. Ancak, görevleri çözmeye başlamadan önce optimize eden kişiler için OOP'ye ihtiyaç duyulmayabilir.


Çok fazla kodlamadınız (muhtemelen), OOP temiz bir nefes gibidir.

Temel olarak, insanlar çıkar için değil, kendini geliştirme amacıyla değil, ancak bu onların işi ve bu işte sonuç önemlidir.

 
Dmitry Fedoseev :

Kolaylık açısından yanında durmuyor, ancak performans yetenekleri açısından sadece pointer ile idare edebilirsiniz.

Ve kolaylık göreceli bir kavramdır.


Dmitry, elbette, OOP kullanımı performansı biraz düşürür. Ama bunlar yüzdelik kesirler.

Ancak OOP, programcı üretkenliğini nasıl artırır!

İşte projelerimden birinden küçük bir örnek, algılama hızı için kesilmiş, aslında hala bir sürü şey var.

 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;

Örneğin, tüm API'nin sınıflardan oluştuğu .NET'i alıyoruz.

.NET paradigmasını gerçekten seviyorum, bu arada, doğrudan Visual Studio'da C# ile yazabileceğiniz mükemmel bir cAlgo terminali var.

 
Alexey Volchanskiy :

Dmitry, elbette, OOP kullanımı performansı biraz düşürür. Ama bunlar yüzdelik kesirler.

Az sayıda seçenek varsa, o zaman azalır, ancak çok sayıda seçenek varsa, bir avantaj olacaktır.

En önemlisi, OOP'de hız, seçeneklerin sayısına bağlı değildir. Ve prosedürel programlamada, başınızın üzerinde bir tavan vardır.

 

Neyse batırdılar...

Evet, herhangi bir görevin hem OOP tarzında, arayüzlerin tahsisi, miras hiyerarşisinin inşası , sanal fonksiyonların beyanı ile çözülebileceği açıktır ve tamamen prosedürel bir tarzda - hatta her şeyi bire yapıştırabilirsiniz. büyük işlev.

Sorun, desteğin rahatlığı ve verimliliğidir.

MT'de - OOP'ye en uygun yer sipariş sistemidir. Şahsen, "konumlar" ve "konum bileşenleri" sanal arayüzlerim var. "Pozisyon", MT4'teki bir dizi emir veya bir dizi MT5 pozisyonudur. Bir "pozisyon bileşeni", tek bir sipariş veya tek bir MT5 pozisyonudur (hedge veya ağ).

İşte gerçek arayüz dosyası ( Peter Konow , kod miktarına göre yorum sayısını tahmin edebilirsiniz ve bazı incelikleri hatırlamadığım gerçeğiyle karşılaştığımda periyodik olarak oraya ekliyorum. gerçek nesneler "konum bileşenidir". Sadece bunu hatırlamama gerek yok - EA, arayüze göre bileşenlerle çalışır ve aslında bu arayüzün arkasında neyin durduğu önemli değil. Ancak, değiştirirken buna geri dönmek zorundayım. - bu nedenle, genellikle bu dosyadaki ilk yoruma ihtiyacım var):

 // С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 ;
};

Ticaret bileşeni arayüz dosyası aşağıdaki gibidir (yukarıda zaten verdim ama tekrar edeceğim:

 // С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 ;  
  
};

Bu arayüzlere göre hem gerçek hem de tarihi siparişler için hem MT4 hem de MT5 sipariş sistemlerini uyguladım.

Pozisyon talebinde bulunan bir Uzman Danışman bu arayüzü alır ve MT4 ve MT5 emirleri ile çalışmanın farkını hiç dikkate alması gerekmez. Ayrıca yeni bir emir tipi eklenirse veya onlarla çalışma sırası değişirse Expert Advisor için hiçbir şey değişmeyecek, sadece yeni emir tipinin sınıfı eklenecek ve bu arayüz de desteklenecek.

Riskten korunma hesapları tanıtıldığında sistemin çok makul olduğu kanıtlandı. Uzmanlar hiç değişmedi.

Peter Konow , MT4 ve MT5'te sipariş tiplerindeki farklılık sorununu nasıl çözüyorsunuz?

Yeni bir hesap türü tanıtılırsa (koruma ve netleştirmeye ek olarak) - tek bir yerde hangi değişikliklerin yapılması gerekecek?

Benim düşünceme göre, gerçekten, tüm kodunuzu mektuba hatırlıyorsanız ve bir yıl önce kodunuzda şu veya bu satırın neden yazıldığını kolayca söyleyebilirseniz, o zaman, aslında, tüm bu OOP çanları ve ıslıkları sadece gereksiz jestlerdir. kimsenin ihtiyacı yok.

OOP, kodu değiştirirken her şeyi hatırladığınızda tam olarak gereklidir - OOP, herhangi bir anda mevcut olan varlık setini programdaki belirli bir yerle sınırlamak için blokları birbirinden ayırmanıza izin verir.

 
George Merts :

Neyse batırdılar...

1. Evet, herhangi bir görevin hem OOP tarzında, arayüzlerin tahsisi, bir miras hiyerarşisinin inşası , sanal fonksiyonların beyanı ile çözülebileceği açıktır ve tamamen prosedürel bir tarzda - hatta her şeyi yapıştırabilirsiniz. tek bir büyük işlevde.

Sorun, desteğin rahatlığı ve verimliliğidir.

2. MT'de - OOP'ye en uygun yer sipariş sistemidir. Şahsen, "konumlar" ve "konum bileşenleri" sanal arayüzlerim var. "Pozisyon", MT4'teki bir dizi emir veya bir dizi MT5 pozisyonudur. Bir "pozisyon bileşeni", tek bir sipariş veya tek bir MT5 pozisyonudur (hedge veya ağ).

3. İşte gerçek arayüz dosyası ( Peter Konow , kod miktarına göre yorum sayısını tahmin edebilirsiniz ayrıca bazı incelikleri hatırlamadığım gerçeğiyle karşılaştığımda periyodik olarak oraya ekliyorum. hangi gerçek nesnelerin temsil edildiğini düzenli olarak unut Bunu hatırlamama gerek yok - EA, arayüze göre bileşenlerle çalışır ve bu arayüzün arkasında gerçekte ne olduğu önemsizdir.Fakat, değiştirirken buna geri dönmek zorundayım - bu yüzden Bu dosyada genellikle ilk yorum gerekli olur):

Ticaret bileşeni arayüz dosyası aşağıdaki gibidir (yukarıda zaten verdim ama tekrar edeceğim:

Bu arayüzlere göre hem gerçek hem de tarihi siparişler için hem MT4 hem de MT5 sipariş sistemlerini uyguladım.

Pozisyon talebinde bulunan bir Uzman Danışman bu arayüzü alır ve MT4 ve MT5 emirleri ile çalışmanın farkını hiç dikkate alması gerekmez. Ayrıca yeni bir emir tipi eklenirse veya onlarla çalışma sırası değişirse Expert Advisor için hiçbir şey değişmeyecek, sadece yeni emir tipinin sınıfı eklenecek ve bu arayüz de desteklenecek.

Riskten korunma hesapları tanıtıldığında sistemin çok makul olduğu kanıtlandı. Uzmanlar hiç değişmedi.

4. Reter Konow , MT4 ve MT5'te sipariş tipi farklılığı sorununu nasıl çözüyorsunuz?

Yeni bir hesap türü tanıtılırsa (koruma ve netleştirmeye ek olarak) - tek bir yerde hangi değişikliklerin yapılması gerekecek?

Benim düşünceme göre, gerçekten, tüm kodunuzu mektuba hatırlıyorsanız ve bir yıl önce kodunuzda şu veya bu satırın neden yazıldığını kolayca söyleyebilirseniz, o zaman, aslında, tüm bu OOP çanları ve ıslıkları sadece gereksiz jestlerdir. kimsenin ihtiyacı yok.

OOP, kodu değiştirirken her şeyi hatırladığınızda tam olarak gereklidir - OOP, herhangi bir anda mevcut olan varlık setini programdaki belirli bir yerle sınırlamak için blokları birbirinden ayırmanıza izin verir.

1. Tamamen katılıyorum. Fark, yalnızca sorunları bir şekilde çözme verimliliğindedir.

2. Sipariş sistemiyle pek çalışmadım ve şu anda yapımında teknik bir sorun görmüyorum. Belki öyleler, ancak belirli bir göreve ihtiyaç var ve o zaman OOP olmadan ne kadar etkili çözebileceğim netleşecek.

3. Verilen kod örneği (benim açımdan) okunabilirlik açısından çok kötü. Bu kadar çok yoruma ihtiyaç duyulmasına ve içeriğini neden unuttuğunuza şaşmamalı. Üzgünüm, ama bu benim öznel ilk izlenimim. Sadece biraz ürkütücü.

İşte kodumun okunabilirliğine bir örnek - bir kontrol detayının rengini belirleyen bir fonksiyon:

 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 (Конечный_цвет);
}
//--------------------------------------------------------------------------

Gördüğünüz gibi, burada yorumlara neredeyse gerek yok. Tüm kodum bu tarzda yazılmıştır. Bu nedenle onu çok iyi tanıyorum ve boyu ne olursa olsun onu hatırlıyorum.


Benim düşünceme göre, problem çözme sisteminizde bir çeşit kusur var. Görevin kendisi kristal berraklığında ve kesin olmalıdır ve dolayısıyla çözümü de olmalıdır. Karar belirsizse ve "Sistem kendini çok makul gösterdi" (270 kb kodda nasıl makul olabilir?!) sözleriyle tanımlanmışsa, bu, yazarın sisteminin nasıl çalıştığını yaklaşık olarak anladığı anlamına gelir. Ve sözdiziminin korkunç çanları ve ıslıkları ve çözmede gereksiz olan özü anlaması sonuna kadar engellenir.

Çözümün etkili olabilmesi için gereksiz unsurlar ortadan kaldırılmalı ve problem net bir şekilde görülmelidir.

Neden: