Adott egy oldObject es egy newObject (mindketto instanceof MyClass. oldObjectnek ha van egy property-je, elvesszuk tole, es atadjuk newObjectnek (tehat vagy mindkettobe write-olunk vagy egyikbe sem)
Melyik a helyes velemenyetek szerint?
// oldObject methodjakent
$oldObject->givePropToNewObject($newObject);
es/vagy
// newObject methodjakent
$newObject->takePropFromOldObject($oldObject);
es/vagy
// static methodkent
MyClass::movePropFromObjectToObject($oldObject, $newObject);
?
- 2279 megtekintés
Hozzászólások
Koncepcionálisan egyik sem tűnik jónak :)
- A hozzászóláshoz be kell jelentkezni
Es hogy lesz jo peldaul? (Scrollozz lentebb extra kikotesekert, mar nem tudom editalni)
- A hozzászóláshoz be kell jelentkezni
Az elso nem hiszem, hogy jo lenne (most nem tudom melyik principle, de nem tunik helyesnek).
A masodik mar jobban nez ki.
Harmadik eseten static method call van, az Javaban bad practice (nehez mockolni), de ez PHP, szoval nem tudom.
Mi lenne, ha a static helyett egy factory-d lenne?
$newObject = MyClass::createObject($oldObject);
?
Ez utobbi jobban olvashato, rogton latszik, hogy mi az uj object, nincs kimeneti parameter, ami jo, stb.
- A hozzászóláshoz be kell jelentkezni
Factory-nal oke, hogy valtozik az oldObject?
Amugy a kerdes nem PHP specifikus, es mukodo valasz sok van ra, csak szerintem tipikusan egy olyan kerdes, ahol sok konvencio es principle ellent fog mondani egymasnak, azert vagyok kivancsi.
- A hozzászóláshoz be kell jelentkezni
Jogos, azt nem vettem figyelembe.
A konvenciok, principle-k onmagukban is ellent mondanak egymasnak sokszor, szoval ez inkabb a fejlesztonek guideline, nem szentiras :)
Viszont ha nem createObject() a fv neve, hanem mittudomen transferProperty(), a peldamban, az szerintem elegsegesen jo lehet.
- A hozzászóláshoz be kell jelentkezni
Es a transferPorperty mindenkepp az egyik instance methodja legyen, vagy legyen static es varja a ket instance-t? Vagy ez neked mindegy?
- A hozzászóláshoz be kell jelentkezni
Nekem igazabol mindegy, szamomra csak annyi a fontos, hogy az uj objektum jelenjen meg az ertekadas bal oldalan (is). Akkor lehet szepen latni, hogy mibol mi lett, felesleges kodturkalas nelkul is.
- A hozzászóláshoz be kell jelentkezni
Amugy miert erzed ugy, hogy a masodik jobb lenne az elsonel? Mindkettonel ket atirodo object van, egyikbol hivod a methodot, masikat parameterkent adod at, en szememben a ketto ugyanaz.
- A hozzászóláshoz be kell jelentkezni
Nem tudom megmagyarazni, de valahogy jobbnak tunik atvenni valamit, mint atadni. Nem mellesleg a 2. peldanal a newObject van elol, szoval a kod olvasasakor egyertelmubb, hogy melyik az "igazi" object. A static callos, output parameterest, ugyan C orokseg, de nem eroltetnem. Engem az oruletbe kerget, ha bele kell masznom a kodba, hogy megertsem mi tortenik.
Sajnos nem talalom azt a cikket, nagyon jol leirta a funkcionalis programozas alapjat, marpedig azt, hogy a bemeneti parameterek fuggvenye a kimenet, mindig, determinisztikusan. Ugyan OOP-ben vagyunk, de mas paradigmakbol jo atvenni a jo otleteket :)
- A hozzászóláshoz be kell jelentkezni
Mar nem birom editalni, de tegyuk fel, hogy a fuggvenyhivaskor oldObjectnek es newObjectnek is private membere valtozik, amire (okkal) nincs semmilyen public setter. Tehat nem egy uj class "MyClassManager" fogja ezt megoldani.
A pelda PHP-s, de Javaban is erdekel pl., hogy melyik a helyes.
- A hozzászóláshoz be kell jelentkezni
Nem tudom mit probalsz elerni, de erzesre a megoldas az immutable objektumok teren keresendo. Ha tenyleg _mindketto_ valtozik, akkor Javaban teheted oket azonos csomagba es akkor hozzafersz a package-private adattagokhoz, de jo esellyel ez tervezesi hibara utal mert a fuggvenynek velhetoleg lesz mellekhatasa amire a fuggveny neve nem utal. (Egy create nevu fuggvenytol nem varnam azt, hogy a regi objektumban modosit barmit is.)
Kicsit konkretabb problemaleiras kellene, nem csak egy absztrakt pelda.
--
Pásztor János
Sole Proprietor @ Opsbears | Refactor Zone
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
Most torolhettem ki a kommentemet, mert leirtad, amit szerettem volna. GRRRRR :)
- A hozzászóláshoz be kell jelentkezni
Nem kell package private, hisz ugyanazon class példányai, szóval ez még PHP-vel is működik. Minden másban egyetértek.
- A hozzászóláshoz be kell jelentkezni
Szamomra nem volt egeszen tiszta, hogy ezek biztosan egyazon osztaly peldanyai. Ha ez igy van, akkor termeszetesen semmi problema.
--
Pásztor János
Sole Proprietor @ Opsbears | Refactor Zone
- A hozzászóláshoz be kell jelentkezni
Egy olyan peldat tudok most elkepzelni, hogy A objektumnak van egy elado biciklije, amit B megvesz, igy A is valtozik meg B is. Ilyen esetben nem az objektumok vegzik a muveleteket egymason, hanem egy 3dik kulso fel. Tipikusan az ilyen domain/dto objektumoknal minimalizalni kell az uzleti logikat, hiszen azok csak adatokat tarolnak, igy a levonas hozzaadas movelet az az uzleti logika resze. Midegy, hogy Javrol vagy PHProl van szo, ezz OOP.
Amennyiben 2 service layer kozott van ilyen relacio, az tervezesi hiba, mert azok nem allitgatjak egymas propertijeit.
- A hozzászóláshoz be kell jelentkezni
Jo, de ez esetben lesz egy sellBike vagy buyBike metodus, ami egyertelmuen jelzi, hogy itt bizony valtozas tortenik. A kerdezo regi es uj objektumrol beszel, sztem itt valami mas rejtozik.
--
Pásztor János
Sole Proprietor @ Opsbears | Refactor Zone
- A hozzászóláshoz be kell jelentkezni
+1
Jó lenne, ha a kérdező tisztázná, hogy pontosan miről is van szó.
- A hozzászóláshoz be kell jelentkezni
A biciklis elados pelda eleg kozel jart.
Ezenfelul a valaszokbol rajottem, hogy amit en terveztem kodot, ott nem futottam volna ilyen problemaba. Itt egy taknyolt megoldast kellett tovabbtaknyolni, ahol ez ebben a formaban merult fel. (Bonyolult lenne elmagyarazni miert, de ne gondoljatok egy tul jo kodra, attol meg, hogy tele volt a forras class-okkal, nem eppen volt objektumorientalt :P )
- A hozzászóláshoz be kell jelentkezni
Nem baj az, nem vagy egyedul regi rendszerekkel, csak arra figyelj hogy mindig kicsit szebben hagyd ott a kodot mint amikor nekikezdtel. Lehet lapos hulyesegnek tunik, de ha eleget gyakorolja az ember, a vegen altalaban egy eleg tisztesseges rendszer jon ki belole.
--
Pásztor János
Sole Proprietor @ Opsbears | Refactor Zone
- A hozzászóláshoz be kell jelentkezni
+1
----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"
--> YouTube csatornám
- A hozzászóláshoz be kell jelentkezni
+1
Én is az immutable megoldásra szavazok!
- A hozzászóláshoz be kell jelentkezni
Szerintem mindhárom példa procedurális megoldás, OOP-ben ez úgy nézne ki hogy van egymásra referenciájuk belül és hozzáférnek ahhoz ami szükséges.
- A hozzászóláshoz be kell jelentkezni
Ebbol lesz a vad kaosz :) Mert ha sima dto-k akkor ott nem kell, hogy tudjanak egymasrol. De ha valami uzleti logikat inteznek, akkor sosem lehetsz benne biztos, hogy hogyan viselkedik a cucc, hiszen barmikor megvaltozhat a mukodese (abba bele se menjunk, ha mondjuk multi thread akarod pocogtetni). Szoval erdemes elvinni immutable iranyba a dolgot, es minden viselkedes valtozaskor uj peldanyt gyartani.
- A hozzászóláshoz be kell jelentkezni
Igen, ha a példa EJB3-as konténerektben zajlik és az átadás aszinkron SOAP hívás valamilyen 3rd party queue-n keresztül és a két POJO-ról ami tartalmazza az adatot nem tudunk semmi determinisztikusat mondani, akkor vad káosz 2 év múlva amikor 6 másik ember próbálja az új üzleti logika által okozott incidenseket megoldani.
De ha ügyesen elolvasod mégegyszer a szerző kérdését akkor azt kérdezte OOP szemlélettel két Foo ojjektum hogy is csinálja ezt.
- A hozzászóláshoz be kell jelentkezni
Nezd ha ez valami 1 szemelyes hobbiprojekt, akkor vegulis mindegy, hogy hogy csinalja nem? Amire ki szeretnek lyukadni, hogy a kerdezo azt kerdezte, hogy egy ilyen problemat, hogyan lehet oop szemlelettel megoldani, es nem hiszem, hogy azt kene neki "tanitanunk", hogy hannyon bele minel tobb kereszthivatkozast a kodjaba, mert vegulis fordul meg mukodik is. Nem kell ahhoz EJB kontener, hogy megfelelo retegekre szetdarabold az alkalmazasod, es minimalizald vagy legalabbis lokalizald a side effecteket.
- A hozzászóláshoz be kell jelentkezni
Azt kérdezte elméletben mi a helyes OOP, te meg ráhúztad a saját tapasztalatod kontextusát. Amiben igazad lenne ha egy valós problémát próbálnánk itt megoldani nem pedig 3 sornyi Foo kód lenne a posztban.
Az hogy számodra a dependency injection témaköre keresztbehányás pedig téged minősít.
- A hozzászóláshoz be kell jelentkezni
"pedig téged minősít" az meg teged minosit, hogy minositgetsz itt barkit, es szemelyeskedsz te bunko. Tetelezzuk fel, hogy te nem tudsz elrugaszkodni a mareknyi kodtol, es nem tudsz olyan megoldast adni egy teoretikus kerdesre, ami jol skalazodik? Akkor ez most teged is minosit? Te komolyan azt gondolod, hogy a kerdezonek nincs fogalma a referencia szerinti atadasrol, es nincs tisztaban azzal, hogy ha van referencia, akkor azon keresztul meg tudja valtoztatni az objektum allapotat? Az altalad javasolt alpari megoldasra magatol is rajott, ahhoz nem kell valami sok esz. Arrol nem is beszelve, ha egymasra tarolnak hivatkozast, akkor azt mar peldanyositaskor be kell allitani, melyikbe huzod be a masikat, ha oda vissza kell kapcsolat, akkor korkorosen behuzod oket? Mi van ha 100 kapcsolat van? Probalj meg elszakadni a helloworld szinttol, es javasolj valami olyan dolgot ami a foobar-on kivul massal is mukodik.
- A hozzászóláshoz be kell jelentkezni
Nem latom, a javaslatod mitol lenne OOP, minek kell a ket osztalynak foltetlenul tudnia, hogy egy bizonyos adat a masik tipusban lelheto fel, vagy hogy a masik tipus ojjektuma letezik egyaltalan. OOP nem arrol szol, hogy mindent mindennel osszedrautozunk.
Szerk: ok, beneztem, itt MyClass ket peldanyarol van szo. Mondjuk akkor sem ertem, hogy miert kene a peldanyoknak foltetlenul tudniuk egymas letezeserol egy adat megosztasa vegett. Persze, lehet ertelme, csak OOP szerintem nem kovetelne ezt meg alapbol.
----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"
--> YouTube csatornám
- A hozzászóláshoz be kell jelentkezni
Nem biztos, hogy egyáltalán API metódust csinálnék ebből.
Ha pl. van egy fa adatstruktúrád, amiben vannak csomópontok, és ezen a fán illetve a csomópontokon bizonyos műveleteket végzel, lehet olyan művelet, ami több csomópontot módosít egyszerre. Ilyenkor én csak a fa osztályt és annak a fő műveleteit (addNode, removeNode, balance, stb.) ajánlanám ki, az egyes csomópontok mezőinek a módosítgatása mind privát, és külön privát metódus se feltétlenül kell rá, ha olyan egyszerű, mint pl. egy mező módosítása.
Vagy ha van egy bankszámla osztályod, és egyikről másikra utalsz pénzt, tuti nem így fog kinézni a publikus API, mint amit írtál, hanem lesz egy tranzakció manager osztály vagy valami, ami megkapja, hogy honnan-hova-mennyit, és ő majd felépíti és módosítgatja a bankszámla objektumokat a saját privát implementációjában.
Általánosságban szerintem legjobb az immutable value object, ami önmagában sok gondot megold, és publikus API-n is ki lehet ajánlani nyugodtan, neki saját logikája nincs. Írható-olvasható objektumokkal már vigyázni kell, ebből kétfélét tudok elképzelni. Az egyik az olyan, amit gyakorlatilag nem lehet elrontani, pl. egy lista, ezt lehet rétegek között passzolgatni, van benne publikus tag/privát tag/némi logika, de itt fontos, hogy nem beszélget másik objektumokkal (mert akkor lenne furcsa mellékhatása, el lehetne rontani), és itt is jobb, ha immutable. A másik, aminek ugyan minden tagja publikus, de nincs benne logika, és nincs kiajánlva sem, egy API dolgozik rajta belül.
- A hozzászóláshoz be kell jelentkezni
Esetleg lehetne egy-két interface a történetben:
CanBeOwned -- valami, aminek van/lehet gazdája, pl bicikli
metódusok: getOwner, setOwner
CanBeOwnerOf (CanBeOwned object) -- valaki, aki gazdája lehet egy ilyennek
metódusok: gotObject, lostObject
TransferObject (CanBeOwned object, CanBeOwnerOf(object) from, CanBeOwnerOf(object) to) -- átadás
- A hozzászóláshoz be kell jelentkezni
Mit értesz az alatt, hogy elvesszük a propertyt és átadjuk a másiknak?
A propertyk halmaza változik, vagy a propertyk halmaza ugyanaz marad, csak épp az értékek módosulnak? old adott propertyjének értéke null lesz, a new propertyjének értéke meg kitöltődik?
Előbbi esetben meg nem mondható, hogy mindkettő instanceof Myclass.
- A hozzászóláshoz be kell jelentkezni
+1
Ezt én sem értem, hogy mit jelent, hogy elveszi a property-t.
Mások úgy értelmezik, hogy változik az értékük, és mivel a kérdezőt Java-ban is érdekli a megoldás, így hajlok rá, hogy tényleg ez lehet és nem dinamikusan módosul az objektum.
- A hozzászóláshoz be kell jelentkezni
nem biztos, hogy sokat bonyolitanam es lehet nem tanultam a kulonbozo elvekrol sokat, de ahogy szoktam:
$newObject->setPropertyValami($oldObject->getPropertyValami());
aztjonapot.
amugy meg ha ez c# lenne
ValamiObject oldObject = ....
ValamiObject newObject = new ValamiObject();
...
newObject.Valami = oldObject.Valami;
ami meg felmerul itt szerintem az az, hogy ezek tenyleges ertekek vagy csak referenciak egy objectre, mert akkor nem biztos, hogy az = jo
hanem mondjuk a clone kell neked, de ez meg mar messzire vezet es nem tudom mi a cel vele, de sima int-nel nem sokat szorakoznek.
es mint tudjuk a c#ban csak nyelvi konnyedseg a newObject.Valami mint property ez javaban es mashol igy jelenik meg newObject->getValami() es newObject->setValami(var valami)
szoval a legkozelebbi jo megoldas szerintem a hozzaszolasokbol, a bal oldalon van ami kapja es jobb oldalon ami adja
ez olvashato
szepnap
- A hozzászóláshoz be kell jelentkezni
"$newObject->setPropertyValami($oldObject->getPropertyValami());" az a gondd, hogy jelen peldaban a getPropertyValami() az megvaltoztatja az $oldObjectet, szoval nagyon felrevezeto a neve.
- A hozzászóláshoz be kell jelentkezni
Szerintem tulbonyolitod a dolgot. Kezdve azzal, hogy az egesz OOP koncepciot erosen el-erodalta a dependency injection es a funkcionalis programozas felivelese. Ma mar senki se csinal bonyi design pattern-eket, mert a tobbseguk obsolete lett azota.
Amit en szoktam csinalni es IMHO a legjobb: szeparalni az adatot es a logikat. Az adat class -ban csak adat legyen (ez lehet immutable is ekkor, az a legtisztabb), mig a kulonbozo logic class-ok vegzik a muveleteket az adaton. Ez utobbiak egymast egymasnak DI-zik igeny szerint. Az adat class-ok meg a kulonbozo DI contexteket is felvehetnek (global, session, request).
Ilyenkor az adat class tiszta (en getter/settert se rakok bele, csak public final field-eket), a logic meg siman keszit uj adat class instance-t. A fenti kerdes tehat moot, mert siman igy nezne ki:
new = logic.copyProperty(new, old);
logic.removeProperty(old);
- A hozzászóláshoz be kell jelentkezni
Ha logikai class-ban nincs adat, akkor egyáltalán miért kell példányosítani, miért nem static az összes függvénye?
Ilyenkor nincs szükség DI-re se.
- A hozzászóláshoz be kell jelentkezni
Mert static callt (legalabbis Javaban) nem tudsz mockolni, csak reflectionnel. Az meg mar belepiszkalas a (byte)kodba, nem szep dolog.
- A hozzászóláshoz be kell jelentkezni
Byte code instrumentation-ra gondolthattal, amit pl. Powermock csinal, nem Reflection-ra...
----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"
--> YouTube csatornám
- A hozzászóláshoz be kell jelentkezni
Koszi a helyesbitest!
- A hozzászóláshoz be kell jelentkezni
Ha pure function, akkor nem is kell mockolni.
Egyébként igazad van, ha nem pure function-ök vannak benne, akkor kell a DI vagy hasonló.
- A hozzászóláshoz be kell jelentkezni