Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
yes

Adbot
ADBOT LOVES YOU

Zaxxon
Feb 14, 2004

Wir Tanzen Mekanik

TheresaJayne posted:

Dependency Injection - One should “Depend upon Abstractions. Do not depend upon concretions"

D is the "dependency inversion principle", and in practice it means "program to interfaces." Dependency Injection is a thing you can do effectively if your code follows the DIP.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



evensevenone posted:

https://www.airpair.com/python/posts/python-tips-and-traps#great-exceptations

Evolving horror. This was posted on hackernews today. Originally the suggested snippet was:
code:
try:
    # get API data
    data = db.find(id='foo') # may raise exception
except:
    # log the failure and bail out
    log.warn("Could not retrieve FOO")
    return

# manipulate the data
db.add(data)

Multiple people commented that catching all exceptions is usually a bad idea, so he changed it to
code:
except Exception:
Normally, who the gently caress would care except:

Could be trolling? I thought it was funny, anyway.

raminasi
Jan 25, 2005

a last drink with no ice
C# code:
pt1 = pt1 + -up * moveDown;
pt2 = pt2 - up * moveDown;
Wh...:raise:

TheresaJayne
Jul 1, 2011

Zaxxon posted:

D is the "dependency inversion principle", and in practice it means "program to interfaces." Dependency Injection is a thing you can do effectively if your code follows the DIP.

Basically DI is supposed to mean that you never create Concrete instances inside a class...

so
code:
public void startGame() {
       GameEngine gameEngine = new GameEngine();
       gameEngine.start();
 }
is wrong

code:
public void startGame(GameEngine gameEngine) {
    gameEngine.start();
}
is right as you inject the GameEngine into the system - This is a basic example and there are probably hundreds of goons itching to tell me i am wrong but, thats how i see it anyway.

toiletbrush
May 17, 2010

NovemberMike posted:

To be fair though, the only one of those that is uncontroversially right is LSP, and at least the O is generally considered a bad idea these days.
Why is O considered bad these days? I've asked it in interviews and everyone can quote that line but very, very few people can actually explain what it means.

TheresaJayne
Jul 1, 2011

toiletbrush posted:

Why is O considered bad these days? I've asked it in interviews and everyone can quote that line but very, very few people can actually explain what it means.

It means that once you have a method interface defined, say

processData(int a, int b, int c, String desc)


you need then to process another string, but you should not edit that method signature so you do not break the other code that may call yours, but you extend it by say
an overloaded method or a slightly different method name.

That is for methods but for classes it means you don't modify existing class but you extend from that class

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

toiletbrush posted:

Why is O considered bad these days? I've asked it in interviews and everyone can quote that line but very, very few people can actually explain what it means.

