ugrás a tartalomhoz

Ez late-binding?

b111 · 2016. Aug. 26. (P), 15.34
Sziasztok!

Szeretném ha valaki elmondaná, hogy mi zajlik a háttérben.

<?php
interface contact {
	public function getSign();
}

class post_office {
	public function send_message($recpt, $message) {
		$signature = $this->getSign();
		return $recpt . " " . $message . " " . $signature;
	}
}

class post extends post_office implements contact {
	public function getSign() {
		return "Joe Dow" . PHP_EOL;
	}
}

$post = new post();

$recpt = 'Gipsz Jakab';
$message = "Hello!" . PHP_EOL;

echo $post->send_message($recpt, $message);
A 8. sor lenne a kérdés. Második kérdésem, hogy ezt Java-ban hogyan kell megvalósítani. (PHP 7.0.8)

Köszönöm!
 
1

A post_office nem hívhatná

Poetro · 2016. Aug. 26. (P), 16.30
A post_office nem hívhatná meg a $this->getSign()-t mivel nem implementálja. És pont ezért Java-ban le sem fog fordulni. Legalább abstract osztálynak kellene lennie a post_office-nak, hogy meg lehessen adni a getSign fejlécét.
2

abstract OK

b111 · 2016. Aug. 26. (P), 17.12
Igen, abstract osztállyal jó Javaban.
3

Abstract

vbence · 2016. Aug. 27. (Szo), 16.07
Abstract is a thing of evil.
4

Miért?

smokey · 2016. Aug. 29. (H), 09.08
Miért?
5

Composition over inheritance

vbence · 2016. Aug. 29. (H), 22.38
A témakör "Composition over inheritance" címen fut leginkább. Röviden: ha örököltetsz, akkor a leszármazottad implicit módon példányosítja a szülőt, vagyis egy PirosAuto extends Auto ezt vonja magával: this.super = new Auto()
Vagyis a PirosAuto classba írt kódod csak a konkét Auto osztállyal együtt fog működni.

De mi a helyzet, ha a kódod felhasználójának már van egy Zsiguli példánya, aminek beállította a felnijeit meg a bőrülésket, és most szeretné használni a te pirosító kódodat? A Zsiguli is autó, viszont a te kódod csak az ősosztályt hajlandó példányosítani, fittyethányva az ő kedvenc Zsigulijára, amin olyan sokat dolgozott.

Ha viszont az öröklődéssel szemben komponálunk (például a Decorator minta alkamazásával), akkor a PirosAuto paraméterként várja azt az autót, aminek funkcionalitását kiterjeszteni hivatott.

Ha szeretnéd, hogy a PirosAuto átadható legyen-e Auto-t váró függvényeknek, akkor az Auto egy interfész lesz, amit a PirosAuto implementál. Az egyetlen hátrány, hogy a nyelv nem fogja mágikusan behelyezni a felül nem írott metódusokat az új osztályodba, mint ahogy öröklődésnél teszi. Itt neekd kell wrapperekben meghívnod az "ős" metódusait, még akkor is ha nem szeretnél változtatni azok működésén. - De egy valamire való IDE egyből legenrálja neked ezeket a funkciókat, egy valamire való runtime pedig eloptimizálja a +1 "call" CPU utasítást.
6

Azt azért érdemes lenne

inf · 2016. Aug. 30. (K), 17.03
Azt azért érdemes lenne hozzátenni, hogy mikor használod a Decoratort, és mikor overengineering. Mert mondjuk egy sima webshop-nál vagy akár egy autós játéknál is elég lehet egy `color` meg egy `shape` property az `Auto` példányba. Ha meg mondjuk egyedi autót terveztetsz, akkor a tervezőprogramba bekerülhet a decorator mindenféle nyalánksággal. Azért ez utóbbi a ritkább szerintem.
7

Overengineering

vbence · 2016. Aug. 30. (K), 20.26
Ilyet viccből se mondjunk.
9

