[Xotcl] parameters to keep Class objects

Maksym Zinchenko siqsuruq at gmail.com
Sun Sep 17 20:34:21 CEST 2023


Thank you for your explanation and examples.

On Fri, Sep 15, 2023 at 9:08 AM Stefan Sobernig <stefan.sobernig at wu.ac.at>
wrote:

> Hi Maksym!
>
> > Basically I want something like *Factory Method* pattern.
>
> This clarifies your request! Thanks!
>
> Looking at your design snippet, I would have some suggestions for
> improvement.
>
>  From what I see, your design is not really realising the advantages of
> the FACTORY METHOD (e.g., adding new types of sessions *without* having
> to touch the factory method and the switch in there), nor is it very
> robust because of re-using the NX constructor "init" as the factory method.
>
> o Robustness: Re-using "init" that way is not a good choice in the
> context of NaviServer, because unless you are careful, NaviServer will
> run "init" just once (when building the blueprint script). When shipping
> the script to the interpreters of connection threads, init will not be
> run again (-noinit is added). In addition, autonamed NX objects (those
> created via calling "new") are also not exported into the blueprint
> script. Hence, you experience the "${:storageObj} doesn't exist" issue
> in the connection threads.
>
> o FACTORY METHOD: The by-the-book design of a FM implementation creates
> two lines of concepts: session factories and sessions. For both lines,
> two class hierarchies are typically created, like:
>
> namespace eval ::oodz {
>
>    nx::Class create Session {
>      :public method save {args} {;}
>    }
>    nx::Class create FileSession -superclasses Session
>    nx::Class create DBSession -superclasses Session
>
>
>    nx::Class create SessionFactory {
>
>      :public method createSession {} {
>        error "[:info class]: abstract method, use subclass!"
>      }
>
>      :create ::sessionFactory
>    }
>
>    nx::Class create FileSessionFactory -superclasses SessionFactory {
>      :public method createSession {} {
>        return [FileSession new]
>      }
>    }
>
>    nx::Class create DBSessionFactory -superclasses SessionFactory {
>      :public method createSession {} {
>        return [DBSession new]
>      }
>    }
>
>    namespace export Session DBSessionFactory DBSession
> FileSessionFactory FileSession
> }
>
> This way, you could call:
>
> namespace import ::oodz::*
> set s [[DBSessionFactory new] createSession]
> $s save
>
> This is a lot of design boilerplate, I prefer the following (using NX/
> XOTcl idioms incl. a metaclass):
>
> namespace eval ::oodz {
>
>    nx::Class create SessionClass -superclasses ::nx::Class
>
>    SessionClass create Session {
>      :public method save {args} {;}
>    }
>    SessionClass create file -superclasses Session
>    SessionClass create db -superclasses Session
>
>
>    nx::Class create SessionFactory {
>
>      :public method createSession {-persist_type:class,type=SessionClass} {
>        return [$persist_type new]
>      }
>
>      :create sessionFactory
>    }
>
>    namespace export sessionFactory file db
> }
>
> Then:
>
> namespace import -force ::oodz::*
> set s [sessionFactory createSession -persist_type db]
> $s save
>
> Some remarks:
>
> - "init" is not used!
>
> - session-class names are used as first-class symbols of your factory
> method (no need to maintain yet another mapping: "file" <->
> "FileSession" or similar)
>
> - You can easily add new session types, by creating new SessionClass
> instances;
>
> - Clearly, as always, there are alternatives (e.g., maintain a
> dictionary of persist_types symbols and session classes).
>
> HTH, Stefan
>
> > happening right now is that I am initializing my Session class. It works
> > fine but after some time I'm getting an error that ${:storageObj} doesnt
> > exist.
> > In your example I need to know my type of the class before. Sorry, maybe
> > I understood wrong. If you have a simple example of illustrating factory
> > method I would be grateful.
> > Thank you
> >
> > On Tue, Sep 12, 2023 at 7:02 AM Stefan Sobernig
> > <stefan.sobernig at wu.ac.at <mailto:stefan.sobernig at wu.ac.at>> wrote:
> >
> >     Hi Maksym!
> >
> >     I would recommend using a "property", watch:
> >
> >     package req nx
> >
> >     nx::Class create a {
> >           :public method hmmm {} {
> >              return "Hmmmm!!!"
> >           }
> >     }
> >     nx::Class create b {
> >           :property -accessor public aObj:object,type=::a
> >
> >           :public method saysmth {} {
> >              puts "Hello!? [${:aObj} hmmm]"
> >           }
> >     }
> >
> >
> >     # in init.tcl / created once
> >     ::b create bobj
> >
> >     # somewhere else (later):
> >
> >     ::bobj aObj set [::a new]
> >     ::bobj saysmth
> >
> >     What do you think?
> >
> >     HTH, Stefan
> >
> >
> >      > Hello, can I use parameters to keep Class objects? Like this:
> >      >
> >      > package require nx
> >      >>
> >      >> nx::Class create a {
> >      >> :public method hmmm {} {
> >      >> return "Hmmmm!!!"
> >      >> }
> >      >> }
> >      >>
> >      >> nx::Class create b {
> >      >> :method init {} {
> >      >> set :aObj [a new]
> >      >> }
> >      >>
> >      >> :public method saysmth {} {
> >      >> puts "Hello!? [${:aObj} hmmm]"
> >      >> }
> >      >> }
> >      >>
> >      >> ::b create bobj
> >      >> ::bobj saysmth
> >      >>
> >      > Is it possible that it will not be set if I create my "bobj" from
> >     init.tcl
> >      > in Naviserver at startup?
> >      >
> >      > Thank you in advance
> >      > _______________________________________________
> >      > Xotcl mailing list
> >      > Xotcl at alice.wu.ac.at <mailto:Xotcl at alice.wu.ac.at>
> >      > http://alice.wu.ac.at/mailman/listinfo/xotcl
> >     <http://alice.wu.ac.at/mailman/listinfo/xotcl>
> >
> >     _______________________________________________
> >     Xotcl mailing list
> >     Xotcl at alice.wu.ac.at <mailto:Xotcl at alice.wu.ac.at>
> >     http://alice.wu.ac.at/mailman/listinfo/xotcl
> >     <http://alice.wu.ac.at/mailman/listinfo/xotcl>
> >
>
>


More information about the Xotcl mailing list