ORM在对象类声明中找到

时间:2015-05-26 23:47:21

标签: ruby-on-rails laravel orm mongoose

我注意到一些ORM实现,其中数据库搜索工作作为对象类的静态方法发生,如MongooseJS中那样:

var myCar = new Car({ name: 'MyCar' });
Car.find({ name: /MyCar/ }, callback)

Rails和Laravel做了类似的事情。作为一种代表汽车的方式,这对其他人来说是否有点奇怪?对我来说,find()更像是工厂方法,应该看起来像

var myCar = new Car({ name: 'MyCar' });
CarFactory.find({ name: /MyCar/ }, callback)

或者甚至

var myCar = CarFactory.createCar({ name: 'MyCar' });
CarFactory.find({ name: /MyCar/ }, callback)

尽管find()本质上是Car 上的一个静态方法(与对象本身相对),但对我来说仍然感觉有点像汽车知道所有的其他车。这对其他人来说是不是很奇怪,还是我在想这个?

谢谢!

1 个答案:

答案 0 :(得分:1)

我必须将这个答案分成两部分。第一部分是何时使用工厂,第二部分是ORM的“幕后”。但在我开始之前:这很大程度上取决于我自己的经历。你应该总是自己决定什么最适合你的项目(在这种情况下,使用工厂模式是有意义的,而不是等等)。

何时使用工厂

我经常将工厂视为生成具有依赖关系的对象的方法,这些对象在我创建它时并不知道,或者作为生成我经常需要的对象的简写方式。

例如,假设我们有一个工厂方法可以找到所有“快速”汽车。

class CarFactory {

    public static function getFastCars()
    {
        return Car::where('max_speed', '>', '180')->get();
    }

}

现在,当我们将这种方法称为$cars = CarFactory::getFastCars();时,我不必知道汽车必须要多快才能快速。但是,在您的示例中,您知道汽车的名称,这是ORM找到您的汽车的唯一条件。我认为工厂会让你的代码变得更加复杂。

工厂的另一个用例可能是生成汽车的特定类型。让我们想象一下,我们正在建立一个汽车租赁服务,其中我们可以输入我们想要开车的位置,服务告诉我们哪辆车最适合我们的旅程。这就是工厂派上用场的地方:

/**
 * Car classes
 */
class Car {

    public function __toString()
    {
        return 'basic car';
    }

}

class SportsCar extends Car {

    public function __toString()
    {
        return 'sports car';
    }

}

class OffroadCar extends Car {

    public function __toString()
    {
        return 'off-road car';
    }

}

/**
 * The factory
 */
class CarFactory {

    public static function carForLocation($location)
    {
        $car = null;

        switch ($location)
        {
            case 'racetrack':
                $car = new SportsCar();
                break;
            case 'hills':
                $car = new OffroadCar();
                break;
            default:
                $car = new Car();
        }

        return $car;
    }

}


/**
 * Generating the car based on a location
 */
$car = CarFactory::carForLocation('racetrack');

echo "The type of car best for your journey is a {$car}.";

// Output: The type of car best for your journey is a sports car.

关于ORM

在我的例子中,工厂了解所有汽车。然而,ORM或模型在这里是特定的,不保留任何关于任何汽车的信息(可以说是处于“原始”状态)。在幕后,当您调用Car.find({name: /MyCar/})时,ORM将通过它所依赖的查询构建器从数据库中获取汽车信息。然后,您的汽车实例会将该信息保存在其属性中。

这个答案在某些方面可能是肤浅的(尤其是ORM部分),但我希望无论如何我都可以帮助你。