Questions on OOP in MQL5 - page 21

 
Alexey Navoykov:
Is this a purely test class or are you really going to use it?
If it's the latter, you shouldn't do that. Static variables are not reinitialised when a character changes, as far as I remember.
And in general, it's not a good idea to initialize constant statics with external values, which are not necessarily available at the time of initialization.

Thesecond, I am writing anyway under MT4, even for myself - it does not work in the tester for a few symbols, if I see something useful in MT4, I will switch to MT5 using MT4Orders - I checked my "creative work" without problems with this library

first, i want to see the idea of a proper OOP - that's why i'm testing it, to see what will come out, so far it's going quite messy.... we'll see, i have time, here's the charger i decided to make myself ))))


i know it's not the best way to initialize before the start of the main code, or rather i used to think so, but i have never checked it, no matter how many new builds i had - in MQL everything is always available, even at global visibility level, i saw the sources people go straight to the top and write it that way:

#property strict
int    dig = _Digits;
double point = _Point;
double startbalance = AccountBalance();

and these incorrect initializations have been working for years from build to build. Generally, the developers spoiled the people ))))




SZZY: here in general, as always when using OOP - the main thing is to correctly divide the problem into complex elements and not to inherit from everything at hand. I don't know where to "stick" text output errors - it should be everywhere, in any class and in any place of the program, most likely you will have to create a base class as@Vladimir Simakov showed above his code

 
Igor Makanu:

pp 1-3 all solvable, BUT... OK, here with the statics helped, let it be so because there is a help, at least something to justify his decision, now the code is the following:

created 3 instances of Cdeal, got in the log:

...

so far everything is working as intended!

Even if it works, it is not reliable. Since the function is implemented outside the class, it is difficult to control the order of fields in the class itself. You should at least write a bold comment in the class saying that such and such fields must not be rearranged). But your initial variant was better anyway. You should not sacrifice security to save a line of code )
 
Alexey Navoykov:
But all the same, your original version was better. Don't sacrifice reliability to save a line of code )

which one? - I've got half the topic in my variations ))))

but yeah, you're right a hundred percent!

SZY:

the simplest and most reliable way - create an instance of the class via new in OnInit() - and copy all the terminal environment variables immediately, but it's not the best way - if I plan to open an order immediately at startup of the constructor in this example, then this instance of the class will probably be deleted and then possibly re-created - this already brings up some issues because of repeated calls - I start loading the terminal again, again wasting memory.... in general, it is not solvable this way


ZZZY: maybe another day of experiments, and eventually take@Vladimir Simakov example - everything is very clear there

 
Igor Makanu:

I sketched out my class, which should initialise fields once with constant values, and it seems to work as intended:

I don't like 2 things:

1. I repeat calling SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP) - because order of initialization is not defined, i.e. it's not sure that VolumeSTEP will be initialized first and only then GetDigitsInVolumeStep() will be called

2. I want to get rid of static method static int GetDigitsInVolumeStep() - I've seen a video on youtube saying that in pure OOP one should not use static methods, and now I'm fighting against windmills

the link to the video, it is essentially the samehttps://youtu.be/lfdAwl3-X_c andhttps://youtu.be/zME4SOCHT0I


how can i rewrite these 2 points which i don't like?

1. There is nothing wrong with calling this function twice.

2. Doesn't it confuse you that those who are against using static functions don't give the slightest argument?

You'd better not watch videos from just anyone, but read books.

 
Koldun Zloy:

2. are you not confused that those who are against the use of static functions do not give the slightest argument?

And you are the first to support me that the video does not correspond to anything from practice, I wrote in another thread my opinion about the video - the speaker could not even answer students' questions

 
Igor Makanu:

and you are the first to back me up that the video doesn't match anything from practice, I wrote in another thread my opinion about the video - the reporter couldn't even answer students' questions

I don't think OOP is about cutting back on one's own capabilities for the sake of blindly following the unfounded postulates of some Internet mouthpieces, where everyone sweeps in their own way.

 
Artyom Trishkin:

I don't think that OOP is the reduction of one's own capabilities for the sake of blindly following the unfounded postulates of some Internet mouthpieces, where everyone sweeps in his own way.

if you have seen the video, you should understand that the target is .... well, in general, you also do not understand anything and are not yet mature enough - at least that's how A100 explained it to me

SZZ: I'll experiment a bit later with interfaces, maybe some "entity-beauty" will appear ))))

 

I watched his video on statics, all for the sake of writing like that:

new Type0(new Type1(new Type2(...))); 

Well, writing a wrapper over a statics is a problem, isn't it?

class Stateless_with_state {
        Stateless q;
        Data d;
        call() {q::call(d);}
};

And through templates are clearly more efficient. I liked the question from the audience https://www.youtube.com/watch?v=75U9eefFYoU#t=33m25s

 
Igor Makanu:

ZS: I'll experiment with interfaces a bit later, maybe some "entity-beauty" will appear ))))

Checked if "OOP pattern - Behavioural patterns - Strategy" will work

interface IStrategy
  {
   void Algorithm();
  };
//+------------------------------------------------------------------+
class Strategy_1 : public IStrategy
  {
public:
                     Strategy_1()   {Print(__FUNCTION__);}
   void              Algorithm()    {Print(__FUNCTION__);}
  };
//+------------------------------------------------------------------+
class Strategy_2 : public IStrategy
  {
public:
                     Strategy_2()   {Print(__FUNCTION__);}
   void              Algorithm()    {Print(__FUNCTION__);}
  };
//+------------------------------------------------------------------+
class Context
  {
private:
   IStrategy         *s;
public:
                     Context(IStrategy &_strategy) {Print(__FUNCTION__); s = GetPointer(_strategy); s.Algorithm();}
                    ~Context() {delete s;}
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   Context c1(new Strategy_1);
   Context c2(new Strategy_2);
  }
//+------------------------------------------------------------------+

2019.08.31 21:04:40.441 tst (EURUSD,H1) Strategy_1::Strategy_1

2019.08.31 21:04:40.442 tst (EURUSD,H1) Context::Context

2019.08.31 21:04:40.442 tst (EURUSD,H1) Strategy_1::Algorithm

2019.08.31 21:04:40.442 tst (EURUSD,H1) Strategy_2::Strategy_2

2019.08.31 21:04:40.442 tst (EURUSD,H1) Context::Context

2019.08.31 21:04:40.442 tst (EURUSD,H1) Strategy_2::Algorithm


Works without any problems in my opinion

 
Igor Makanu:

checked if the "OOP Pattern - Behavioural Patterns - Strategy (Strategy)" will work

2019.08.31 21:04:40.441 tst (EURUSD,H1) Strategy_1::Strategy_1

2019.08.31 21:04:40.442 tst (EURUSD,H1) Context::Context

2019.08.31 21:04:40.442 tst (EURUSD,H1) Strategy_1::Algorithm

2019.08.31 21:04:40.442 tst (EURUSD,H1) Strategy_2::Strategy_2

2019.08.31 21:04:40.442 tst (EURUSD,H1) Context::Context

2019.08.31 21:04:40.442 tst (EURUSD,H1) Strategy_2::Algorithm


works without any problems for me

Context(IStrategy* _strategy):s(_strategy){Print(__FUNCTION__); s.Algorithm();}

The new operator returns a pointer. Of course, the developers screwed up with implicit dereferencing and that's why your version works, but I'd rather not get hung up on undocumented things.

2. It's certainly not C++, but it's very similar, so initialisation lists (I don't know about efficiency) are kosher.

Reason: