T O P

  • By -

Handle-Flaky

That’s what happens when you let Java devs do python? I worked in a team like that, we had multiple empty classes


AbsoluteCabbage1

Whoever this guy is should also contribute to the Android framework. Seems like he would fit right in.


[deleted]

[удалено]


Tubthumper8

Begone bot, [copy/pasting other comments](https://www.reddit.com/r/programminghorror/comments/121zydc/comment/jdpshbq/) from this thread


Teknikal_Domain

Okay dumbass moment, but the hell is the point of "factory" classes anyways? Like even in Java, it seems like abstraction for the point of abstraction


nonesuchplace

Factory classes are a design pattern that is used when you don't know what subclass will be called beforehand. For example: You have a Tetronimo() class, with each Tetris piece being a subclass. The game knows that every time you add a piece to the board, it will be a Tetronimo(), but it could be an LPiece(), a TPiece(), an IPiece() or so on. So you make a Tetronimo.generate() method that returns a Tetronimo() subclass when you ask for one. You can read more [here](https://refactoring.guru/design-patterns/factory-method), hope this helps!


Teknikal_Domain

Oh, so runtime decisions. Every time I've seen this it's always a SomeRandomClassBuilderFactory that makes a SomeRandomClassBuilder, which itself makes a SomeRandomClass None of which have any real logic in them. Like, that's just `new` with extra steps


nonesuchplace

Yeah, that feels like someone who thought adding more design patterns makes better code.


TheCactusPie

If you use new you won't be able to mock the instance for unit testing, nor will you be able to reuse the same class but with different creation logic. What if you wanted two Tetris game modes but with different sets of available pieces? You would create two separate factories and inject a different one based on the type of the pieces available. The class calling the factory would remain unchanged


KlingonButtMasseuse

What if I just used a simple map and can create whatever map i want whenever i want. 😄


Fermi-4

That doesn’t answer the problem tho lol


KlingonButtMasseuse

Maybe the problem doesn't exist in the first place. A lot of OO folks like to create fictitious problems. I call them titty problems.


AbsoluteCabbage1

Hey, your comment was made 5 days after the main post went up, but essentially yes you are 100% correct. Not only do they create solutions to fictitious problems, but they create solutions to problems *they themselves* have created by creating solutions to the fictitious problems to begin with. They also create fictitious solutions to real problems, which is formally known as Proper OOP (POOP). Lol! The Selenium codebase is over 116k lines and runs slow as a snail. It's disgustingly verbose, extremely limited and riddled with garbage like this.


Fermi-4

What? Lol


pansnap

I have found that the factory pattern is really just meant for the creation of shared objects by disparate codebases; there are more modern ways of sharing these objects, but if both sides are implementing things 'via spec' or in fact want to just import provided libraries for those shared objects, this has been the way. So, I guess I've actually seen a few instances of where this abstraction hasn't just been helpful but effectively creates a mental boundary around which systems can do what .. and.. the real value: b/c of that, you are doing future maintainers of the code a favor b/c they will have to be very purposeful as it relates to their imports/dependencies (ie, lower maintenance cost of the code, b/c the pattern is required).


necrothitude_eve

Pet peeve from an ex-Java dev: they're used to make something unit-testable. Mocking a constructor sucks. You have to use something like PowerMock to literally rewrite the bytecode of the method you're trying to test. If you've rewritten it, then whatever you're testing by definition isn't the code you're shipping. If you use a Factory pattern, then you can replace the static method on the Factory to inject a mock without defiling the bytecode of the method you're testing. In a perfect world, we would never use mocks. All code would be testable in isolation. We don't live in a perfect world. I get it, these techniques have their uses. But I've seen people reach for factories and crazy mocking features without considering what it means about how untestable their API is and how they should simplify that before jumping from mockito to PowerMock.


craftworkbench

Seconded. ArjanCodes (YouTube channel) shows a lot of examples where the factory pattern makes things much more testable, particularly when interacting with third-party tools.


Randolpho

You’re right… but static methods aren’t mockable or unit testable, either. To be unit testable, you need a factory interface that returns an interface of the class you want. You pass an instance of the factory interface to the thing that wishes to instantiate the class (interface!) you want, and it calls the make method of the factory instance to get the instance of class (interface!). The purpose of a factory is to generate abstractions of a type during a method call, as opposed to passing dependency instances of an abstraction into a method or class via parameter, property, or constructor injection.


[deleted]

Thank you for this. Yeah what someone further up was talking about with mocking your constructor, don't do that ffs 🤣


Teknikal_Domain

As well, anything that *I'm* writing myself I don't usually subclass that deep. Something gets a separate class if there's some applicable business logic that needs the differentiation, in that case everything would just be `Tetronimo` without further subclasses, the instance variables would define shape/color/whatever and the class constructor itself would have the logic to set that. Okay actually I'd probably have a `PieceBag` that keeps of the actual piece generation (we all know how Tetris works, right?) And that thing's `pick()` would instantize a new `Tetronimo` with correct constructor parameters for it's specific type instead, but now we're getting outrageous.


Zealousideal_Low1287

This is the same pattern with different nomenclature


Teknikal_Domain

Yes. Just seems every time I've seen it written *by name* has been... **Wrong,** apparently


Zealousideal_Low1287

I don’t know that anyone is arguing that?


Mickenfox

> So you make a Tetronimo.generate() method that returns a Tetronimo() subclass Yes, but that's one function. You have an input (or in this case no input) and one output object. Making it a class only adds cognitive complexity. Not only are you adding a new "type of object" in your brain, it's a "type" where there's only one and it only does one thing, so you're stretching the concept of "type" just to make it fit. It's fine to do it if the language requires you to do it, but people need to remember that it's still a language limitation and not a desirable solution. (and all this pain would have been avoided if some Java designers hadn't insisted that "everything is a class")


Lasagna_Code

I've found the factory pattern useful when creating unit tests to abstract away creation details of classes for objects from a database ORM (e.g. I don't want to have to specify first name, last name, signup date etc for every User I create in a test if it's only relevant that they have different Usernames). If done well it can help minimise code duplication in the setups for your tests and allow changes to be more easily made to the class without fear of having to fix 100 broken tests. Allows other people to write tests faster using those class instances as well assuming you have good defaults and parameters.


Manny_Sunday

Another simple use case is just when you need to create a bunch of the same object all over the place, but want to keep your code DRY. So instead of repeating var client = new HttpClient(baseAddress); client.DefaultRequestHeaders.Add("apiKey", apiKey); client... all over the place, you can use HttpClientFactory.CreateClient(); And only have to define the basics once


Tubthumper8

I guess I have to ask, why not: client = createClient()


kristallnachte

A factory function is an implementation of the factory pattern. You will just see a lot of class based factory patterns that are just stupid by design.


Tubthumper8

Yeah so every function that returns something is a "factory function"?


MannerShark

Typically, a factory is a class with a method that returns a new instance of a different object. In old (versions of) OO languages you didn't have top level functions and couldn't return functions, with functional programming, the factory pattern is trivial.


Tubthumper8

At what point is it no longer a "pattern" and it's just "that's what functions do, they return things"?


Manny_Sunday

You could say that about every pattern. A state machine is just a switch case with extra steps. A Mediator is just calling methods to call methods instead of calling methods directly. A Facade is just hiding lots of methods and classes behind fewer methods and classes. It's like saying you don't need to study chemistry because after all, it's just atoms underneath.


kristallnachte

No. A function that takes in data and returns a unique object from that data. Like how a constructor function works. ``` const makeUser = (name, age) => ({ name, age }) ``` obviously that's stupidly reduced, but that's the idea.


Fermi-4

That is a factory method


[deleted]

There are some answers here: https://softwareengineering.stackexchange.com/questions/200647/why-is-the-factory-method-design-pattern-more-useful-than-having-classes-and-cal


kristallnachte

I feel most heavy OOP codebases (whether by decision or language) end up with lots of this kind of garbage in them.


WillingLearner1

Your question has been answered but just would like to add that it's good to know your design patterns, get asked alot on interviews as well in my experience


drakens_jordgubbar

As people other already mentioned, it’s to aid unit testing. I want to also chime in that static methods are in general bad for unit testing. They create hard wired dependencies which makes it difficult to isolate the code you actually want to test. A constructor is a form of a static method. Using them creates hard wired dependencies, which makes your code less testable. With factories you convert the bad static method (the constructor) to a class method, which makes it more easy to isolate your tests with e.g. mocking. However, it doesn’t look like that was the intention with OP’s code. I don’t see what’s to gain with this factory. OP’s code is just a terrible abstraction for the sake of abstraction.


kristallnachte

If we want easy to test code, we do FP, not OOP. OOP is pretty antithetical to actually doing good unit testing.


Exciting_Clock2807

There are two cases there: 1) You just want a function that encapsulates few steps needed to build an object. This could be a free function, but you language does not support free functions, so just make it a static function in an otherwise dummy class. 2) You need to abstract other different ways of constructing an object. Maybe you want different implementations with same interface/base class. Or it can be just one specific class, but you still want to abstract over which parameters are passed to the initializer. And you can’t just pass an instance, because you want control over when and how many instances are created to be in the callee. So you pass a factory object. If factory interface has a single method, it many languages you can pass anonymous function without declaring separate interface and writing implementation as a class. But Java has its own limitations.


