Δευτέρα 13 Ιουλίου 2020

Prototype Pattern (OOP)

Sometimes the cost to retrieve data is bigger than to copy data. So we have to encapsulate data in an object and using a clone() function we have a proper clone (deep) and we can pass it to other consumers. Here we have one prototype the AnalysisData. We have an Analysis class which has a AnalysisData. We make the AnalysisData (here by append values to a stack object), and two concrete analysis classes which inherit from Analysis class and use these to make A1 and A2 by sending to constructor a clone of an AnalysisData. As last operation we pass the AnalysisData without cloning and we see that the data from stack consumed (we get length=0). Each concrete Analysis object (group is the name in M2000) consume the values in one pass, popping the values from stack.



\\ Class AnalysisData has a Clone() function
\\ Clone() copy the stack a making a new pointer
\\ By default all groups in M2000 are like prototypes  but not as in javascript
\\ In M2000 groups are flat, or may have other inner groups
\\ inner groups are values too, so they clone as outer group
\\ members as Arrays with names with parenthesis also copied, but shallow
\\ all other members which are pointers just copy the pointer
\\ so a clone function may used to perform a deep copy


\\ in prototype pattern  the analysisdata class is the prototype
\\ this has the clone() function
Class AnalysisData {
Private:
      a=stack
Public:
\\ Length is a read only property
      Group Length {
             Value {
                    Link parent a to a
                    =len(A)
             }
      }
      Module AppendData (P_any as AnalysisData){
            stack .a {
                  Data ! P_any.a
            }
      }
      Function GetNext(&x) {
            stack .a {
                  if empty then exit
                  read x
                  =true
            }
      }
      function clone() {
            m=this '       we get the copy of pointer .a
            m.a<=stack(.a) ' now we make a new pointer on a copy of stack .a
            =m
      }
class:
      Module AnalysisData {
            .a<=[]
      }
}
\\ class Analysis has a AnalysisData Group, the prototype
Class Analysis {
Private:
\\ remove rem and place it to next line
Rem  AnalysisData P(100,2000)
AnalysisData P
Public:
      Module AppendData {
            .P.AppendData
      }
      Module PerformAnalysis {
            I=0
            While .P.GetNext(&I)
                  Print i,
            End While
            Print
      }
Class:
      Module Analysis (P_any as AnalysisData) {
            \\ we make the Analysis by append from another AnalysisData
            .AppendData P_any
      }
}


\\ Class ConcreteAnalysis1 is an Analysis, with a specific PerformAnalysis method
Class ConcreteAnalysis1 as Analysis {
      Module Final PerformAnalysis {
            I=0
            sum=0
            While .P.GetNext(&I)
                  sum+= i
            End While
            Print "Sum = "; sum
      }
Class:
      Module ConcreteAnalysis1 {
      \\ we just call the Analysis constructor
            .Analysis
      }
}
\\ Class ConcreteAnalysis2 is a Analysis, with a specific PerformAnalysis method
Class ConcreteAnalysis2 as Analysis {
      Module Final PerformAnalysis {
            I=0
            Max=-Infinity
            While .P.GetNext(&I)
                  If i>Max then Max=i
            End While
            Print "Max = "; Max
      }
Class:
      Module ConcreteAnalysis2 {
            .Analysis
      }
}
\\ The final objects have less methods than the methods of AnalysisData
\\ The removed methods are those who we have after the Class: label
\\ in the class/group definition. This label skip the registration of a member, but for modules and functions perform other tasks to make them as part of the object until the object deleted. When we copy a group only those members which exist in the registry of that group copied.


P1set=AnalysisData(100,200,150,100,400,200,100)
Print P1set.Length=7
A1=ConcreteAnalysis1(P1set.Clone())
A1.PerformAnalysis  ' show 1250
A2=ConcreteAnalysis2(P1set.Clone())
A2.PerformAnalysis  ' show 400
A1.AppendData P1set.Clone()
A1.AppendData P1set
Print P1set.Length=0
A1.PerformAnalysis  ' show 2500


Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.