|
|
|
|
| Zitat von PutzFrau
Was ist das denn für eine in Anwendung, die 15000 bool Flags braucht?
| |
|
|
|
|
|
|
|
Ein menschlich konfigurierbarer random forest?
|
|
|
|
|
|
|
Konfigurierbar klingt ein bisschen so, als sei das nicht die einzige Methode.
|
|
|
|
|
|
|
| Zitat von PutzFrau
Was ist das denn für eine in Anwendung, die 15000 bool Flags braucht?
| |
Pago arbeitet vielleicht bei Oracle?
e: Aber so allgemein ist das glaube ich nicht ungewöhnlich bei Software mit "wenigen aber wichtigen" Kunden, dass da halt irgendwas reinkommt und man dann halt irgendwo nen paar magische Flags einbaut um das gewünschte Verhalten irgendwie zu ermöglichen *hust*
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von csde_rats am 28.08.2021 12:52]
|
|
|
|
|
|
Hm, geraten: was mit SAP?
Ansonsten, gibt es für eure Sprache sowas wie ein Config Framework? Normalerweise sind die ja auf viele Anwendungsfälle direkt optimiert, bieten das einheitliche Interface, clevere Merge/Default Strategien und haben oft Caches in gut schon eingebaut...
Vielleicht ist das ein Weg Stück für Stück zu sowas zu migrieren und dabei genau das Verhalten und die Performance zu überprüfen.
Dann könnte man die Config vielleicht auch neu schneiden und spezialisieren, damit man gar nicht erst alles laden muss an der Stelle.
Ansonsten passiert recht viel bei Key-Value-Stores, die auch ziemlich fix sind (Beispiel: Redis). In sowas vielleicht mal reingeschaut?
Das wird dir alles nicht neu sein, nur ohne Kosten fällt mir auch nichts ein. Mehr Caches über Caches... kann man machen, debuggen will man das irgendwann aber nicht mehr.
|
|
|
|
|
|
|
Jedes if ist ein Bug, und jeder Cache ein Heisenbug. Bei etwaigen Gegenbeispielen wurde der Bug nur noch nicht gefunden.
|
|
|
|
|
|
|
| Zitat von PutzFrau
Was ist das denn für eine in Anwendung, die 15000 bool Flags braucht?
| |
Ein Code-Autoformatter, dass jeder Kunde seinen Lieblingsstil durchsetzen kann.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Danzelot am 28.08.2021 14:04]
|
|
|
|
|
|
Wir haben einen Nachfolger für ein extern eingekauftes Tool entwickelt. "KeyUser" (besondere User) beta seit Anfang Mai, offene Beta seit Anfang Juni, produktiv seit Anfang Juli. Abschaltung des VOrgängertools am 1.10.
Jetzt kam die erste Eskalation rein, es sei nicht nutzbar etc.pp. Ich wette, je näher der 1.10. rückt, desto mehr Aufschreie gibt es, und wenn die alte Software abgeschaltet wird dann heißt es sicher: HAT UNS NIEMAND GESAGT (haben wir), TESTPHASE WAR ZU KURZ (war sie nicht), DAS TOOL IST SCHEIßE (ist es nicht), ICH KANN NICHT ARBEITEN (kannst du).
<3 Konzernlife.
|
|
|
|
|
|
|
"ich kann nicht arbeiten" ist dann immer Code für "die Menüeinträge, die ich auswendig kenne, sind weg"?
|
|
|
|
|
|
|
| Zitat von Oli
Wir haben einen Nachfolger für ein extern eingekauftes Tool entwickelt. | |
wieso?
ich bin jedes mal happy, wenn irgend ne inhouse zusammengeklöppelte und historisch mutierte scheiße mit software von der stange ersetzt wird. machts so viel einfacher hinten raus und man hat auch einfach mal offizielle standards.
|
|
|
|
|
|
|
Weil wir die outhouse zusammengeklöppelte und historisch mutierte scheiße ersetzen wollten, die das Unternehmen viel Geld kostet. Und weil das Tool sehr stark verzahnt mit unserer Support Arbeit ist, die vorher auch von dem selben Dienstleister gemacht wurde. Die Synergie haben wir jetzt quasi wieder hergestellt. Außerdem haben wir die Zeit und das Können.
Davon abgesehen finde ich es eine Pest, wenn alles eingekauft wird.
|
|
|
|
|
|
|
Ich habe eine generelle frage wie ihr folgende Situationen / Patterns umsetzt/handahbt.
Etwas Pseudocode:
|
Code: |
MeinController.php
class UserController{
public function login(Response $respnse, $userId){
if($userId == null){
FlashMessage("Doof");
return $response->redirect("/error");
}
$user = getuserById($userId);
//ganz viel anderer code
if($user == null){
FlashMessage("Doof");
return $response->redirect("/error");
}
//ganz viel anderer code
if($user->getWasauchimmer() != 1){
FlashMessage("Doof");
return $response->redirect("/error");
}
return $response;
}
}
|
|
Mir geht es um dieses mehrfache return FlashMessage. Wie macht man das besser das man nicht mehrfach diese FlashMessage niederschreiben muss. Spontan wäre ein try/catch mit einer exception aber dann hätte ich in dem try block sehr viel code.
Wie regelt ihr das?
/e: update pseudocode
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von X-Tender am 30.08.2021 12:07]
|
|
|
|
|
|
Ich würde einfach kündigen, weil ich nicht mit PHP arbeiten will.
|
|
|
|
|
|
|
...
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von krak0s am 30.08.2021 12:03]
|
|
|
|
|
|
Ne Controller-Funktion "login", die wahlweise "true" oder "FlashMessage(...)" zurückgibt... k.A. wie bei PHP das mit den Booleanskis funktioniert, aber wahrscheinlich wäre dann ein if(uc.login(...)) falsch, oder?
Ich würde spontan sagen: "login" gibt nix / User-Objekt zurück, wenn erfolgreich, und sonst knallt es wird ne Exception geworfen. Und die kann dann irgendein Stück Code, was näher an der UI dran ist, zu einer Flash-Message machen.
|
|
|
|
|
|
|
Ich würde allerdings auch pro Fehler eine Exception mit passenden Fehlercode + Fehlermeldung werfen, so das du dann an übergeordneter Stelle per try/catch darauf ordentlich reagieren kannst.
Und wenn es im catch dann nur der Aufruf "FlashMessage(...)" ist, aber dort kannst du wenigstens dann deine eindeutigen Fehlercodes und Fehlermeldung aus der Exception holen.
e: mit deinem abgeänderten Code:
|
Code: |
try {
$userController = new UserController();
$user = $userController->login($userId);
} catch (Exception $e) {
FlashMessage($e->message, $e->code);
$response->redirect("/error");
}
|
|
|
[Dieser Beitrag wurde 2 mal editiert; zum letzten Mal von Underboss am 30.08.2021 12:58]
|
|
|
|
|
|
Es gibt nur ein return Statement am Ende der Methode!
Also am Anfang ein Bool mit false initialisieren, nur bei erfolgreichem login auf true setzen und am Ende noch mal vergleichen.
Oder halt (wenn die nachfolgenden Aktionen von der UserId abhängig sind) eine Exception werfen.
| Zitat von SkunkyVillage
Ich würde einfach kündigen, weil ich nicht mit PHP arbeiten will.
| |
PHP 7 (und jetzt 8) ist echt okay.
Zumindest, wenn man seine vernünftige IDE benutzt.
|
[Dieser Beitrag wurde 2 mal editiert; zum letzten Mal von [KDO2412]Mr.Jones am 30.08.2021 12:14]
|
|
|
|
|
|
Ich habe den pseudocode aktualisiert.
Es gibt keine wirklich logische Übergeordnete ebene die eine exception gut abfangen könnte.
Zeugs kommt in controller rein, view kommt raus (oder in dem fall ein redirect wenn fehler).
|
|
|
|
|
|
|
Nachdem ich am Wochenende versucht habe, ein Projekt zu TypeScript zu migrieren, habe ich das heute erst mal wieder aufgegeben. Ich hab zu exzessiv von Dynamisierung Gebrauch gemacht und hatte das Gefühl, zu viel Refactoring machen zu müssen und dafür zu wenig zurückzubekommen.
Was mich u.a. richtig gestört hat, war, dass es in TS keine anständige (kurze) Syntax für optionale Parameter gibt (zumindest nichts Vergleichbares zu { optionalParam = 123 } = {}). Da mit Interfaces rumzurödeln fand ich irgendwie redundant und unnötig.
Mal gucken. Ein andermal vielleicht.
/ Und ganz banal: Dynamisieren macht mir auch einfach Spaß.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Ameisenfutter am 30.08.2021 12:10]
|
|
|
|
|
|
| Zitat von X-Tender
Ich habe eine generelle frage wie ihr folgende Situationen / Patterns umsetzt/handahbt.
Etwas Pseudocode:
|
Code: |
MeinController.php
class UserController{
public function login(Response $respnse, $userId){
if($userId == null){
FlashMessage("Doof");
return $response->redirect("/error");
}
$user = getuserById($userId);
//ganz viel anderer code
if($user == null){
FlashMessage("Doof");
return $response->redirect("/error");
}
//ganz viel anderer code
if($user->getWasauchimmer() != 1){
FlashMessage("Doof");
return $response->redirect("/error");
}
return $response;
}
}
|
|
Mir geht es um dieses mehrfache return FlashMessage. Wie macht man das besser das man nicht mehrfach diese FlashMessage niederschreiben muss. Spontan wäre ein try/catch mit einer exception aber dann hätte ich in dem try block sehr viel code.
Wie regelt ihr das?
/e: update pseudocode
| |
Wenn die login Methode dir gefühlt zu viel macht, lager die Prüfungen in eine eigene Klasse aus.
UserLoginValidator->validate()
if(UserLoginValidator->hasErrors())
{
FlashMessage(UserLoginValidator->getFlashMessage);
return UserLoginValidator->getResponse();
}
Statt der statischen MEthodenaufrufe kannst das natürlich auch als Instanzvariable machen.
Ist nur leichter so zu lesen.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von DeineOmi am 30.08.2021 12:14]
|
|
|
|
|
|
| Zitat von Ameisenfutter
Nachdem ich am Wochenende versucht habe, ein Projekt zu TypeScript zu migrieren, habe ich das heute erst mal wieder aufgegeben. Ich hab zu exzessiv von Dynamisierung Gebrauch gemacht und hatte das Gefühl, zu viel Refactoring machen zu müssen und dafür zu wenig zurückzubekommen.
Was mich u.a. richtig gestört hat, war, dass es in TS keine anständige (kurze) Syntax für optionale Parameter gibt (zumindest nichts Vergleichbares zu { optionalParam = 123 } = {}). Da mit Interfaces rumzurödeln fand ich irgendwie redundant und unnötig.
Mal gucken. Ein andermal vielleicht.
/ Und ganz banal: Dynamisieren macht mir auch einfach Spaß.
| |
Entweder willst du Typisierung oder nicht.
|
|
|
|
|
|
|
Es gibt tatsächlich einige Sachen, die mich verwirren/stören:
1. "ganz viel anderer Code" zwischen Dingen, von denen ich erst mal vermuten würde, dass sie direkt nacheinander kämen:
|
PHP: |
<?php
if ($userId == null) {
return FlashMessage("Doof");
}
$user = getuserById($userId);
if ($user == null) {
return FlashMessage("Doof");
}
if (!$user->einloggbar()) {
return FlashMessage("Doof");
}
// anderes Zeug, das eine Session herstellt
?>
|
|
2. Es wird entweder "true", oder eine wie auch immer geartete "FlashMessage" zurückgegeben. Ich würde was ganz anderes erwarten. Z.B. eine Session (bzw. "null", wenn kein Login möglich), ein User-Objekt, oder halt "true" und "false".
3. Wie mit einem nicht-erfolgreichen Login umgegangen wird, gehört nicht in die Login-Methode.
4. Ich finde auch die Parameter komisch. Wo kommt die $userId her? Ich würde von einer Login-Methode erwarten, dass sie einen Nutzer-Namen und ein Passwort erwartet.
Um dir das Leben im ersten Schritt zu erleichtern, würde ich mein Hauptaugenmerk auf die Punkte 2 (return true/false) und 3 legen.
***
| Zitat von [KDO2412]Mr.Jones
Es gibt nur ein return Statement am Ende der Methode!
Also am Anfang ein Bool mit false initialisieren, nur bei erfolgreichem login auf true setzen und am Ende noch mal vergleichen.
| |
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von cms am 30.08.2021 12:18]
|
|
|
|
|
|
| Zitat von Oli
| Zitat von Ameisenfutter
Nachdem ich am Wochenende versucht habe, ein Projekt zu TypeScript zu migrieren, habe ich das heute erst mal wieder aufgegeben. Ich hab zu exzessiv von Dynamisierung Gebrauch gemacht und hatte das Gefühl, zu viel Refactoring machen zu müssen und dafür zu wenig zurückzubekommen.
Was mich u.a. richtig gestört hat, war, dass es in TS keine anständige (kurze) Syntax für optionale Parameter gibt (zumindest nichts Vergleichbares zu { optionalParam = 123 } = {}). Da mit Interfaces rumzurödeln fand ich irgendwie redundant und unnötig.
Mal gucken. Ein andermal vielleicht.
/ Und ganz banal: Dynamisieren macht mir auch einfach Spaß.
| |
Entweder willst du Typisierung oder nicht.
| |
Ember selbst ist halt auch ein JS-Framework. Es fing eigentlich schon damit an, dass ich Schwierigkeiten hatte, die ganzen Framework-Objekte zu typisieren. Da war dann erstmal ganz viel unknown.
Eine andere Sache war folgende: Ich habe im UI Daten, von denen es sowohl Repräsentationen im Model gibt als auch außerhalb des Models (das sind dann 2 verschiedene Klassen, ein Model und ne native Klasse). Die nativen Objekte werden anhand der Models erzeugt. Damit ich die Struktur nicht an zwei Stellen pflegen muss, gehe ich bei der Erzeugung halt schön die Keys des Models durch und kopiere die Properties an das erzeugte Objekt. Sowas mit Typisierung unter einen Hut zu kriegen fand ich schwierig. Ich dachte, ich könnte das dann über ein gemeinsames Interface für Model und native Klasse abdecken, aber da war ich dann nicht sattelfest genug, weil Ember die Attributdefinitionen im Model über @attr()-Decorators löst. Ich kapier einfach zu wenig, was das bedeutet und ob das ein Problem darstellt. Ist in einem TS-basierten Framework sicher einfacher für jemanden, der nicht so sattelfest ist.
Ich denke, ich werde das Thema irgendwann nochmal an einem frischen Projekt angehen, wo ich mich von Anfang an auf Typisierung committen kann. Und da dann nochmal ergebnisoffen ermitteln, ob das was für mich ist, oder ob mir da dann auch noch was fehlt.
/ Vielleicht noch ein Pro, das mir schon direkt aufgefallen ist: Bei einem Import von der IDE halt auch wirklich gesagt zu bekommen, was das Objekt für Methoden hat und wie die Schnittstellen aussehen, ohne die Datei öffnen zu müssen, ist natürlich schon geil. Den Luxus kennt man gar nicht mehr, wenn man fast nur noch JavaScript macht.
|
[Dieser Beitrag wurde 3 mal editiert; zum letzten Mal von Ameisenfutter am 30.08.2021 12:26]
|
|
|
|
|
|
| Zitat von cms
...
***
| Zitat von [KDO2412]Mr.Jones
Es gibt nur ein return Statement am Ende der Methode!
Also am Anfang ein Bool mit false initialisieren, nur bei erfolgreichem login auf true setzen und am Ende noch mal vergleichen.
| |
| |
Ich finde es furchtbar, wenn Funktionen mittendrin an mehreren Stellen ein "return" ausführen. Mag praktisch sein, aber macht es nicht leichter lesbar / verständlicher, vor allem wenn da noch "viel Code" zwischen ist.
Und wenn am Ende $loginSuccessful true ist, dann kannst Du ja ein Userobjekt zurückgeben oder was auch immer...
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von [KDO2412]Mr.Jones am 30.08.2021 12:44]
|
|
|
|
|
|
Du lässt lieber Code ausführen, der nicht gebraucht wird?
|
|
|
|
|
|
|
Daher ja der Edit mit Exception schmeißen... Ich bin krank, und hab Kopfweh.
|
|
|
|
|
|
|
Ich habe meinen Psudocode ja angepasst.
im grunde ist es egal was hinten rauskommt. Ich glaube es wäre besser wenn ichden code in einzelne funktionen unterteilen würde und am ende sowas hier machen
|
Code: |
try{
$user = $this->machDas($userId);
$this->dannDas($user);
[..]
$this->drölfZeugsWasEgal();
}catch($e){
FlashMessage ("DOOF");
return $response->redirect("/error");
}
return $response;
|
|
Bei einigen Antworte muss ich spontan an das hier denken...
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von X-Tender am 30.08.2021 13:01]
|
|
|
|
|
|
Woher kommt (heute) eigtl der PHP-Hate? Klar, Syntax ist immer noch nicht 100% C-like, aber das macht doch Laravel wieder wett.
|
|
|
|
|
|
|
Ok, wie ist es lesbarer?
|
PHP: |
<?php
$loginSuccessful = false;
if ($userId) {
user = doStuff();
$loginSuccessful = true;
}
if ($loginSuccessful && $user) {
if (!$user->einloggbar()) {
$loginSuccessful = false;
}
} else {
$loginSuccessful = false;
}
if ($loginSuccessful) {
return true;
} else {
return FlashMessage("WTF mache ich hier???");
}
?>
|
|
oder
|
PHP: |
<?php
$loginSuccessful = true;
if ($loginSuccessful && $userId) {
$user = getUser($Id);
} else {
$loginSuccessful = false;
}
if ($loginSuccessful && $user) {
$canUserBeLoggedIn = true;
} else {
$loginSuccessful = false;
}
if ($loginSuccessful && $canUserBeLoggedIn) {
doStuff();
} else {
$loginSuccessful = false;
}
return $loginSuccessful;
?>
|
|
oder
|
PHP: |
<?php
$loginSuccessful = false;
if ($userId) {
$user = getUser($userId);
if ($user) {
if ($user->istEinloggbar()) {
if (doStuff()) {
$loginSuccessful = true;
}
}
}
return $loginSuccessful;
?>
|
|
Kurz: Dass Funktionen nur ein single Return haben dürfen ist eine Idee, die zeitgleich mit der Erkenntnis gekommen ist, dass Funktionen nur einen Single Point of Entry haben dürfen. Letzteres ist super, ersteres ist etwas, das seit 30 Jahren tot sein sollte, sich aber leider hält und zu mehr Kopfzerbrechen führt und fehleranfälliger ist, als mehrere Return-Statements.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von cms am 30.08.2021 13:03]
|
|
|
|
|
|
Story of my life.
|
|
|
|
|
|
Thema: Software-Entwicklung 0 ( new SammelThread() ) |