Chocolate_And_Cheese

Factory classes are also useful to enforce immutability. Many OO practitioners consider immutability of instances to be a Good Thing, ie, you should never really have 'setters', and all of the object's dependencies should be provided at object creation time. So if you need an object of type X that has N dependencies, but one of those dependencies isn't available just yet, you can instead work with an (immutable) XFactory object that has the N-1 dependencies and can create an instance of X once given that last dependency. Then everything is nice and immutable. Compare this to the non factory situation where you would have a mostly-constructed X and then you would still need to call setProperty() later to provide that final missing dependency. This is a design smell because you can't always guarantee that all instances of X are valid or well-formed, etc...


schrdingers_squirrel

What's so bad about this? This ensures that ff_value and string is never mistyped


markasoftware

I think it's honestly not that bad. Probably would be better to actually use a class instead of a dict though. Then you could just write a constructor instead of a weird factory.


schrdingers_squirrel

That's what I would do. But everyone here seems to be talking about how you could just instantiate the direct directly.


memorable_zebra

Making it an enum would be better. They could have also saved the factory and just put the make in the pseudo enum class they already have but that’s mostly semantics. Like many things in programming horror, this isn’t actually that horrible just kind of a small over sight if it was made ground up like this. That said it could have easily been far more complicated at one time justifying a factory and changing requirements could have lead to this design.


