SynackSA
SynackSA

Reputation: 889

Transform one class to another class

I want a system of class versioning which would allow one system to talk to another system in a way that any future changes wouldn't affect what's already in place.

Let's say system A and system B talk to each other via RPC calls. Business requirements change and system A and B need to be changed for future development while being backward compatible

The following would work:

class base_version
{

    public static function getVersion($version = 1)
    {
        $versionClass = 'version_'.$version;
        return new $versionClass();
    }

}

class version_1
{
    public function sayHello()
    {
        echo "Hello version 1\n";
    }
}

class version_2
{
    public function sayHello()
    {
        echo "Hello version 2\n";
    }
}


$obj = base_version::getVersion();
$obj->sayHello();

$obj = base_version::getVersion(2);
$obj->sayHello();

I don't like the static instancing however. What I would like to do is something like this, except I know you can't reassign $this.

class base_version
{
    public function __construct($version)
    {
        $versionClass = 'version_'.$version;
        $this = new $versionClass();
    }
}


$obj = new base_version();
$obj->sayHello();

$obj = new base_version(2);
$obj->sayHello();

How can I achieve this?

Upvotes: 2

Views: 200

Answers (1)

I think that with an abstract class with a defined constructor you can do something close to that.

Let's remind us that abstract class need to have at least one abstract function, but can also have 'concrete'[sic]* functions that will be the same for each inheriting class. Abstract classes can't be instanciated, only their children.

here it is:

abstract class base_version
 {function __construct($version)
   {$this->version = $version;
    switch ($this->version)
     {case 1:
        // construct for class 1
        break;
      case 2:
        // construct for class 2 etc.
        break;
      default:
        // for careless programmers who won't define the constructor in the future
        break;}}
  function version()
   {return $this->version;}
  abstract function sayHello();}

this is a base abstract class. If your business requirements change, you can add cases here for new classes in the constructor.

class greeter extends base_version
 {function sayHello()
   {return 'This is the old version' . $this->version();
    }}

class new_greeter extends base_version
 {function sayHello()
   {return 'Hello version ' . $this->version();
    }}

the point of the abstract class here is that for a class to not throw errors if extending the abstract class, it must implement a function sayHello().

that way, whoever ever makes a class extending base_version won't break the program because objects will all have at the very least those functions defined as abstract in the base class.

so there it iss, a way to define classes that can change in time without breaking the way the older ones work

$obj = new greeter(1);
$obj ->sayHello();
$obj2 = new new_greeter(2);
$obj2->sayHello();
  • 'concrete' in c++ has a specific meaning, I don't want to offend anybody by using it here even if it's not exactly the same

Upvotes: 1

Related Questions