It's considered bad because generally speaking, classes should by default be closed for extension as well. It's really hard to design a class with a sane API for extending it. If you don't consciously think about it, it's guaranteed to be loving terrible. And when's the last time you wrote a class, with no plans for extending it right now, and actually thought about how it's going to work if someone else comes along and extends it? (And if you do that regularly, you're basically wasting many many hours thinking about that stuff for classes that no-one is ever going to extend).

Actually, inheritance just sucks in general. You either want polymorphism (interfaces!) or code re-use (composition!), some hosed-up bastard child of the two has a whole lot of drawbacks.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
The entire idea of never changing working code and only adding new things has always sounded like pretty much the worst possible idea to me. Yes, propagating changes outward when you make a change sucks, but a code base that's ten times the size it needs to be with only a quarter of it actually used (and no one being sure which quarter) is far worse. You have to do it at module boundaries where it's impossible to modify the things using a class, but even then you should be deprecating as much of the old functionality as possible for the sake of providing a coherent API that doesn't have ten ways to do very similar things.

Space Whale
Nov 6, 2014

TheresaJayne posted:

Basically DI is supposed to mean that you never create Concrete instances inside a class...

so
code:
public void startGame() {
       GameEngine gameEngine = new GameEngine();
       gameEngine.start();
 }
is wrong

code:
public void startGame(GameEngine gameEngine) {
    gameEngine.start();
}
is right as you inject the GameEngine into the system - This is a basic example and there are probably hundreds of goons itching to tell me i am wrong but, thats how i see it anyway.

Use an interface for the type signature in your parameters.

Sedro
Dec 31, 2008

TheresaJayne posted:

Basically DI is supposed to mean that you never create Concrete instances inside a class...

That's basically it. Consider if the game engine had dependencies, and maybe its dependencies have other dependencies, and so on
code:
public void startGame() {
       GameEngine gameEngine = new GameEngine(/* lots of stuff */);
       gameEngine.start();
 }
or if you changed it to a singleton
code:
public void startGame() {
       GameEngine gameEngine = GameEngine.instance();
       gameEngine.start();
 }
With the dependency inverted, you don't care. It's somebody else's problem. And that somebody else can be a dependency injection container which manages those dependencies and lifetimes.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

TheresaJayne posted:

Basically DI is supposed to mean that you never create Concrete instances inside a class...

so
code:
public void startGame() {
       GameEngine gameEngine = new GameEngine();
       gameEngine.start();
 }
is wrong

code:
public void startGame(GameEngine gameEngine) {
    gameEngine.start();
}
is right as you inject the GameEngine into the system - This is a basic example and there are probably hundreds of goons itching to tell me i am wrong but, thats how i see it anyway.

Cool, now when reading your lovely code I have to track down another level of indirection since you chose to have a method on a random object that literally calls a method on an object.

FlapYoJacks
Feb 12, 2009
Am I the horror? I inherited a mess of a website code wise, and I am rebuilding it into a object based website. The way I am organizing it is thusly:

Pages will live in a pages folder (or something to that effect, not sure yet) but I also have a objects folder.

In the objects folder are self contained objects such as the footer, header, products bar, etc etc.
Each object has it's own css, img, and font folder as well. This way the people who are going to take over who aren't super technical on the code side can modify each object easily and quickly.

I know I am repeating files sometimes, such as right now the same font is being used in a lot of the objects, but I want it to be subject to change in the future.

Right now the current website has everything dumped into a single css, fonts, and img folder (hundreds of files in each.)


How do you guys organize your websites?

Space Kablooey
May 6, 2009


Suspicious Dish posted:

Cool, now when reading your lovely code I have to track down another level of indirection since you chose to have a method on a random object that literally calls a method on an object.

You can't be serious. Isn't a part of OO supposed to be exactly that?

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

HardDisk posted:

You can't be serious. Isn't a part of OO supposed to be exactly that?

Uh, no?

The posted code is pointless, but you'd probably have an instance variable that you assign the GameEngine to as well in that method, which would make it less so.

Having SomeRandomObject.StartGame(gameEngine); be identical to gameEngine.start(); would result in some posts in this thread when found.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



It's almost as if example code is sometimes pared down to the point of real-world uselessness to illustrate a single idea. Weird!

M31
Jun 12, 2012
There is this awful pattern, the Visitor pattern, which is exactly functions calling a single method on a parameter.

(from the Wikipedia article)
code:
class Engine implements ICarElement {
    public void accept(ICarElementVisitor visitor) {
        visitor.visit(this);
    }
}

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I've never understood the point of that.

Athas
Aug 6, 2007

fuck that joker

Suspicious Dish posted:

I've never understood the point of that.

It's implementing pattern-matching and generic traversals when you have neither higher-order functions or actual pattern matching.

raminasi
Jan 25, 2005

a last drink with no ice

Suspicious Dish posted:

I've never understood the point of that.

It gives idiots a wrong answer to regurgitate on StackOverflow when someone asks how to kludge multiple dispatch in languages without multiple dispatch.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
How is it multiple dispatch though? Why can't the visitor just call this.visit(engine); instead?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Suspicious Dish posted:

How is it multiple dispatch though? Why can't the visitor just call this.visit(engine); instead?

Overload resolution is statically dispatched in most languages (for good reason).

Brain Candy
May 18, 2006

Sedro posted:

or if you changed it to a singleton

People bringing up DI seem to segue into "and you can use it with singletons!!!" pretty quickly. When did global mutable state become okay?

dwazegek
Feb 11, 2005

WE CAN USE THIS :byodood:

Brain Candy posted:

People bringing up DI seem to segue into "and you can use it with singletons!!!" pretty quickly. When did global mutable state become okay?

It's not uncommon to end up with a bunch of classes that don't have mutable state, so they can be safely turned into singletons.

Still doesn't make it a good idea to actually do so though.

Sedro
Dec 31, 2008

Brain Candy posted:

People bringing up DI seem to segue into "and you can use it with singletons!!!" pretty quickly. When did global mutable state become okay?
Neither DI nor singletons imply that there's mutable state.

Hughlander
May 11, 2005

Brain Candy posted:

People bringing up DI seem to segue into "and you can use it with singletons!!!" pretty quickly. When did global mutable state become okay?

I've had it strongly argued to me that in almost every case all a DI container is anyway is a singleton through indirection. Wether it's by injecting Singletons, or by getting a Factory Singleton. Of course this was also arguing against any sort of DI for a dynamic scripting language like Ruby...

dwazegek
Feb 11, 2005

WE CAN USE THIS :byodood:

Hughlander posted:

I've had it strongly argued to me that in almost every case all a DI container is anyway is a singleton through indirection. Wether it's by injecting Singletons, or by getting a Factory Singleton. Of course this was also arguing against any sort of DI for a dynamic scripting language like Ruby...


I guess you could argue that the DI container itself is a singleton, cause there' generally only one per application. I'm not sure why that would be relevant though.

But why would anyone assume it's injecting singletons?

The only times I've ever used singletons in a DI container is for stuff like (immutable) config classes where there only is 1 instance for the entire application. In every other case (including factories) the injected instances have always been tied to some scope, or have been new instances.

JawnV6
Jul 4, 2004

So hot ...

Brain Candy posted:

When did global mutable state become okay?

I call it RAM

Brain Candy
May 18, 2006

Sedro posted:

Neither DI nor singletons imply that there's mutable state.

Sure, as long as you don't count whatever does the lazy loading. Write your entire program in XML if it makes you happy. (please stop. no. don't. )

