doutuo3935
doutuo3935
2018-03-02 17:10
浏览 58
已采纳

多个扩展类调用特定的子类

I've kind of been experimenting around with some different ways of dependencies, inheritance and scoping. No way of doing it is set in stone yet, I'm just experimenting so I would like to have an answer to the actual problem I'm facing or to know if I'm wanting the impossible. I don't want advice on how to build a standard MVC. The point of this experimenting is to find out if there really aren't better ways of doing very specific things.

Necessary information

I have about 8 'core' classes which I basically want to be available everywhere, even within each other (like siblings). This would likely create circular dependency, which is never what we want.

The thing is that I want all of these classes to come together as the "core", meaning I want all of them to share one object and modify situations for each other (kind of like a singleton pattern, I guess?). Then within the MVC itself, the classes will extend this core and those will be dependency-injected and such as any other MVC would.

The core is quite small. It just has some very basic functions like loading classes, being able to set a few things to $this, compiling the templates and such things.

So, I've been having this tiny little train of thoughts, what if I extended said 8 in a "train" type manner, and call only the very last extension so that I have them all within 1 single instance? This would look like this:

class base{
//The base
}

class model extends base{
 //The 1st child
 public function load($modelName){
   //Code to load a model
 }
}

class controller extends model{
 //2nd child
  public function load($controllerName){
    //code to load controller
  }
}

Great, I have everything in one instance!

Well, not exactly how I'd like it to be, though!

This brings out a big issue: Calling any "duplicate" function like load() will cause the last one to run by default.

$this->load('mymodel');
//Returns: controller "mymodel" not found

How I would like to call it is as follows;

$core->model->load('mymodel');
//Executes the childclass Model's "load" method
$core->controller->load('mycontroller');
//Executes the controller class's load method.

The real question:

Can I achieve this? If so, how?

I was thinking of something like this:

1 ) construct in the base

2 ) get all the child classes

3 ) put child classes within variables through $this->{$className} = $classObj;

4 ) call $this->classname->method style.

But I simply can't think of any way to achieve this. Googling it only results in people asking about extending multiple parents...

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • duangong0690
    duangong0690 2018-03-05 02:45
    已采纳

    Ok, so I've figured it out myself since nobody was willing to help exactly.

    class core {
    
        //This works to get all classes together
        public function __construct($isLoad = false, $calledClass = 'routing') {
            if( !$isLoad ) {
                global $coreClasses,;
                foreach( $coreClasses as $c => $o ) {
                    if( $calledClass != $c ) {
                        $this->{$c} = $o;
                    }
                }
            }
        }
            public function loadCore() {
                global $coreClasses;
                global $coreDependencies;
                // require_once BASE . 'base.php';
                foreach( $coreClasses as $class => $object ) {
                    $classFile = "$class.php";
                    $className = "$class";
                    if( !class_exists($className) ) {
                        require_once BASE . $classFile;
                        $coreClasses[$class] = new $className();
                    }
                    $this->{$class} = $coreClasses[$class];
                }
    
                foreach( $coreDependencies as $className => $aDependency ) {
                    foreach( $aDependency as $sDependency ) {
                        $coreClasses[$className]->{$sDependency} = $coreClasses[$sDependency];
                    }
                }
            }
    }
    

    The above somewhat gets it done. The core-controller class of the MVC now extends the core class, which is going to include all necessary core-classes within the $this scope. The controllers in turn extend the controller class.

    The funny thing is, I went for dependency injection in the first place... Then I was quick to notice that dependency injection was performing slower for me than just re-using the same class instances.

    I figured it's because not reinitiating the classes and easily adding them is actually faster than doing the 5-10 operations required to actually inject dependencies.

    I'm not joking, on all my tests so far, this method seems to be quite a bit faster.

    Note Now, I still went for dependency injection, given that it's a bit more strict and less 'free to mess up' that way... As people have been making clear, standards are there for a reason. I felt it should be noted nonetheless.

    I'm still slightly upset that experimenting and trying out different ways of doing things is apparently not allowed.

    点赞 评论
  • douhe4336
    douhe4336 2018-03-02 17:51

    Okay, I understand that this is just an experiment - so let me explain why this isn't a road you want to go down.

    If you've got three classes that you chain together with inheritance:

    • Class A - has method Load() and members X, Y, and Z
    • Class B - inherits from Class A, has methods Load() and Unload(), and member X
    • Class C - inherits from Class B, has members W and X.

    Okay, so you declare an instance of C... what do you get?

    You get something that has:

    • Load() - the version declared in class C (because you overrode the ones in A and B)
    • Unload() - the one declared in class B
    • Members W and X declared in class C
    • Members Y and Z declared in class A

    ... at this point, you've lost two X members and two Load() methods. They were overriden by their children.

    "That's fine - I'll just make sure I don't name my methods and members the same from class to class. Problem solved!"

    Putting aside that all this will do is basically just build one "super-class" that contains everything (this is terrible design - please don't do this), but it'll be a maintenance nightmare. Suddenly, you can't put in any new methods and members in any of the classes without checking all the rest to see if that method or member is in use - because if it is, one of them will override the other.

    Teresko's being a bit abrasive, but it's for a good reason: you are abusing inheritance, and you're doing it to create a structure that's terrible. You should brush up a bit on OOP principles before trying to go down this road.

    点赞 评论

相关推荐