Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 11.09.2013, 23:35
Аватар для Murdoc
Аспирант
Отправить личное сообщение для Murdoc Посмотреть профиль Найти все сообщения от Murdoc
 
Регистрация: 04.05.2013
Сообщений: 45

Наследование прототипов
Шаблон фабрика(фабричный метод) создает объекты в зависимости от контекста.

Помимо создания нужно унаследовать как прототип фабрики, так и прототип используемого конструктора.

Как это грамотно реализовать?

Код:

define(['TankModel', 'ShipModel'], function (Tank, Ship) {
  // Factory GameModel
  function GameModel() {}

  // общие методы, которые наследуются всеми
  GameModel.prototype.getType = function () {
     console.log('this getType');
  };

  // фабричный метод
  // type - тип конструктора
  // params - данные для конструктора
  GameModel.factory = function (type, params) {
    var object;

    // вывести ошибку, если конструктор
    // для запрошенного типа отсутствует
    if (typeof GameModel[type] !== 'function') {
      throw {
        name: 'Error',
        message: type + ' не существует'
      }
    }

    // тут нужно унаследовать содержимое фабричного прототипа
    // делать это каждый раз при использовании одних и тех же конструкторов не нужно
    if (typeof GameModel[type].prototype.getType !== 'function') {
      GameModel[type].prototype = new GameModel();
    }

    // тут возвращается объект от конструктора [type]
    object = new GameModel[type]();

    // работа с готовым объектом:

    // это метод конструктора
    object.initialize(params);
    // это метод фабрики
    object.getType();

    return object;
  };

  // делает танки
  GameModel.tank = Tank;

  // делает корабли
  GameModel.ship = Ship;

  return GameModel;
});



Создание объекта:

var tank = GameModel.factory('tank');
var ship = GameModel.factory('ship');





Эта фабрика не работает. Фабричные методы затираются при вызове конструктора

Последний раз редактировалось Murdoc, 11.09.2013 в 23:40.
Ответить с цитированием
  #2 (permalink)  
Старый 12.09.2013, 04:35
Аватар для Murdoc
Аспирант
Отправить личное сообщение для Murdoc Посмотреть профиль Найти все сообщения от Murdoc
 
Регистрация: 04.05.2013
Сообщений: 45

Скопировал фабричные (общие) методы в свойство объекта (жду критики):

define(['TankModel', 'ShipModel'], function (Tank, Ship) {
  // Factory GameModel
  function GameModel() {}

  // общие методы, которые наследуются всеми
  GameModel.prototype.getType = function () {
     console.log('this getType');
  };

  // фабричный метод
  // type - тип конструктора
  // params - данные для конструктора
  GameModel.factory = function (type, params) {
    var object;

    // вывести ошибку, если конструктор
    // для запрошенного типа отсутствует
    if (typeof GameModel[type] !== 'function') {
      throw {
        name: 'Error',
        message: type + ' не существует'
      }
    }

    // тут возвращается объект от конструктора.
    // В качестве аргумента идет прототип объект,
    // который сохраняется в свойство объекта
    object = new GameModel[type](GameModel.prototype);

    // работа с готовым объектом:

    // это метод конструктора
    object.initialize(params);

    // это метод фабрики
    // все методы фабрики скопированы
    // при инициализации объекта
    // и доступны как object.gameModel['метод']()
    object.gameModel.getType();

    return object;
  };

  // делает танки
  GameModel.tank = Tank;

  // делает корабли
  GameModel.ship = Ship;

  return GameModel;
});




не думаю что это лучшее решение
и это уже не наследование, а копирование. А значит требует ресурсы памяти

Последний раз редактировалось Murdoc, 12.09.2013 в 17:45.
Ответить с цитированием
  #3 (permalink)  
Старый 13.09.2013, 14:39
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Не очень удачно по моему.
object = new GameModel[type](GameModel.prototype);
object.initialize(params);

Как то странно подмешиваемые методы передавать как параметр конструктору, а инициализацию дергать потом отдельно. По крайней мере здесь причин для этого я не вижу.


Вроде вот так как то по привычнее будет.
define(['TankModel', 'ShipModel'], function (Tank, Ship) {

    function GameModel( type, params){   
       //Проверка на наличие конструктора
       if (typeof GameModel[type] !== 'function') {
           throw {
               name: 'Error',
               message: type + ' не существует'
           }
        }

        var instance=new GameModel[type](params);

        //если нужно то можно подмешать методы фабрики        
        instance.getType=GameModel.prototype.getType;

        return instance;
    }

    //Перечислим продукты которая может создавать фабрика
    GameModel.Ship=Ship;
    GameModel.Tank=Tank;
    

    //методы которые можно подмешивать
    GameMode.prototype.getType=function(){
       //бла бла
    }    
});


Или может быть даже так
Добавим подмешиваемые методы сразу в прототип.

define(['TankModel', 'ShipModel'], function (Tank, Ship) {

    function GameModel( type, params){   
       //Проверка на наличие конструктора
       if (typeof GameModel[type] !== 'function') {
           throw {
               name: 'Error',
               message: type + ' не существует'
           }
        } 

        return new GameModel[type](params);
    }

    //метод для добавления новых продуктов к фабрике
    GameModel.add=function(name,obj){
        //примеси
        obj.prototype.getType=GameModel.prototype.getType;
        GameModel[name]=obj;
    }

    //Перечислим продукты которая может создавать фабрика
    GameModel.add('Ship',Ship);
    GameModel.add('Tank',Tank);
    
    //методы которые можно подмешивать
    GameModel.prototype.getType=function(){
       //бла бла
    }    
});