But something tells me that's not how you use it

Sedro posted:

code:
public void startGame() {
       GameEngine gameEngine = GameEngine.instance();
       gameEngine.start();
 }

Xenoveritas
May 9, 2010
Dinosaur Gum

Brain Candy posted:

Write your entire program in XML if it makes you happy. (please stop. no. don't. )

I once wrote what was effectively a Lisp interpreter that used XML to build its lists. Sadly I've since lost that code.

1337JiveTurkey
Feb 17, 2005

Brain Candy posted:

People bringing up DI seem to segue into "and you can use it with singletons!!!" pretty quickly. When did global mutable state become okay?

First, singletons aren't necessarily global. Rather they're unique within some scope and that scope may potentially be global. It can also be scoped to a single request, a single window of a desktop application or a single thread running some process in the background. For something like parsed command line parameters or a config file, the state truly is global.

Second making an interface globally visible is different than making the underlying state globally mutable. All the state is still local to the implementation and the interface should be defined in a manner that provides consistent behavior. It doesn't matter if one component marks a region on a window dirty or a dozen, the window implementing the interface needs to handle both cases consistently.

Finally shared state and side effects are necessary for any computations to do anything other than heat up the server room. Writing to a log file is a side effect. A financial transaction's correctness depends on consistently updating the shared global state between independent systems. The fact that side effects (even globally visible ones!!) are necessary to achieve some goal doesn't change the the underlying fact that they are side effects.

Brain Candy
May 18, 2006

1337JiveTurkey posted:

First, singletons aren't necessarily global. Rather they're unique within some scope and that scope may potentially be global. It can also be scoped to a single request, a single window of a desktop application or a single thread running some process in the background. For something like parsed command line parameters or a config file, the state truly is global.

I'm unclear about what bit of state isn't a singleton if I'm even a little bit liberal about what unique means.
But instead of arguing about that, I'd like to talk about those things you get by calling SomeType.instance(). Particularly, the ones that don't give me different thing depending on the calling thread.

1337JiveTurkey posted:

Second making an interface globally visible is different than making the underlying state globally mutable. All the state is still local to the implementation and the interface should be defined in a manner that provides consistent behavior. It doesn't matter if one component marks a region on a window dirty or a dozen, the window implementing the interface needs to handle both cases consistently.

Unfortunately, I frequently work with more than two threads so I'd still really like to have idempotence for things I can get to from anywhere.

quote:

Finally shared state and side effects are necessary for any computations to do anything other than heat up the server room. Writing to a log file is a side effect. A financial transaction's correctness depends on consistently updating the shared global state between independent systems. The fact that side effects (even globally visible ones!!) are necessary to achieve some goal doesn't change the the underlying fact that they are side effects.

:allears:

comedyblissoption
Mar 15, 2006

Brain Candy posted:

People bringing up DI seem to segue into "and you can use it with singletons!!!" pretty quickly. When did global mutable state become okay?
As others have said, you can have injected objects that are singletons in the scope of the DI container which is probably global.

In java-like OOP languages, the unit of modularity is a class. So even if some subset of your code is structured to work with immutable data and no mutable state, if you want modularity and also testability, you are forced to use instantiated classes with injected dependencies in this code. This is also conceptually a 'singleton' class since it makes no sense to have multiple instances. This results in so much boilerplate to the degree that you want to use a framework just to pass in arguments for you. This may suggest that having your basic abstraction be a class is a poor fit for certain styles of coding.

comedyblissoption
Mar 15, 2006

This is the idiomatic, boiler-platish, minimalist way to write modular and testable code in C#. Unfortunately this is unironically the best practice in C#.
code:
public interface ICubeService
{
    double Cube(double x);
}    

public class CubeService : ICubeService
{
    public double Cube(double x) {
        return x * x * x;
    }
}

public interface ISphereVolumeService
{
    double GetVolume(double radius);
}

public class SphereVolumeService : ISphereVolumeService
{
    private readonly ICubeService _cubeService;
    
    public SphereVolumeService(ICubeService cubeService) {
        _cubeService = cubeService;
    }
    
    public double GetVolume(double radius) {
        return 4 / 3 * Math.PI * _cubeService.Cube(radius);
    }
}

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Mutable, shared state is actually really useful in a lot of cases, and it's kind if sad that most programmers get taught platitudes (and proceed to apply them over-generally) instead of learning the reasoning behind them.

Brain Candy
May 18, 2006

Jabor posted:

Mutable, shared state is actually really useful in a lot of cases, and it's kind if sad that most programmers get taught platitudes (and proceed to apply them over-generally) instead of learning the reasoning behind them.

:ironicat:

Yeah, if only people always kept context in mind.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Is this the part where someone funny comes in and says "I wish your posts were mutable????". If not, we're certainly reaching it fast.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

I just wish they weren't shared.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

(So no, nobody funny will get involved.)

Adbot
ADBOT LOVES YOU

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

Suspicious Dish posted:

Is this the part where someone funny comes in and says "I wish your posts were mutable????". If not, we're certainly reaching it fast.

Are strings mutable in PHP?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply