Hi Chris,

By having the behavior of the driver defined, each object generated by the
driver (based on the mspec) must add its control logic.

In general, the way to solve the answers is based on the differentiation of
the classes in two ways, using "instanceof" or checking the values of the
"properties".

In code it would be something like this:

if (payloadItems[0] instanceof
S7PayloadUserDataItemCpuFunctionMsgSubscriptionResponse) {
...
} else if (payloadItems[0] instanceof
S7PayloadUserDataItemCpuFunctionMsgSubscriptionSysResponse) {
...
} else if (payloadItems[0] instanceof
S7PayloadUserDataItemCpuFunctionMsgSubscriptionAlarmResponse) {
...
}  else if (payloadItems[0] instanceof
S7PayloadUserDataItemCpuFunctionAlarmAckResponse) {
...
}   else if (payloadItems[0] instanceof
S7PayloadUserDataItemCpuFunctionAlarmAckErrorResponse) {
...
}

An so on, and

if ((myparameter.getCpuFunctionGroup() == 0x04) &&
(myparameter.getCpuFunctionType() == 0x00) &&
(myparameter.getCpuSubfunction() == 0x03)) {
...
} else if ((myparameter.getCpuFunctionGroup() == 0x02) &&
(myparameter.getCpuFunctionType() == 0x00) &&
(myparameter.getCpuSubfunction() == 0x01)){
...
} else if  ((myparameter.getCpuFunctionGroup() == 0x02) &&
(myparameter.getCpuFunctionType() == 0x00) &&
(myparameter.getCpuSubfunction() == 0x05)) {
...
}

And so on

This is something that works and solves the problem, it is not in
discussion, and it is a good interceptor point for other languages, but how
can we help make it more readable and automatic from the mspec.


@startuml
interface Message
Message : public void accept(MessageVisitor visitor);

class S7PayloadUserDataItem
Message <-- S7PayloadUserDataItem
S7PayloadUserDataItem <--
S7PayloadUserDataItemCpuFunctionMsgSubscriptionResponse
S7PayloadUserDataItem <--
S7PayloadUserDataItemCpuFunctionMsgSubscriptionSysResponse
S7PayloadUserDataItem <--
S7PayloadUserDataItemCpuFunctionMsgSubscriptionAlarmResponse
S7PayloadUserDataItem <-- S7PayloadUserDataItemCpuFunctionAlarmAckResponse
S7PayloadUserDataItem <--
S7PayloadUserDataItemCpuFunctionAlarmAckErrorResponse

S7PayloadUserDataItemCpuFunctionMsgSubscriptionResponse : public void
accept(MessageVisitor visitor);
S7PayloadUserDataItemCpuFunctionMsgSubscriptionSysResponse : public void
accept(MessageVisitor visitor);
S7PayloadUserDataItemCpuFunctionMsgSubscriptionAlarmResponse : public void
accept(MessageVisitor visitor);
S7PayloadUserDataItemCpuFunctionAlarmAckResponse : public void
accept(MessageVisitor visitor);
S7PayloadUserDataItemCpuFunctionAlarmAckErrorResponse : public void
accept(MessageVisitor visitor);
@enduml

The only code required within each generated instance is

S7PayloadUserDataItemCpuFunctionMsgSubscriptionResponse() {
...
   public void accept(MessageVisitor visitor) {
       v.visit(this);
   }
...
}

Now the visitor interface can be generated manually or from the mspec.

@startuml
interface S7MessageVisitor
S7MessageVisitor : public void
visit(S7PayloadUserDataItemCpuFunctionMsgSubscriptionResponse visitable);
S7MessageVisitor : public void
visit(S7PayloadUserDataItemCpuFunctionMsgSubscriptionSysResponse visitable);
S7MessageVisitor : public void
visit(S7PayloadUserDataItemCpuFunctionMsgSubscriptionAlarmResponse
visitable);
S7MessageVisitor : public void
visit(S7PayloadUserDataItemCpuFunctionAlarmAckResponse visitable);
S7MessageVisitor : public void
visit(S7PayloadUserDataItemCpuFunctionAlarmAckErrorResponse visitable);
@enduml

Having this interface defined, we can implement directly on the protocol
logic object, in the case of S7 "S7ProtocolLogic".

After implementing the logic associated with the objects, the main code
would look like:

...
payloadItems [0] .accept (this);
...

Something more elegant, I think.

For the control of the state machine we would surely have to pass specific
parameters, so the interface of the visitors should be something like:

public void accept (MessageVisitor visitor, Object ... args);

or something similar,

As for why this pattern applies to our case.

1. The objects associated with the protocol do not change over time, unless
the protocol is changed, which in itself is another protocol.
2. The objects generated by the mspec only have properties and not
associated logic.
3. The logic associated with each object can be implemented by the Visitor
pattern, which from my point of view generates more organized code, while
remaining optional.

My grain of sand,




El mar, 9 nov 2021 a las 5:45, Christofer Dutz (<christofer.d...@c-ware.de>)
escribió:

> Hi Cesar,
>
> could you possibly whip up some example code that shows how it's currently
> done and how you propose to do it?
>
> Sebastian and I are currently greatly refactoring the code-generation, so
> now would be a perfect time for optimizing things.
>
> Chris
>
> -----Ursprüngliche Nachricht-----
> Von: Cesar Garcia <cesar.gar...@ceos.com.ve>
> Gesendet: Montag, 8. November 2021 21:02
> An: Apache PLC4X <dev@plc4x.apache.org>
> Betreff: Visitor pattern
>
> Hi everyone,
>
> I have a query for you.
>
> In the case of mspec for Java, would it be possible to include the VSD
> (Visitor Design Pattern) in the generated classes?
>
> This is because most of the code uses "instanceof" for the differentiation
> of the message objects in the implementation of the S7 driver, this in
> conjunction with the field values.
>
> With this pattern we could have a much more elegant driver in the
> implementation.
>
> If you have observations it would be interesting to hear them,
>
> Best regards,
>
> --
> *CEOS Automatización, C.A.*
> *GALPON SERVICIO INDUSTRIALES Y NAVALES FA, C.A.,* *PISO 1, OFICINA 2, AV.
> RAUL LEONI, SECTOR GUAMACHITO,*
>
> *FRENTE A LA ASOCIACION DE GANADEROS,BARCELONA,EDO. ANZOATEGUI* *Ing.
> César García*
>
> *Cel: +58 414-760.98.95*
>
> *Hotline Técnica SIEMENS: 0800 1005080*
>
> *Email: support.aan.automat...@siemens.com
> <support.aan.automat...@siemens.com>*
>


-- 
*CEOS Automatización, C.A.*
*GALPON SERVICIO INDUSTRIALES Y NAVALES FA, C.A.,*
*PISO 1, OFICINA 2, AV. RAUL LEONI, SECTOR GUAMACHITO,*

*FRENTE A LA ASOCIACION DE GANADEROS,BARCELONA,EDO. ANZOATEGUI*
*Ing. César García*

*Cel: +58 414-760.98.95*

*Hotline Técnica SIEMENS: 0800 1005080*

*Email: support.aan.automat...@siemens.com
<support.aan.automat...@siemens.com>*

Reply via email to