ООП: счетчик, принадлежащий классу и наследованию - PullRequest
1 голос
/ 20 сентября 2011

У меня есть иерархия классов, и я бы хотел, чтобы у каждого объекта был идентификатор вида Classname-integer (примеры: Car-0, Car-1, Motorcycle-0, Truck-0, Truck-1, ...)

Иерархия классов:

Vehicle
   Car
   Motorcycle
   Truck

Проблема в том, что я хочу написать только один раз код, который управляет идентификаторами, и я потерялся в конструкторах, прототипах, позднем связывании и т. Д.

Пример того, что я хотел бы получить в псевдокоде:

car = new Car
anotherCar = new Car
car.id                  // "Car-0"
anotherCar.id           // "Car-1"
truck = new Truck
truck.id                // "Truck-0"

конструктор Car инициализирует идентификатор объекта текущим доступным идентификатором Car, а затем увеличивает его так, чтобы следующий новый Car имел другой идентификатор. Это не должно влиять на идентификаторы других классов.

В идеале я хотел бы написать код только в базовом классе Vehicle, но я не знаю, возможно ли это.

Мой текущий целевой язык - Coffeescript / Javascript, но приветствуются и другие языки, а также некоторые рассуждения о том, как это работает.

Как бы вы решили это?

Ответы [ 4 ]

2 голосов
/ 20 сентября 2011

Вы можете использовать конструктор Vehicle для добавления функции-прототипа, которая будет обновлять идентификатор, например: http://jsfiddle.net/ZDUEk/.

(function() {
    var ids = {}; // remember last id

    function Vehicle() {

    }

    Vehicle.prototype.applyVars = function() {
        var name = this.constructor.name, // Car or Truck
            id   = ids[name];

        if(!id) {
            id = ids[name] = 0; // init id
        }

        this.id = name + "-" + id; // set to form Type-X

        ids[name]++; // increment for next id
    };

    function Car() {
        this.applyVars(); // set id
    }

    function Truck() {
        this.applyVars(); // set id
    }

    Car.prototype = new Vehicle;
    Car.prototype.constructor = Car;

    Truck.prototype = new Vehicle;
    Truck.prototype.constructor = Truck;

    window.Vehicle = Vehicle;
    window.Car = Car;
    window.Truck = Truck;
})();

var car1   = new Car,
    car2   = new Car,
    truck1 = new Truck;

alert([car1.id, car2.id, truck1.id]);
1 голос
/ 20 сентября 2011

Использование Object.create и pd

// Vehicle prototype
var Vehicle = {
  drive: function() {
    // code
  },
  name: "Vehicle",
  counter: 0
}

// Car prototype
var Car = Object.create(Vehicle, pd({
  name: "Car",
  counter: 0
  // car methods
}));

// vehicle factory
var vehicle = function(data, proto) {
  proto = proto || Vehicle;
  data.id = proto.name + proto.counter++;
  return Object.create(proto, pd(data));
};

// car factory
var car = function(data) {
  return vehicle(data, Car);
};

Здесь вы хотите сохранить имя и счетчик на прототипах. Тогда ваш автомобильный завод просто генерирует новый идентификатор на счетчике и имени прототипа.

0 голосов
/ 21 сентября 2011

Я позаимствовал некоторые идеи из поста @ pimvdb и придумал этот фрагмент кода Coffeescript:

class Vehicle
    @ids = {}
    @name = 'Vehicle'
    constructor: ->
        @constructor.ids[@constructor.name] ?= 0
        @type = @constructor.name
        @id = "#{@type}-#{@constructor.ids[@type]++}"

class Car extends Vehicle
    @name = 'Car'

class Truck extends Vehicle
    @name = 'Truck'

car = new Car
alert car.id
car = new Car
alert car.id
truck = new Truck
alert truck.id
car = new Car
alert car.id

Можно проверить здесь: http://jashkenas.github.com/coffee-script/ (нажмите «попробовать coffeescript»)

Кажется, именно то, что я искал, спасибо.

0 голосов
/ 20 сентября 2011

Перевод вашего примера в более формальное описание: у некоторых конструкторов есть свой собственный дилер ID.

// a Vehicle has an id property, but no id dealer
function Vehicle( id ){
   this.id=id;
}
Vehicle.prototype.id = function(){ return this.id; }

// some objects can deal IDs
function IDDealer(){
   this.nextid=0;
}
IDDealer.prototype.nextId = function(){
   this.nextid ++;
   return this.nextid;
}


function Car(){
   Vehicle(this, idDealer.nextId() );
}
// a Car has a proper ID dealer
Car.prototype.idDealer = new IDDealer();


function Truck(){
   Vehicle(this, idDealer.nextId() );
}
// a Truck has a proper ID dealer
Truck.prototype.idDealer = new IDDealer();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...