Can you elaborate pls? ;-)

inf · 2016. Aug. 30. (K), 22.31
Can you elaborate pls? ;-)
10

Sok

vbence · 2016. Aug. 30. (K), 23.18
Túl sok ember, túl sokszor puffogtatta ezt amikor lusta volt a munkáját lelkiismeretesen végezni. Természetesen előfordulhat, de a jelenleg productionben lévő kód hány százaléka "lőtt túl a célon" patternek alkalmazásával, és hány százaléka az, ami átgondolatlan hekkelés eredménye, aminek elkészülése során fel sem merült egy-egy modernebb pattern használata?

Én bátran ajánlom mindnekinek, 10 esetből kilencszer jobban fogsz járni kompozícióval, mint örökléssel, ha szükséged van polimorfizmusra. (Ugyanezt tudom mondani egy DI konténerre new-zás helyett, és így tovább).

Publikus adatot meg publikus apiban használni (legalább is olyan nyelvekben, ahol nem létezik a property intézménye) kevés jó okból lehet. Az Android APIban elhiszem, hogy okkal döntöttek így egykét helyen, egy webshopban vagy játékban nem igazán tudok ilyen okot elképzelni.

A szakma jelenlegi siralmas helyzetében egy diszklémert írni egy tervezési minta bemutatása után csak arra jó, hogy alabit adjon annak, aki nem hajlandó semmi újat tanulni.

(Elnézést, kicsit érzékenyen érint a téma).
11

Csak arra akartam rámutatni,

inf · 2016. Aug. 31. (Sze), 02.30
Csak arra akartam rámutatni, hogy a példád a jelenlegi formájában egyáltalán nem indokolja a polimorfizmust és a Zsiga, PirosAuto, stb. osztályok meglétét. Szóval nem egy jó példa. Esetleg egy cikkben ki tudnád fejteni a composition over inheritance alapelvet egy ennél jobb példával. :-)
8

Nem teljesen értem, mire

smokey · 2016. Aug. 30. (K), 21.49
Nem teljesen értem, mire gondolsz. Tudnád szemléletetni bekezdésenként néhány sor kóddal a gondolatokat?
12

Nagyjából erről van szó a

inf · 2016. Aug. 31. (Sze), 02.55
Nagyjából erről van szó a composition over inheritance részben.

class A {
    public function a(){}
}

class AB extends A {
    public function b(){}
}

class AC extends A {
    public function c(){}
}

class ABC extends AB,AC {
}
Na ilyet nem lehet csinálni, mert nincs többszörös öröklés PHP-ben, szóval az ABC nem tud egyszerre két helyről örökölni, így nem tudod újrahasznosítani egyszerre a b() és c() metódusokat.

Öröklődés helyett kompozíciót szoktak használni:

class A {
    public function a(){}
}

class B {
    public function b(){}
}

class C {
    public function c(){}
}

class ABC {
    private $a;
    private $b;
    private $c;

    public function __construct(A $a, B $b, C $c){
        $this->a = $a;
        $this->b = $b;
        $this->c = $c;
    }

    public function a(){
        return $this->a->a();
    }

    public function b(){
        return $this->b->b();
    }

    public function c(){
        return $this->c->c();
    }

}
A példányosítást meg így tudnád megcsinálni:

$abc = new ABC(new A(), new B(), new C());
A gond ezzel, hogy nem valami újrahasznosítható a kód, meg nehezen módosítható, szóval érdemes egy DI container-be beszórni, aztán szétkapni az összeszerelés lépéseit:

class ABCContainer {

	public function getABC(){
		$a = $this->getA();
		$b = $this->getB();
		$c = $this->getC();
		$abc = new ABC($a, $b, $c);
		return $abc;
	}

	protected function getA(){
		return new A();
	}
	
	protected function getB(){
		return new B();
	}
	
	protected function getC(){
		return new C();
	}
}

