关于php:为扩展类实现工厂方法的最佳方法是什么?


What's the best way to implement a factory method for an extended class?

考虑以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class Vehicle {

    /**
    * Create a new instance of Vehicle
    *
    * @return Vehicle
    */

    public static function create(){

        return eval("return new" . get_called_class() . '();' );
        // return self(); would always return Vehicle reg ardless

    }


    public function drive(){

        echo"I am a Vehicle!";

    }

}

class Bus extends Vehicle {

    public function drive(){

        parent::drive();

        echo"
Specifically, a bus!"
;

    }

}


class Car extends Vehicle {

    public function drive(){

        parent::drive();

        echo"
Specifically, a car!"
;

    }

}

// Drive a car
    Car::create()->drive();

// Drive a bus
    Bus::create()->drive();

我在Vehicle类中实现了一个工厂"create"方法,该方法允许我获取要使用的类的实例。

我尝试使用"return new self();",但它总是返回车辆的一个实例,所以我使用eval。

问题:是否有非eval方法来实现create()方法,以便:

  • 它返回正在使用的类的实例
  • 它不需要在每个扩展类上实现create()。


使用static而不是self,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
class Vehicle {
    public static function create(){
        return new static();
    }

    public function drive(){
        echo"I am a Vehicle!";
    }
}

class Bus extends Vehicle {
    public function drive(){
        parent::drive();
        echo"
Specifically, a bus!"
;

    }
}

$b = Bus::create();
$b->drive();

印刷品

1
2
I am a Vehicle!
Specifically, a bus!


(沃尔克打败了我,但这有点变化)

等等,你为什么要这样做?不会:

1
2
3
4
5
public static function create() {
    $class = get_called_class();

    return new $class();
}

工作?


最好的方法是将工厂方法从混凝土类型中移入自己的工厂类中。这样,您不仅可以更轻松地处理这个问题,而且还可以轻松地用另一个工厂替换该工厂。

我假设您知道对象继承是如何工作的,所以您不必处理任何不太直接的静态问题,并且开始以相当快的速度站在某个方面。