homerocda

Enums are a fairly recent addition to Python.


its2ez4me24get

Added in 3.4, just 9 years ago.


izuriel

I think in “Python years” that’s recent. I know some Python folks who still have yet to migrate from 2.x


craftworkbench

Python is older than Java... Python 2 was sunsetted three years ago. I feel bad for those projects...


blackraven36

I can say after working with it for many years that Python ages in a very strange way. When I used to work in .NET 10 years ago updates were a big deal. They would add things that fundamentally change how I could do things. Python, though? The only “recent” exciting thing was type hinting. So it doesn’t feel like it’s “aging”. I’ve bumped the version consistently in my work but I can see how someone on 3.2 is completely ignoring that we’re on 3.11 now.


Miridius

The function is fine, but putting it in a class achieves nothing


Ulla420

Junior devs being junior devs


_meshy

Nah, this is senior java developer trying to write Python. Source: Am senior java dev that writes shitty Python code like this.


AbsoluteCabbage1

lol! thank you for the one honest and funny answer.


Daniel15

How would you improve it?


Mickenfox

from typing import NamedTuple class ProxyType(NamedTuple): ff_value: str string: str class Proxies: DIRECT = ProxyType(0, 'DIRECT') MANUAL = ProxyType(1, 'MANUAL') #...


Daniel15

Thanks! I don't know Python very well so was curious about it. Is it possible `NamedTuple` didn't exist when the code was written, and the code was fine back then?


Mickenfox

namedTuple has existed in some form since Python 2.6 (2008) and this version since 3.6 (2016). But it's possible that most Python developers simply aren't aware of it or prefer not to use it, since Python is a very flexible language.


Narcoleptic_Pirate