$container = new ABCContainer();
$abc = $container->getABC();
Ezen túl az ABC osztályod viselkedése sem valami könnyen módosítható:

    public function __construct(A $a, B $b, C $c){
        $this->a = $a;
        $this->b = $b;
        $this->c = $c;
    }
Ugye itt az a baj, hogy bele van betonozva, hogy csak A, B, illetve C osztályok példányait használhatja. Szerencsésebb lenne, ha csak a használható osztályok felületét határoznánk meg.

interface iA {
	public function a();
}

interface iB {
	public function b();
}

interface iC {
	public function c();
}

class A implements iA {
	// ...
}

class B implements iB {
	//... 
}

class C implements iC {
	//... 
}

class ABC implements iA, iB, iC {

	// ...

    public function __construct(iA $a, iB $b, iC $c){
        $this->a = $a;
        $this->b = $b;
        $this->c = $c;
    }


	// ...
}
Így tudsz olyat csinálni, hogy


class A2 implements iA {
	public function a(){
		// valami más implementáció, mint az A osztálynál
	}
}

class ABCContainer {

	public function getABC(){
		$a = $this->getA();
		return $this->newABC($a);
	}

	public function getA2BC(){
		$a2 = $this->getA2();
		return $this->newABC($a2);
	}

	protected function newABC(iA $a){
		$b = $this->getB();
		$c = $this->getC();
		$abc = new ABC($a, $b, $c);
		return $abc;
	}

	protected function getA(){
		return new A();
	}

	protected function getA2(){
		return new A2();
	}
	
	protected function getB(){
		return new B();
	}
	
	protected function getC(){
		return new C();
	}
}

$container = new ABCContainer();
$abc = $container->getABC();
$a2bc = $container->getA2BC();
De akár többféle container-t is csinálhatsz különböző szituációkra, ha úgy esik jól.

Ezen az úton kellene elindulni örököltetés helyett.
13

Köszi a terjedelmes példát,

smokey · 2016. Aug. 31. (Sze), 09.53
Köszi a terjedelmes példát, teljesen értem mire gondolsz, ezt a metodológiát nap mint nap alkalmazom én is, és eléggé bejön. A mostani project, amin dolgozom Silex keretrendszerre épít és ezt az egész logikát nagyon szépen támogatja.

Viszont tartom azt a véleményt, hogy van értelme az absztrakciónak és nem olyan ördögi dolog, ha arra használja az ember, amire való (pl.: strategy pattern, általános entitások vagy bármilyen más osztályok kiterjesztése esetén, ahol az ősből nincs értelme példányt készíteni).

Szerintem sok vitát szűlt már hasonló kérdéses dolog, hogy egy adott témakörben két alternatív lehetőség közül melyiket érdemesebb alkalmazni. Sokszor azt veszem észre, hogy mindenkinek igaza lehet, kérdés, hogy egy adott megoldás milyen kontextusban állja meg a helyét.

Pl.: objektum orientált programozás vs funkcionális programozás; mindegyik lehet jó választás és rossz választás is; viszont, hogy adott esetben melyik a jó azt szerintem a probléma dönti el; pl.: üzleti alkalmazás vs komplex matematikai alkalmazás esetén az asszociáció egyértelmű (szerintem).

Múltkor sikerült részt vennem egy témájában viszonylag OFF beszélgetésben itt Weblaboron, most nem szeretném ebbe az irányba elvinni ezt a beszélgetést. Ha van értelme folytatni ezt a szálat, akkor azt javaslom nyissunk egy új témát.
14

Na örülök, akkor ezzel a

inf · 2016. Aug. 31. (Sze), 16.29
Na örülök, akkor ezzel a részével nincs gondod.

Szerintem is probléma függő, hogy mi a legjobb megoldás, vagy akár több jó megoldás is lehet. Jó lenne erről többet beszélni, mint állandóan egyik vagy másik megoldást sulykolni.