Τετάρτη, 8 Ιουλίου 2020

Singleton Pattern (OOP)

We can define a Singleton object and if we pass it as pointer to object or as a copy we get the same object (in logic). Copies of groups can be done using Group(aPointerOfGroup) or defined a new group using Group namedgroup=aPointerOfGroup.

1. We make a lambda function starting with a closure to the Null Group. First time we place the pointer of the Singleton group to M. So each time we get the same.
2. The group singleton convert to a closed group (nameless) and hold by the pointer M. Because state is a tuple, each time we copy the group we get the same copy of state (as pointer to tuple).
3. We can read the value of state evaluate the export value from Value member. If k is a pointer we need Eval(k) to execute the value member. If k is named group then k return the value (not the group). Using Group(k) always we get a copy of group (but we get a copy of state so we have the same state to every group).
4. The method module add, do one thing add x to every item in tuple this.state and here we have only one item. Every other group which have the same pointer to this.state (or .state) get the new value.
5. When the module CheckSingleton ends push a value to stack, the lambda variable (a lambda is both  a variable and a function) as a copy, and also here we get a copy of a pointer, the closuer M. At the return from call  we read lambda from stack as something, so we get also a function something(). 
6. We make a named group as M and a pointer to group z and demonstrate the use.

A singleton must be global, but here we can make copies, and work perfect
A singleton has one instance (although we have different instances when copy it as group, each one has same state, not only as value but using same pointer to tuple, so we can say that it is one instance by logic)

Module CheckSingleton {
    \\ singleton
    \\ pointers and static groups are the same object because
    \\ each one has a pointer to same state (a tuple)
    \\ but from outside we do the miracle to have a static group to act as a pointer
    \\ We need a lambda function to hold the pointe to Singleton as closure
    Global One=lambda M=pointer() (aValue=0)-> {
        If M is type null then
            \\ one time happen
            Group Singleton {
            Type:One
            Private:
                state=(aValue,)
            Public:            
                module Add (x) {
                    .state+=x
                }
                Set {Drop}
                Value {
                    =.state#val(0)
                }
            }
            M->group(Singleton)
        end if
        \\ return M which is a pointer
        =M
    }
    K=One(100)
    Print Eval(K)=100
    M=One()
    Print Eval(M)=100
    Print K is M = true
    Print K is type One = true
    K=>add 500
    Print eval(K)=600
    \\ copy K to Z (no pointer to Z, Z is named group)
    Z=Group(K)
    Print eval(z)=600, z=600
    Z.add 1000
    Print Z=1600, Eval(M)=1600, Eval(K)=1600
    \\ push a copy of Z, but state is pointer so we get a copy of a pointer
    Push Group(Z)
    Read beta
    Beta.add 1000
    Print Z=2600, Eval(M)=2600, Eval(K)=2600
    \\ convert pointer to group (a copy of group)
    group delta=One()
    delta.add 1000
    Print Z=3600, beta=3600, delta=3600, Eval(M)=3600, Eval(K)=3600
    \\ M and K are pointers to groups
    M=>add 400
    Print Z=4000, beta=4000, delta=4000, Eval(M)=4000, Eval(K)=4000
    class alfa {
        X=100
    }
    \\ we can't change named group Z becaues Z has a set member and drop the value;
    Z=alfa()
    Print valid(z.x)=false
    \\ but pointers can change to what group they point
    K->alfa()
    Print K is type alfa
    Print K=>X=100
    Push one
}
CheckSingleton
\\ peek the top from stack
global something=Stackitem()
\\ drop it
drop
\\ so now we have a global something and a global something()
group m=something()
Print m=4000
m.add 1000
Print m=5000
z=something()
z=>add 1000
Print Eval(z)=6000, m=6000


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

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