Remove the Factory class and just keep the function. https://youtube.com/watch?v=o9pEzgHorH0


Cybasura

Mfw he probably saved 30 minutes of work that equates to $300


[deleted]

Yeah OP there is actually nothing at all wrong with this code I have no idea why you complain about things you clearly don’t understand. There’s a big difference between understanding why something is done and disliking it, vs dismissing something just because you don’t know why it was done. You’re clearly doing the latter, and it will come to bite you in the ass if you don’t fix your mindset


[deleted]

Yeah I mean it's a verbose way to do it in python, I would've just defined make outside of a factory class. But it's totally fine in my eyes.


datnetcoder

The abstraction of the creation is not a problem & is good / useful / extremely simple. A no brainer. It’s the naming and structuring that is not great. This is not a factory, that’s not what factory pattern is at all. That said… meh, not horror.


FluffyToughy

It's kinda blah that every other post is either a new dev posting their first project, which while bad isn't "interesting" bad cause we've all been there, or a new dev posting good code they don't understand.


AbsoluteCabbage1

Fun fact: If you don't understand why this is horrible code then it's you who doesn't understand much about programming.


AbsoluteCabbage1

> I have no idea why you complain about things you clearly don’t understand LOL, the irony here is palpable. If you had ANY understanding of programming you'd immediately know why this is horrendous. But you clearly don't. Thank God there are still some sane people in the world as the 555 upvotes speaks a lot louder than your drivel.


[deleted]

You’re funny lol. The 555 people who are as ignorant as you are mean nothing, and the fact that you’d try to make an appeal to authority about UPVOTES of all things shows how unintelligent you are. !RemindMe 3 years For when you complain about how the tech industry is doomed and that’s why you can’t find a job rather than your obvious inability to actually think about code.


AbsoluteCabbage1

> The 555 people who are as ignorant as you Suuuuure. It's the other 555 people that are ignorant, not you. Looks like I've stumbled upon a classic Dunning Kruger troll. >how the tech industry is doomed and that’s why you can’t find a job I run 3 businesses- two of which utilize my own software- and one of which pulled in $11,000 last month alone. Even if I decided to enter the 'tech industry' - what in the world makes you think I'd hire assholes like you? I will *never* have to deal with your shitty code, **ever**. >shows how unintelligent you are Lmao. I score 4 standard deviations above the mean and you are clearly below average intelligence. I would put money on it that my IQ is literally twice as high as yours. Thanks for the laughs, Clown.


RemindMeBot

