Listing objects

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Lüpher Cypher

    #1

    Listing objects

    Hi,

    Suppose we have a hierarchical class structure that looks something like
    this:

    Object
    |
    +-- Main
    |
    +-- Object1
    | |
    | +-- Object11
    | |
    | +-- Object 12
    |
    +-- Object2
    |
    +-- Object3
    |
    +-- Object4
    |
    +-- Object41
    | |
    | +-- Object 411
    |
    +-- Object 42

    Now, the application looks like this:

    <?php
    $app = new Main(...);
    $app->doSomething( );
    ?>

    Class Main() is instantiated only once, however it works with all other
    classes, which may be instantiated a number of times.

    Now suppose there is a scenario:

    Main creates Object11.
    Object11 calls Object1::foo(), which creates Object2.
    Object2 may then create Object1, in which case
    Object1 calls its foo(), which creates Object2.
    Object2 may then create Object1
    ..etc. until Object2 decides not to create Object1..

    So, basically we'd get:

    Main
    Object11->foo()
    Object2
    Object1->foo()
    Object2
    ...

    Now, when Object2 instantiates, it assigns a value to its variable, say,
    Object2::var, which should be unique. So, after assigning the value,
    Object2 has to check it against any other Object2::var.
    However, Object2 is not necessarily instantiated under Object1, so,
    let's say we have

    Main
    $obj11 = Object11
    $obj2 = Object2
    $obj1 = Object1
    $obj2 = Object2
    $obj3 = Object3
    $obj2 = Object2
    $obj411 = Object411
    $obj42 = Object42
    $obj1 = Object1
    $obj2 = Object2


    Assume $app->obj11->obj2->obj1->obj2::var should be checked against

    $app->obj11->obj2::var
    $app->obj3->obj2::var
    $app->obj411->obj42->obj1->obj2::var

    I assumed the easiest way would be to have a global array of all objects
    descending from Object and update it in Object's constructor:

    function Object() {
    global $objects;
    $objects[count($objects)] = &$this;
    ...
    }

    Then we could simply iterate through $objects, and if object's class is
    Object2, compare the var's.
    However, this does not work, even through the object is passed by
    reference - if the object's variables are updated (by the object itself
    or by another object), the global array apparently has a copy of the
    initial object state:

    $obj2 = new Object2();
    results in
    $obj2 = Object2( var => 1 )
    $objects[0] = Object2( var => 1 )

    $obj2->var++;
    results in
    $obj2 = Object2( var => 2 )
    $objects[0] = Object2( var => 1 )

    So, I guess, some other mechanism should be used.


    Any ideas?

    Thanks,
    luph
  • Peter Fox

    #2
    Re: Listing objects

    Following on from Lüpher Cypher's message. . .[color=blue]
    >Hi,
    >
    >Suppose we have a hierarchical class structure that looks something like
    >this:[/color]
    Sorry, I lost the plot half way through.

    Your objects can be
    1 - nesting : object has a 'what are my children' and 'who is my
    parent' functionality.

    2 - pointing : eg object has a 'these are my siblings' or
    'previous/next' functionality

    3 - dictionary entries : object in some container is discoverable by
    name

    Variations and combinations of course apply. BUT every object exists in
    some context. I /think/ you might be trying to get A's to point-to/own
    B's where more than one A could be the parent of a B. Eg
    "Sally is daughter of Jean"
    "Geoffrey is son of Teddy"
    "Sally is daughter of Teddy" // Only one Sally! J+T are married.

    In this case[1] create an array of children and point to elements in
    that array from your parent objects.

    eg $child['Sally'] = new ChildObj(.....) ;
    then $Jean->AddChild('Sall y') // just a key name or index
    or $Jean->AddChild($chil d['Sally']) // inside the routine do $myKids[]
    = & $NewChild
    where $NewChild is the function argument.

    [1] If in this example children can be parents then you should be
    looking at a single universal 'person' class with the necessary links.






    --
    PETER FOX Not the same since the adhesive company came unstuck
    peterfox@eminen t.demon.co.uk.n ot.this.bit.no. html
    2 Tees Close, Witham, Essex.
    Gravity beer in Essex <http://www.eminent.dem on.co.uk>

    Comment

    • Josse Barrera

      #3
      Re: Listing objects



      Lüpher Cypher wrote:
      [color=blue]
      > Hi,
      >
      > Suppose we have a hierarchical class structure that looks something like
      > this:
      >
      > Object
      > |
      > +-- Main
      > |
      > +-- Object1
      > | |
      > | +-- Object11
      > | |
      > | +-- Object 12
      > |
      > +-- Object2
      > |
      > +-- Object3
      > |
      > +-- Object4
      > |
      > +-- Object41
      > | |
      > | +-- Object 411
      > |
      > +-- Object 42
      >
      > Now, the application looks like this:
      >
      > <?php
      > $app = new Main(...);
      > $app->doSomething( );
      > ?>
      >
      > Class Main() is instantiated only once, however it works with all other
      > classes, which may be instantiated a number of times.
      >
      > Now suppose there is a scenario:
      >
      > Main creates Object11.
      > Object11 calls Object1::foo(), which creates Object2.
      > Object2 may then create Object1, in which case
      > Object1 calls its foo(), which creates Object2.
      > Object2 may then create Object1
      > ..etc. until Object2 decides not to create Object1..
      >
      > So, basically we'd get:
      >
      > Main
      > Object11->foo()
      > Object2
      > Object1->foo()
      > Object2
      > ...
      >
      > Now, when Object2 instantiates, it assigns a value to its variable, say,
      > Object2::var, which should be unique. So, after assigning the value,
      > Object2 has to check it against any other Object2::var.
      > However, Object2 is not necessarily instantiated under Object1, so,
      > let's say we have
      >
      > Main
      > $obj11 = Object11
      > $obj2 = Object2
      > $obj1 = Object1
      > $obj2 = Object2
      > $obj3 = Object3
      > $obj2 = Object2
      > $obj411 = Object411
      > $obj42 = Object42
      > $obj1 = Object1
      > $obj2 = Object2
      >
      >
      > Assume $app->obj11->obj2->obj1->obj2::var should be checked against
      >
      > $app->obj11->obj2::var
      > $app->obj3->obj2::var
      > $app->obj411->obj42->obj1->obj2::var
      >
      > I assumed the easiest way would be to have a global array of all objects
      > descending from Object and update it in Object's constructor:
      >
      > function Object() {
      > global $objects;
      > $objects[count($objects)] = &$this;
      > ...
      > }
      >
      > Then we could simply iterate through $objects, and if object's class is
      > Object2, compare the var's.
      > However, this does not work, even through the object is passed by
      > reference - if the object's variables are updated (by the object itself
      > or by another object), the global array apparently has a copy of the
      > initial object state:
      >
      > $obj2 = new Object2();
      > results in
      > $obj2 = Object2( var => 1 )
      > $objects[0] = Object2( var => 1 )
      >
      > $obj2->var++;
      > results in
      > $obj2 = Object2( var => 2 )
      > $objects[0] = Object2( var => 1 )
      >
      > So, I guess, some other mechanism should be used.
      >
      >
      > Any ideas?
      >
      > Thanks,
      > luph[/color]

      This is a textbook case of a badly designed set of classes. Their
      relationships are so complicated that even you the architect, are having
      problems explaining yourself. I think you'll need to go back to the
      drawing board on this one.

      Extract the common features into a set of interfaces which should help
      clarify the class relationships and clean up the design. Also wherever
      possible, try to use (design) patterns, that way, your code will be
      reusable (not to mention easir to maintain). Incidentally, your Main
      class looks like a Singleton pattern, but only you the archiect, can
      know that for sure since your description given here is not very lucid.

      hope that helps

      Comment

      • Dikkie Dik

        #4
        Re: Listing objects

        As Peter Fox has pointed out, put the tasks where they belong. I have
        the feeling that you are playing the role of a conductor who has to
        learn each musician how to play as well.

        Use clear names for objects. If your model represents companies,
        departments, employees, tasks and subtasks, just call your classes those
        descriptive names.

        If you have to compare different instances that might have the same
        state (value of internal variables), you could give the class an
        IsEqualTo method to do the comparison. Even better, a lazy collection
        can be used to ensure that equal objects are actually the same instance.
        You could then just use the reference equality operator (===).

        Oh, and just delegate. Conductors trust their musicians in their skills.
        At least in a concert. In software, use unit tests as a "musician's exam".
        For instance, if each object in your structure has some value and you
        want to calculate the total of it, don't traverse the structure
        yourself. Trust your directly known objects and ask them to calculate
        THEIR total and add these.

        It is not always bad to repeat methods:
        Employee->Name()
        May be defined as
        Employee->EmployeeRecord Wrapper->Name()

        The short verion is clearer AND independent of the underlying structure,
        giving you more architectural flexibility.

        If you fancy some technical stuff, google for the "Law of Demeter". It
        is about what objects should know each other and what objects should not.

        Best regards

        Comment

        • Lüpher Cypher

          #5
          Re: Listing objects

          Dikkie Dik wrote:[color=blue]
          > As Peter Fox has pointed out, put the tasks where they belong. I have
          > the feeling that you are playing the role of a conductor who has to
          > learn each musician how to play as well.
          >
          > Use clear names for objects. If your model represents companies,
          > departments, employees, tasks and subtasks, just call your classes those
          > descriptive names.[/color]

          I figured that much :)
          [color=blue]
          >
          > If you have to compare different instances that might have the same
          > state (value of internal variables), you could give the class an
          > IsEqualTo method to do the comparison. Even better, a lazy collection
          > can be used to ensure that equal objects are actually the same instance.
          > You could then just use the reference equality operator (===).[/color]

          Hmm.. $a === $b will return true if $a == $b (i.e. their properties have
          the same values) and they are of the same class. That doesn't mean they
          are the same object, though..


          Ok, let me try a clearer version :)

          Object
          |
          +--- App
          | ::$page
          |
          +--- Control
          | ::$parent
          | ::$data
          | ::$object
          |
          +--- Data
          | ::$id
          |
          +--- Template
          | ::owner
          | ::control
          |
          +--- Page

          In the main script I have

          $app = new App();

          In constructors I have

          function App() {
          ...
          $null = null;
          $this->page = new Page($null);
          }

          function Page(&$owner) {
          parent::Templat e(&$owner);
          }

          function Template(&$owne r) {
          $this->owner = &$owner;
          ...
          $this->control = new Control(&$this) ;
          }

          function Control(&$paren t) {
          $this->parent = &$parent;
          ...
          $this->data = new Data();
          ...
          if (already_exists ($this->data->id)) {
          echo "Duplicate ID";
          return;
          }
          ...
          if ($some_conditio n) {
          $object = new $CustomSubclass OfTemplate($thi s->parent);
          }
          }

          function Data() {
          ...
          $this->id = $some_retrieved _id;
          }

          Basically, the interesting part is:

          When Template is instantiated (initially Page in App constructor), it
          instantiates Control, which, in turn, instantiates Data. At this point,
          $data->id will be set.
          At the end of Control's constructor, if some condition is satisfied, a
          subclass of Template will be instantiated and stored in Control's $object.
          Thus, we can have:
          $app->$page->$control->$object->$control->$object->...->$control->null($object )
          We can also pretty much go bottom-up through Template objects via $owner
          and we can get the Template object from Control via $parent.

          Now, in the middle of Control's constructor there is a check that
          $data-id does not already exist.

          One way would be to go through Templates:

          $temp = $this->parent;
          while (isset($temp)) {
          if ($this->data->id == $temp->control->data->id) {
          echo "error";
          return;
          }
          }

          Apparently this does not work, even though owner is passed by reference.

          Another way would be to have a global array and save all objects there
          by reference. This is actually more appealing to me, since then I could
          access any object at any time from anywhere. Say, if I have an array of
          objects under Template and each of them has an associative array
          key=>value, then to "compile" an associative array from all those
          arrays, I'd simply iterate through the global array, check object's
          class, and take in the key/value pairs in the resulting array, rather
          than traverse a tree of Templates and those objects. Anyways, what I
          tried is something like this:

          global $objects;
          $objects = array();

          class Object() {
          global $objects;
          $objects[count($objects)] = &$this;
          }

          However, if a property of an object is changed, the object in $objects
          stays the same.. But then, it must be a copy?


          luph

          Comment

          • Lüpher Cypher

            #6
            Re: Listing objects

            Oh, forgot to update $temp here:

            $temp = $this->parent;
            while (isset($temp)) {
            if ($this->data->id == $temp->control->data->id) {
            echo "error";
            return;
            }
            $temp = $temp->owner;
            }

            Also, it does not work because $temp->control->data is null. However, if
            $this->data is accessed from $temp->control, it is instantiated..

            luph

            Comment

            • Lüpher Cypher

              #7
              Re: Listing objects

              Peter Fox wrote:[color=blue]
              > Following on from Lüpher Cypher's message. . .[color=green]
              >> Hi,
              >>
              >> Suppose we have a hierarchical class structure that looks something like
              >> this:[/color]
              > Sorry, I lost the plot half way through.
              >
              > Your objects can be
              > 1 - nesting : object has a 'what are my children' and 'who is my
              > parent' functionality.
              >
              > 2 - pointing : eg object has a 'these are my siblings' or
              > 'previous/next' functionality
              >
              > 3 - dictionary entries : object in some container is discoverable by name
              >[/color]

              It is more of a [1] and [3] :)
              [1] for I do have a tree-like structure of objects. I have $parent (for
              all objects) and $owner (for objects that are of subclasses of some
              class) properties so, I can go bottom-up. I also do have children array
              for objects that have owner so, I can go top-down.
              [3] for I am trying to have a global associative array that has unqiue
              object names as keys and object references as values.
              [color=blue]
              > Variations and combinations of course apply. BUT every object exists in
              > some context. I /think/ you might be trying to get A's to point-to/own
              > B's where more than one A could be the parent of a B. Eg
              > "Sally is daughter of Jean"
              > "Geoffrey is son of Teddy"
              > "Sally is daughter of Teddy" // Only one Sally! J+T are married.
              >
              > In this case[1] create an array of children and point to elements in
              > that array from your parent objects.
              >
              > eg $child['Sally'] = new ChildObj(.....) ;
              > then $Jean->AddChild('Sall y') // just a key name or index
              > or $Jean->AddChild($chil d['Sally']) // inside the routine do $myKids[]
              > = & $NewChild
              > where $NewChild is the function argument.
              >
              > [1] If in this example children can be parents then you should be
              > looking at a single universal 'person' class with the necessary links.
              >[/color]

              I do have a universal class :)
              Say,

              class Object
              var $name;
              var $owner;
              var $children[];


              Now,

              class A extends Object
              class B extends Object

              A's can be owned by A's and/or B's, B's can have many A's and/or B's
              B's can be owned by A's and/or B's and can have many A's and/or B's as well.

              One of the things I am trying to do is to have global references to all
              Objects:

              global $objects;
              $objects = array();

              function Object() {
              global $objects;
              ... assign name ...
              $objects[$this->name] = &$this;
              }

              However, if a property of some Object changes, $objects[$object_name]
              still has the "old" object. I assume $objects[$object_name] does not
              reference the object then, rather has a copy of it. So far I was unable
              to solve this.. By the way, this will work:

              $obj = new Object();
              $objects[$obj->name] = &$obj;

              if it is executed outside any function and any class..


              luph

              Comment

              • Dikkie Dik

                #8
                Re: Listing objects

                > Hmm.. $a === $b will return true if $a == $b (i.e. their properties have[color=blue]
                > the same values) and they are of the same class. That doesn't mean they
                > are the same object, though..[/color]

                Sorry, I'm probably confusing with other languages.
                [color=blue]
                > Ok, let me try a clearer version :)
                >
                > Object
                > |
                > +--- App
                > | ::$page
                > |
                > +--- Control
                > | ::$parent
                > | ::$data
                > | ::$object
                > |
                > +--- Data
                > | ::$id
                > |
                > +--- Template
                > | ::owner
                > | ::control
                > |
                > +--- Page[/color]

                This is the inheritance hiearchy, I assume that you also have an
                association hierachy. App will be the root, and then...
                I would think that an App creates a page and creates a data channel, or
                asks a Control to do that. Within my perception, a page has a template
                and date (gets it from App). So App knows Control and Page, and also
                knows that Control has Data. All these objects do not have to know App
                as far as I can see.

                [color=blue]
                > In the main script I have
                >
                > $app = new App();
                >
                > In constructors I have
                >
                > function App() {
                > ...
                > $null = null;
                > $this->page = new Page($null);
                > }
                >
                > function Page(&$owner) {
                > parent::Templat e(&$owner);
                > }
                >
                > function Template(&$owne r) {
                > $this->owner = &$owner;
                > ...
                > $this->control = new Control(&$this) ;
                > }
                >
                > function Control(&$paren t) {
                > $this->parent = &$parent;
                > ...
                > $this->data = new Data();
                > ...
                > if (already_exists ($this->data->id)) {
                > echo "Duplicate ID";
                > return;
                > }[/color]

                If the problem is here, let's keep it here. I have written my own
                DatabaseID class with its own IsEqualTo method (and an IsNew method).
                For the very simple reason: A data-object might be constructed with
                database data (known ID) or be a new record that was not yet stored in
                the database. With this DatabaseID class, I can give EVERY data-object
                an ID. If the DatabaseID instance is not contructed with a database ID,
                the IsEqualTo method will always return FALSE. Two new records are per
                definition different in my application. Only if both compared objects
                were constructed with an ID from the database, an actual by-value
                comparison if done.
                [color=blue]
                > ...
                > if ($some_conditio n) {
                > $object = new $CustomSubclass OfTemplate($thi s->parent);
                > }
                > }[/color]

                What is template doing in Control? If Control is responsible for both
                templates and data, it is a clear signal that this class wants to be
                split into two classes.
                [color=blue]
                >
                > function Data() {
                > ...
                > $this->id = $some_retrieved _id;
                > }
                >
                > Basically, the interesting part is:
                >
                > When Template is instantiated (initially Page in App constructor), it
                > instantiates Control, which, in turn, instantiates Data. At this point,
                > $data->id will be set.
                > At the end of Control's constructor, if some condition is satisfied, a
                > subclass of Template will be instantiated and stored in Control's $object.
                > Thus, we can have:
                > $app->$page->$control->$object->$control->$object->...->$control->null($object )[/color]

                Is that bad? Frankly I don't care how deep a structure goes, as long as
                it makes sense and is finite.
                [color=blue]
                >
                > We can also pretty much go bottom-up through Template objects via $owner
                > and we can get the Template object from Control via $parent.
                >
                > Now, in the middle of Control's constructor there is a check that
                > $data-id does not already exist.
                >
                > One way would be to go through Templates:
                >
                > $temp = $this->parent;
                > while (isset($temp)) {
                > if ($this->data->id == $temp->control->data->id) {
                > echo "error";
                > return;
                > }
                > }
                >
                > Apparently this does not work, even though owner is passed by reference.
                >
                > Another way would be to have a global array and save all objects there
                > by reference. This is actually more appealing to me, since then I could
                > access any object at any time from anywhere.[/color]

                Yikes!
                One of the main features of object-oriented programming is that you can
                nicely shield off what others should not access. The contents of a page
                should only be accessible by asking the $page object, which is only
                accessible by asking $app. Why? Because it allows $page to decide how
                and when to fill in the data, and to throw an exception if no data was
                passed. That is $page's reponsibility, not $app's, and not even yours.
                If you want to peek inside of $page's internals, write a temporary
                method or echo statement, during development only.
                Not even your responsibility? No. You can program it, write a unit test
                for it, and when it is finished, it can live on its own. It is sad, but
                the only thing left for you to do is typing the URL...
                [color=blue]
                > Say, if I have an array of
                > objects under Template and each of them has an associative array
                > key=>value, then to "compile" an associative array from all those
                > arrays, I'd simply iterate through the global array, check object's
                > class, and take in the key/value pairs in the resulting array, rather
                > than traverse a tree of Templates and those objects. Anyways, what I
                > tried is something like this:
                >
                > global $objects;
                > $objects = array();
                >
                > class Object() {
                > global $objects;
                > $objects[count($objects)] = &$this;
                > }
                >
                > However, if a property of an object is changed, the object in $objects
                > stays the same.. But then, it must be a copy?
                >
                >
                > luph[/color]

                Comment

                • Lüpher Cypher

                  #9
                  Re: Listing objects

                  Dikkie Dik wrote:[color=blue]
                  >[color=green]
                  >> Ok, let me try a clearer version :)
                  >>
                  >> Object
                  >> |
                  >> +--- App
                  >> | ::$page
                  >> |
                  >> +--- Control
                  >> | ::$parent
                  >> | ::$data
                  >> | ::$object
                  >> |
                  >> +--- Data
                  >> | ::$id
                  >> |
                  >> +--- Template
                  >> | ::owner
                  >> | ::control
                  >> |
                  >> +--- Page[/color]
                  >
                  > This is the inheritance hiearchy, I assume that you also have an
                  > association hierachy. App will be the root, and then...
                  > I would think that an App creates a page and creates a data channel, or
                  > asks a Control to do that. Within my perception, a page has a template
                  > and date (gets it from App). So App knows Control and Page, and also
                  > knows that Control has Data. All these objects do not have to know App
                  > as far as I can see.[/color]

                  Well, App only creates and knows Page (Template).
                  Template creates Controller, which creates Data. So, Template knows
                  Control, and Control knows Data. However, depending on the Data, Control
                  may instantiate another Template (at which point the process repeats).
                  The original Template has access to Control's Template.
                  Right now it's like this:

                  $app = new App(
                  $page = new Page(
                  $ctl = new Control(
                  $data = new Data()
                  if (<another template>) {
                  $temp = new TemplateSubclas s(
                  $ctl = new Control(
                  ...
                  )
                  )
                  }
                  )
                  )
                  )
                  $app->render(
                  $page->render(
                  if ($ctl->temp exists) {
                  $out = $ctl->temp->render(
                  if ($ctl->temp exists) {
                  $out = $ctl->temp->render(
                  ...
                  )
                  }
                  return $out.<custom output>;
                  )
                  }
                  return $out.<custom output>;
                  )
                  echo <results>;
                  )

                  Some of these do call App's methods, though, for instance to get a
                  global application parameter..
                  [color=blue]
                  >[color=green]
                  >> In the main script I have
                  >>
                  >> $app = new App();
                  >>
                  >> In constructors I have
                  >>
                  >> function App() {
                  >> ...
                  >> $null = null;
                  >> $this->page = new Page($null);
                  >> }
                  >>
                  >> function Page(&$owner) {
                  >> parent::Templat e(&$owner);
                  >> }
                  >>
                  >> function Template(&$owne r) {
                  >> $this->owner = &$owner;
                  >> ...
                  >> $this->control = new Control(&$this) ;
                  >> }
                  >>
                  >> function Control(&$paren t) {
                  >> $this->parent = &$parent;
                  >> ...
                  >> $this->data = new Data();
                  >> ...
                  >> if (already_exists ($this->data->id)) {
                  >> echo "Duplicate ID";
                  >> return;
                  >> }[/color]
                  >
                  > If the problem is here, let's keep it here. I have written my own
                  > DatabaseID class with its own IsEqualTo method (and an IsNew method).
                  > For the very simple reason: A data-object might be constructed with
                  > database data (known ID) or be a new record that was not yet stored in
                  > the database. With this DatabaseID class, I can give EVERY data-object
                  > an ID. If the DatabaseID instance is not contructed with a database ID,
                  > the IsEqualTo method will always return FALSE. Two new records are per
                  > definition different in my application. Only if both compared objects
                  > were constructed with an ID from the database, an actual by-value
                  > comparison if done.[/color]

                  Well, all I need is just checking whether an ID exists. In this case,
                  Data loads an XML file and sets its ID value to a string. This ID should
                  be unique. So, after Controller instantiates Data, it should check that
                  the loaded ID wasn't already assigned in some other Controller. I figure
                  the easiest way is to iterate an array of objects, see if an object has
                  Control as its class, and compare the IDs in Datas. :)
                  [color=blue]
                  >[color=green]
                  >> ...
                  >> if ($some_conditio n) {
                  >> $object = new $CustomSubclass OfTemplate($thi s->parent);
                  >> }
                  >> }[/color]
                  >
                  > What is template doing in Control? If Control is responsible for both
                  > templates and data, it is a clear signal that this class wants to be
                  > split into two classes.[/color]

                  Well, Template is presentation class so, it's all about *how* the data
                  should be displayed and has no other functionality. It knows its Control
                  so that it can present dynamic data. Control relies on Data to choose
                  *what* should be displayed.
                  Suppose Data consists of 3 classes. Control chooses one of them and
                  instantiates it. Template simply outputs whatever it is, inserting the
                  output of the class Control chose along way. This way Data is only about
                  data, Control is about what should be output, and Template is only about
                  how it should be output, no matter what the actual content is. I figure
                  instantiating the chosen class in Template would mean that Template is
                  also about data, and instantiating it in Data would mean that data is
                  dynamic.. :)


                  [color=blue]
                  >[color=green]
                  >>
                  >> function Data() {
                  >> ...
                  >> $this->id = $some_retrieved _id;
                  >> }
                  >>
                  >> Basically, the interesting part is:
                  >>
                  >> When Template is instantiated (initially Page in App constructor), it
                  >> instantiates Control, which, in turn, instantiates Data. At this
                  >> point, $data->id will be set.
                  >> At the end of Control's constructor, if some condition is satisfied, a
                  >> subclass of Template will be instantiated and stored in Control's
                  >> $object.
                  >> Thus, we can have:
                  >> $app->$page->$control->$object->$control->$object->...->$control->null($object )
                  >>[/color]
                  >
                  > Is that bad? Frankly I don't care how deep a structure goes, as long as
                  > it makes sense and is finite.[/color]

                  Well, it's actually not all that bad, since there is no need to write
                  such long references :) It is finite, otherwise the page will never load :)
                  [color=blue]
                  >[color=green]
                  >>
                  >> We can also pretty much go bottom-up through Template objects via
                  >> $owner and we can get the Template object from Control via $parent.
                  >>
                  >> Now, in the middle of Control's constructor there is a check that
                  >> $data-id does not already exist.
                  >>
                  >> One way would be to go through Templates:
                  >>
                  >> $temp = $this->parent;
                  >> while (isset($temp)) {
                  >> if ($this->data->id == $temp->control->data->id) {
                  >> echo "error";
                  >> return;
                  >> }
                  >> }
                  >>
                  >> Apparently this does not work, even though owner is passed by reference.[/color][/color]

                  Found where the mistake is :) Apparently $a = new A() means that $a is a
                  copy of the actually instantiated class A() ;-o All I had to do was to
                  change all instantiations to form $a = &new A();
                  [color=blue][color=green]
                  >>
                  >> Another way would be to have a global array and save all objects there
                  >> by reference. This is actually more appealing to me, since then I
                  >> could access any object at any time from anywhere.[/color]
                  >
                  > Yikes!
                  > One of the main features of object-oriented programming is that you can
                  > nicely shield off what others should not access. The contents of a page
                  > should only be accessible by asking the $page object, which is only
                  > accessible by asking $app. Why? Because it allows $page to decide how
                  > and when to fill in the data, and to throw an exception if no data was
                  > passed. That is $page's reponsibility, not $app's, and not even yours.
                  > If you want to peek inside of $page's internals, write a temporary
                  > method or echo statement, during development only.
                  > Not even your responsibility? No. You can program it, write a unit test
                  > for it, and when it is finished, it can live on its own. It is sad, but
                  > the only thing left for you to do is typing the URL...[/color]

                  Well, echo's are what I usually use to debug things :)
                  In this case, however, I could either traverse a tree, meaning that I
                  would start in a leaf, and would have to traverse all nodes and leaves,
                  bottom-up, check if a node/leaf is of appropriate class, and then check
                  whether ID is the same or not.
                  With array, I can simply use foreach:

                  foreach($object s as $name=>$obj) {
                  if (!is_a($obj,"Co ntrol")) { continue; }
                  if ($name == $this->getName()) { continue; }
                  if ($this->getId() == $obj->getId()) { echo "error"; return; }
                  }

                  Where each object has a unique name :) That's what I actually use, now
                  that the references work in the global array.
                  It is pretty much a shortcut to doing some things :)


                  luph

                  Comment

                  Working...