Последний вариант это собрать все примеси в одном специализированном объекте, но так чтобы они могли работать с экземпляром. Первый приходящий на ум способ сделать это не вмешиваясь в работу конструктора, просто сохранить ссылку на экземпляр в замыкании.

define(['TankModel', 'ShipModel'], function (Tank, Ship) {

    function GameModel( type, params){   
       //Проверка на наличие конструктора
       if (typeof GameModel[type] !== 'function') {
           throw {
               name: 'Error',
               message: type + ' не существует'
           }
        } 

        var instance=new GameModel[type](params);
        instance.GameModel=Inclusions(instance);
        return instance
    }

    //набор включений которые добавляются фабрикой в экземпляр
    function Inclusions(obj) {
        return {
            getType:function(){
                 return typeof obj;
            }
        }
    }   

});

//вместо 
instance.GameModel=Inclusions();
//хватило бы и
instance.GameModel={f1:function(){}, f2:function(){}}
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 14.09.2013 в 21:47.
Ответить с цитированием
  #4 (permalink)  
Старый 13.09.2013, 14:51
Аспирант
Посмотреть профиль Найти все сообщения от iLikeMaxmaxmaximus
 
Регистрация: 07.08.2013
Сообщений: 50

я не совсем понимаю как работает фабрика (да да пасоны я реал не понмиаю)

но как сделать цепочку прототипа обьяснить могу



function Animals (){

  function Cat (){}
  Cat.prototype = Object.create(Animals.prototype);

  function Rabbit (){}
  Rabbit.prototype = Object.create(Animals.prototype); 

}




кот и кролик наследуют прототип свой и прототип фабрики

Последний раз редактировалось iLikeMaxmaxmaximus, 13.09.2013 в 15:06.
Ответить с цитированием
  #5 (permalink)  
Старый 13.09.2013, 23:58
Аватар для Murdoc
Аспирант
Отправить личное сообщение для Murdoc Посмотреть профиль Найти все сообщения от Murdoc
 
Регистрация: 04.05.2013
Сообщений: 45

DjDiablo, как раз то что нужно.
Выбрал 2-й вариант

Спасибо!

Последний раз редактировалось Murdoc, 16.09.2013 в 00:07.
Ответить с цитированием
  #6 (permalink)  
Старый 14.09.2013, 01:53
Аватар для Murdoc
Аспирант
Отправить личное сообщение для Murdoc Посмотреть профиль Найти все сообщения от Murdoc
 
Регистрация: 04.05.2013
Сообщений: 45

доработал функцию add немного:

// метод для добавления новых продуктов к фабрике
  GameModel.add = function (name, object) {
    var props = GameModel.prototype
      , i;

    for (i in props) {
      if (props.hasOwnProperty(i)) {
        object.prototype[i] = props[i]
      }
    }

    GameModel[name] = object;
  };

Последний раз редактировалось Murdoc, 14.09.2013 в 11:11.
Ответить с цитированием
  #7 (permalink)  
Старый 14.09.2013, 13:59
Аспирант
Посмотреть профиль Найти все сообщения от iLikeMaxmaxmaximus
 
Регистрация: 07.08.2013
Сообщений: 50

к слову о красоте кода
// метод для добавления новых продуктов к фабрике
GameModel.add = function (name, object) {

    var props = GameModel.prototype;

    for (var i in props) if (props.hasOwnProperty(i)) {
        object.prototype[i] = props[i]
    }

    GameModel[name] = object;
};
Ответить с цитированием
  #8 (permalink)  
Старый 14.09.2013, 22:10
Аватар для Murdoc
Аспирант
Отправить личное сообщение для Murdoc Посмотреть профиль Найти все сообщения от Murdoc
 
Регистрация: 04.05.2013
Сообщений: 45

а чем мой плох? )
Ответить с цитированием
  #9 (permalink)  
Старый 15.09.2013, 22:43
Аспирант
Посмотреть профиль Найти все сообщения от iLikeMaxmaxmaximus
 
Регистрация: 07.08.2013
Сообщений: 50

Сообщение от Murdoc
а чем мой плох? )
мой красивее чем твой ты пишешь некурасивый код это мой плевок тебе в лицо

Последний раз редактировалось iLikeMaxmaxmaximus, 16.09.2013 в 08:51.
Ответить с цитированием
  #10 (permalink)  
Старый 16.09.2013, 00:04
Аватар для Murdoc
Аспирант
Отправить личное сообщение для Murdoc Посмотреть профиль Найти все сообщения от Murdoc
 
Регистрация: 04.05.2013
Сообщений: 45

а ну, если только в этом дело...
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Прототипное наследование не распространяется на вложенные свойства? novikov Общие вопросы Javascript 4 19.11.2012 14:31
Множественное наследование - миф или реальность?! B~Vladi Оффтопик 109 04.09.2012 16:13
Вопрос про ООП, цепочки прототипов. Shaci Общие вопросы Javascript 5 27.01.2010 14:50
Наследование Fliand Events/DOM/Window 0 12.08.2009 20:48
Наследование в CSS SunnyDay (X)HTML/CSS 14 06.10.2008 20:06