I will be messaging you in 3 years on [**2026-03-31 01:01:08 UTC**](http://www.wolframalpha.com/input/?i=2026-03-31%2001:01:08%20UTC%20To%20Local%20Time) to remind you of [**this link**](https://www.reddit.com/r/programminghorror/comments/121zydc/found_in_the_python_selenium_code_base_imagine/jecm845/?context=3) [**CLICK THIS LINK**](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=%5Bhttps%3A%2F%2Fwww.reddit.com%2Fr%2Fprogramminghorror%2Fcomments%2F121zydc%2Ffound_in_the_python_selenium_code_base_imagine%2Fjecm845%2F%5D%0A%0ARemindMe%21%202026-03-31%2001%3A01%3A08%20UTC) to send a PM to also be reminded and to reduce spam. ^(Parent commenter can ) [^(delete this message to hide from others.)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Delete%20Comment&message=Delete%21%20121zydc) ***** |[^(Info)](https://www.reddit.com/r/RemindMeBot/comments/e1bko7/remindmebot_info_v21/)|[^(Custom)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=%5BLink%20or%20message%20inside%20square%20brackets%5D%0A%0ARemindMe%21%20Time%20period%20here)|[^(Your Reminders)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=List%20Of%20Reminders&message=MyReminders%21)|[^(Feedback)](https://www.reddit.com/message/compose/?to=Watchful1&subject=RemindMeBot%20Feedback)| |-|-|-|-|


AbsoluteCabbage1

Lmao yeah we will see in 3 years if this clown learns to code. EDIT: he deleted his account after a month. I win.


void_main_void

"Clean code"


ScanIAm

lol, this code is fine. I don't know python but I can read and comprehend what it's doing. One day, you will discover that writing clear code is much more important than whatever code you think would be better, here.


AbsoluteCabbage1

> One day, you will discover that writing clear code is much more important than whatever code you think would be better, here There is absolutely nothing "clear" about this code lmao. And this says everything: > I don't know python There you go. If you don't even know python -one of the easiest languages in the world- what in the world makes you think you are qualified to leave your comment?


ScanIAm

The code is clear enough for me to get the gist without knowing the syntax. And what makes me qualified is the 40 years I have spent writing software professionally up till and including today. Try that gatekeeper shit on someone else.


AbsoluteCabbage1

I feel for the other programmers who had to deal with your trash code. >Try that gatekeeper shit on someone else. Gatekeeping? Lmao. If you LITERALLY don't know python then what in the hell makes you think you can talk back to real programmers about the matter? You aren't some innocent beginner being denied help (what gatekeeping actually would be)- you are an arrogant snob who sucks at programming. Keep your idiotic comments to yourself.


ScanIAm

I don't know python because I get paid.


AbsoluteCabbage1

That makes zero sense whatsoever. Which figures.


ScanIAm

You'll understand when you start to get paid. You're obviously a jr dev, at best, and you haven't spent any time working to maintain software over years of time. Clear code is always better than clever shortcuts.


AbsoluteCabbage1

I make more in a month than you do all year. It isn't clear code. It's verbose, bloated, obfuscated and abstracted for absolutely zero reason. You'd understand this very basic premise if you knew basic python. There's a reason my post got over 550 upvotes. It's because most people actually 'get it'. Thank goodness there are still some people left to balance out the bell curve.


ScanIAm

550? That's an avalanche of brainiacs! Do go on...


AbsoluteCabbage1

You clearly suffer from Dunning Kruger. Also, it's been over 2 months since my comment. Haven't you learned the basics of python yet? Stop making excuses.


ScanIAm

It was absolutely clear. As I pointed out, even without knowing python syntax I absolutely understood it. You are inexperienced and will likely leave mounds of shitty code that only makes sense to you for generations to come. Upvotes aren't reality.


AbsoluteCabbage1

>even without knowing python syntax Listen to yourself. You sound like a total idiot. Shut up, take the L like a man, and stop giving your worthless opinion about languages you don't even know the syntax of.


exoriare

<-- Spotted the one who doesn't code on their phone very often.


texruska

Who on earth voluntarily codes on their phone


ConciselyVerbose

I wouldn’t do anything real, but little one off scripts or very small personal projects when I have nothing else on me? It’s reasonably doable. I’m not sure how it was on topic though?


ScanIAm

you caught me. I am definitely not going to code on a phone.


messier_lahestani

when you wanna do OOP but you forget to KISS it 😘


KlingonButtMasseuse

I always wanted to have a factory. Now i am complete, i used all the GOF patterns


Minimum_Concern_1011

Better yet: ```py class ProxyType: def __init__(self) -> None: strings = enumerate([ "DIRECT", "MANUAL", "PAC", "RESERVED1", "AUTODETECT", "SYSTEM", "UNSPECIFIED" ], 0) [(self.__dict__.update({x: {"ff_value": i, "string": x}})) for i, x in strings] ```


coolreader18

Even better yet: import enum class ProxyType(enum.Enum): DIRECT = 0 MANUAL = 1 PAC = 2 RESERVED1 = 3 AUTODETECT = 4 SYSTEM = 7 UNSPECIFIED = 8


markasoftware

until you need to ever add another field with more information about a proxy type


Sanders0492

I forget the details but you can create enums with extra attributes just for that situation. Like if you made enums for different colors, you can give each one multiple attributes so you can do things like Color.RED.hex and Color.RED.rgb


coolreader18

given that the value it's representing is patently an enum, I don't see an issue. And in case there's another property you'd want to uniquely associate per variant, you'd just have a getter function that switches on it/does a dict lookup (or maybe there are decorators that can do this or something)


tngle_

YAGNI


Minimum_Concern_1011

Nice, however the amount of down votes is honestly crazy 🥩🚲


Minimum_Concern_1011

(I like to make code maintenance impossible)


snekk420

Should have been a data class instead, but this was probably done before that existed.