Τρίτη 14 Ιουλίου 2020

Adapter Pattern (OOP)

Adapter pattern, we have the Adaptee, where a methodB exist, and we want the Adapter to change it as methodA, of a ISomething interface for a method of Client class doit. Here when we call M.MethodA the stack of values has 100 on the top, so we call inner=>methodB passing the same stack so we read the X from the stack.

For using a function we have to pass the current stack from funcA to funcB. This can be done using ![], the ! says push a stack object to top of stack, and [] replace the current stack with an empty stack and return a pointer to stack, so the M.funcA(2,3) convert to .inner=>funcB(![]). We use => and not dot for pointers to groups.

\\  Adapter Pattern
Class Adaptee {
      module methodB (x) {
            Print "x=";x
      }
      function funcB (x, y) {
            =x**y
      }
}
Class ISomething {
      module methodA {
            error "abstract"
      }
      Function funcA {
            error "abstract"            
      }
}
Class Adapter as ISomething {
Private:
      inner=pointer()
Public:
      module methodA {
            .inner=>methodB
      }
      function funcA {
            =.inner=>funcB(![])
      }
Class:
      module Adapter (p as pointer){
            .inner<=p
      }
}
Class Client {
      module doit (M as ISomething) {
            M.MethodA 100
            Print M.funcA(2, 3)=8
      }
}
C=Client()
Ad=Adapter(Pointer(Adaptee()))
C.doit Ad




Example2
Passing by reference plus two adapters each one for different Adaptee. Now Adapter get specific type of pointer (the previous example use as pointer to get any type without checking), M2000 is an interpreter so checking happen in every call at execution. C and AD objects are as variables, so these objects erased at the end of execution. Inner object is a pointer to a float object (has no name). So when the Adapter object (ad) goes out of scope then the Inner get a null object. The inner object erased when no pointer points to it.
A Class clause define a  global function which return an object of type Group. Each object use class name as type also. If a class use another class (as ISomething) then get another type as the name of that class. So Ad is a group of type Adapter and type ISomething.

C is type of Client and need a pointer of type ISomething as parameter for Doit method (a module in a group). Ad can get a new copy by merging a floating group (which Adapter1() function return), When we call C.Doit Ad we pass a copy of Ad. To change it for reference we have to use & before name in both places, at the definition of DoIt and at the call.

Class Adaptee {
      module methodB (x, &z) {
            Print "x=";x
            z++
      }
      function funcB (x, y) {
            =x**y
      }
}
Class Adaptee1 {
      module methodklm (x, &z) {
            Print "x*2=";x*2
            z+=5
      }
      function funcMN (x, y) {
            =x+y
      }
}
Class ISomething {
      module methodA {
            error "abstract"
      }
      Function funcA {
            error "abstract"            
      }
}


Class Adapter as ISomething {
Private:
      inner=pointer()
Public:
      module methodA {
            .inner=>methodB
      }
      function funcA {
            =.inner=>funcB(![])
      }
Class:
      module Adapter (p as *Adaptee){
            .inner<=p
      }
}
Class Adapter1 as ISomething {
Private:
      inner=pointer()
Public:
      module methodA {
            .inner=>methodklm
      }
      function funcA {
            =.inner=>funcMN(![])
      }
Class:
      module Adapter1 (p as *Adaptee1){
            .inner<=p
      }
}
Class Client {
      module doit (M as ISomething) {
            L=500
            M.MethodA 100, &L
            Print "L=";L
            Print M.funcA(2, 3)=8
      }
}
C=Client()
Ad=Adapter(Pointer(Adaptee()))
C.doit Ad
Ad=Adapter1(Pointer(Adaptee1()))
C.doit Ad





Changing for doit using pass by reference (look &M and &Ad at the code below):

Class Client {
      module doit (&M as ISomething) {
            L=500
            M.MethodA 100, &L
            Print "L=";L
            Print M.funcA(2, 3)=8
      }
}
C=Client()
Ad=Adapter(Pointer(Adaptee()))
C.doit &Ad
Ad=Adapter1(Pointer(Adaptee1()))
C.doit &Ad

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

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

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