Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   вопрос о реализации (https://javascript.ru/forum/misc/58178-vopros-o-realizacii.html)

caetus 08.09.2015 17:22

вопрос о реализации
 
есть например 3 вида уток
обычная утка: умеет летать , плавать и крякать!
деревянная: только плавать!
резиновая: плавать и крякать !

есть например массив всех уток [] и в переборе нужно вызвать кряканья у всех уток которые это умеют !

одним словом паттерн стратегия !

я сделал так !
хочу услышать ваше мнения на счет этого ...
Рони ? ))

var Duck = (function () {

	var Duck = function (name) {
		if(!(this instanceof Duck)) return new Duck(name);

		this.name = name;
	}

	var F = function () {};


	var proto = {
		duckWooden: Object.create(F.prototype),
		duckUsual: Object.create(F.prototype),
		duckRubber: Object.create(F.prototype)
	}
	
	var obj =  {
		duckWooden: function (name) {
			if(Duck.prototype != proto.duckWooden) 
				Duck.prototype = proto.duckWooden;
			
			return Duck(name)
		},
		duckUsual: function (name) {
		
			if(Duck.prototype != proto.duckUsual)
				Duck.prototype = proto.duckUsual;
			
			return Duck(name)
		},
		duckRubber: function (name) {
		
			if(Duck.prototype != proto.duckRubber)
				Duck.prototype = proto.duckRubber;
			
			return Duck(name)
		},
		prototype: F.prototype
	}
	
	for(var i in proto) {
		proto[i].constructor = obj[i];
		obj[i].prototype = proto[i]
	}

	return obj;

})();

Duck.prototype.fly = function () { console.log('i fly') }
Duck.prototype.quack = function () { console.log('quack quack! my name '+ this.name)	}
Duck.prototype.swim = function () {	console.log('i swim') }


var wooden = Duck.duckWooden('Della')

Duck.duckWooden.prototype.fly = function () {};
Duck.duckWooden.prototype.quack = function () {};
Duck.duckRubber.prototype.fly = function () {};
Duck.prototype.remove = function () {};

var rubber = Duck.duckRubber('Donald')
var usual = Duck.duckUsual('Billi')

rubber.quack()
usual.quack()
wooden.quack()

console.log(wooden, rubber, usual)

Lemme 08.09.2015 18:26

caetus, а что, если типов уток будет 15? Геморой какой-то....
ES6 на вас не хватает =)

class Duck {

  constructor(name) {
    this.name = name;
  }

  quack() {
    console.log(`${ this.name }: quaack!`);
  }

  fly() {
    console.log(`${ this.name }: looks at you from height!`);
  }

  swim() {
    console.log(`${ this.name }: I'm swimming like a fish!`);
  }
}

const duck = new Duck('Foo');

duck.quack(); // quaack!
duck.fly(); // looks at you from height!
duck.swim(); // I'm swimming like a fish!


class WoodenDuck extends Duck {
	
  constructor(name) {
    super(name);
  }
  
  quack() {
  	console.log(`${ this.name }: I wanna quack, but I can't...`);
  }
  
  fly() {
    console.log(`${ this.name }: throw me to see how I fly!`);
  }
}

const wd = new WoodenDuck('Bar');

wd.swim(); // Bar: I'm swimming like a fish!
wd.fly(); // Bar: throw me to see how I fly!


Правда, так делать нелогично, ведь зачем деревянной утке знать о том, что она не умеет?=)

forwardonly2015 08.09.2015 19:18

AbstractDuck={
 create: function(){return Object.create(this)},
 extend: function(src){
   for(var i in src){
     if(!src.hasOwnProperty(i)) return this
     this[i]=src[i]
   }
   return this
 },
 swim: function(){console.log("I am swimming")}
}
RealDuck=AbstractDuck.create().extend({
  quack: function(){console.log("My name is "+this.name+", quack, quack.")}
})
RubberDuck=AbstractDuck.create().extend({
  quack: RealDuck.quack
})
WoodDuck=AbstractDuck.create()


;[
  RealDuck.create().extend({name: "Donald"}),
  RubberDuck.create().extend({name: "RubberDonald"}),
  WoodDuck.create().extend({name: "Woody"})
].forEach(function(duck){if(duck.quack) duck.quack()})



//My name is Donald, quack, quack.
//My name is RubberDonald, quack, quack.

рони 08.09.2015 19:29

forwardonly2015,
почему не
extend: function(src){
   for(var i in src){
     if(src.hasOwnProperty(i)) this[i]=src[i]
   }
   return this
 }

forwardonly2015 08.09.2015 20:14

рони,
Чтобы не обходить все прототипы, тк нам, в данном случае, нужна только верхняя часть.

nerv_ 09.09.2015 00:23

Lemme, + за адекватный ответ :)

только не
const duck

а
let

или константу пиши большими буквами

Lemme 09.09.2015 00:38

nerv_, да, я помню про константы и большие буквы (так принято), но, как я понял, тут (в js) константа == let, только без возможности изменения значения, т.е - лучше использовать const, вместо let, если значение этой "переменной" меняться не будет/не должно.

Это выводы - сделанные после прочтения тонны документаций, статей, туторов. О react, flux, redux. etc (там такого не сказано, но когда смотришь код - это замечаешь).

Да и частенько в репозиториях видел в .eslint
prefer-const: 1


Поэтому я и пишу, если это константа, то большими, типо -

// это константа в прямом смысле этого слова.
const API_KEY = '412akejkrlqw64e3qw';

// а это лишь указывает на то, что значение этой переменной никогда меняться не должно
// поэтому используем константу
const duck = new Duck();


Не знаю, почему у меня так сложилось, мб, когда много читаешь(кода) - оно откладывается на подсознательном уровне "как Попов у некоторых", а может это реально логично, или защита от дурака =), или же, const использует меньше памяти/чистится проще, я хз в общем.

forwardonly2015 09.09.2015 00:53

Цитата:

Сообщение от Lemme
так делать нелогично, ведь зачем деревянной утке знать о том, что она не умеет?=)

Так ведь она и не должна знать, это конкретно в твоей реализации она знает почему-то.

Lemme 09.09.2015 01:23

forwardonly2015, да это само собой, просто я написал пример - как это выглядит на ES6, а не о том "треше", когда чтоб добавить новую "утку", нужно перелопатить весь код. Т.е банальное наследование.

На самом деле - мне было лень писать абстрактный класс, а потом еще утки =)

т.е

class AbstractDuck {

	constructor(name) {
		this.name = name;
	}

	// все утки умеют плавать	
	swim(name) {
		// TODO
	}
	
	// не все утки умеют летать, поэтому пусть это будет "будто" метод интерфейса
	fly() {}

	// другие общие методы
}

class Duck extends AbstractDuck {
	
	constructor(name) {
		super(name);
	}

	// а эта - умеет еще и летать.
	fly() {
		super();
		// TODO
	}

	// другие методы
}


Да и знания мои в ООП - забей ваще, допустим - "обычная утка" и "резиновая" умеют крякать, одно дело, если они крякают по разному тогда есть смысл реализовывать для них разные методы quack, но если методы идентичны, а в абстрактный класс их не вынесешь, ибо возвращаемся к тому, что "деревянная" утка будет знать о том, что знать не должна, а если реализовывать - как и задумано, т.е перегружать методы, то получится копипаст, а это тоже не ок=)

рони 09.09.2015 01:24

forwardonly2015,
тогда почему не
extend: function(src){
   for(var i in src){
     if(!src.hasOwnProperty(i)) break;
     this[i]=src[i]
   }
   return this
 },


Часовой пояс GMT +3, время: 13:54.