|
Pilsner posted:An interface on every class, just for the sake of, grossly pollutes the codebase and is terrible. It is a hack concept that stems from unittesting frameworks that require you to have an interface on a class in order to be able to mock it. Writing the code properly with as little technical fluff as possible is first priority, making it fit to some test framework or mocking is second priority. I mean, I think (hope?) we can all agree that making an interface for every class in your application is silly. But creating an interface for classes that are going to be dependencies (repositories, services, etc.) is just idiomatic .NET as far as I can tell. Especially in web-land since ASP.NET comes with a DI container out of the box now.
|
# ? Sep 23, 2016 05:58 |
|
|
# ? Jun 4, 2024 05:06 |
|
I don't understand. How could the presence of an interface make things harder? At worst, it just seems like a file hanging around that you can safely ignore.
|
# ? Sep 23, 2016 12:54 |
|
rt4 posted:I don't understand. How could the presence of an interface make things harder? At worst, it just seems like a file hanging around that you can safely ignore. It's extra boiler plate for people with bad IDEs and extra clicks for people with good IDEs. It can encourage dependency injection in places where it's otherwise not needed. (Note: I don't support these views, just seem them as possible arguable answers.)
|
# ? Sep 23, 2016 12:58 |
|
rt4 posted:I don't understand. How could the presence of an interface make things harder? At worst, it just seems like a file hanging around that you can safely ignore. It's more code that you have to write and (more importantly) maintain for very little benefit if you go overboard.
|
# ? Sep 23, 2016 14:59 |
|
How does an interface require maintenance?? If an interface really takes so long to type or requires frequent adjustment down the road, that may be a problem with the software design rather than the practice of programming to interfaces.
|
# ? Sep 23, 2016 15:04 |
|
All code's going to require maintenance sooner or later, and I like to have as little of it as possible when it does. Just a difference in style, I guess.
|
# ? Sep 23, 2016 15:24 |
|
My personal opinion is that since it's so easy to just split a class into interface and impl if you turns out you actually do need an alternate implementation, why would you even bother doing that work up-front? YAGNI 90% of the time.
|
# ? Sep 23, 2016 16:04 |
|
rt4 posted:I don't understand. How could the presence of an interface make things harder? At worst, it just seems like a file hanging around that you can safely ignore. because it's extra baggage. change the class function headers and you have to change the interface function headers
|
# ? Sep 23, 2016 16:12 |
|
These are some seriously bullshit arguments up in here.
|
# ? Sep 23, 2016 19:08 |
|
return0 posted:These are some seriously bullshit arguments up in here. There is no articulable reason for having one-class interfaces. Source: you're unable to articulate any.
|
# ? Sep 24, 2016 00:37 |
|
One-class interfaces are sometimes known as header files
|
# ? Sep 24, 2016 00:38 |
|
"This is not a problem if you have a good software design" doesn't strike me as a great way to argue that something is not a problem.
|
# ? Sep 24, 2016 00:41 |
|
qntm posted:"This is not a problem if you have a good software design" doesn't strike me as a great way to argue that something is not a problem. An interface per class appeals to the lowest common denominator. It's generally better for people to be thinking in terms of interfaces excessively rather than avoiding them preferentially, so if you have an interface per class you cover your bases at a cost of making the code base less navigable and understandable when you use an interface only once. That is, if you can't trust your people to use interfaces smartly, at least get them thinking more about it.
|
# ? Sep 24, 2016 01:41 |
|
baquerd posted:It's generally better for people to be thinking in terms of interfaces excessively rather than avoiding them preferentially This is exactly the point that's up for debate here, seemingly. Repeating it doesn't make it true. baquerd posted:so if you have an interface per class you cover your bases at a cost of making the code base less navigable and understandable when you use an interface only once. That is, if you can't trust your people to use interfaces smartly, at least get them thinking more about it. And this is exactly the behavior that should be avoided. Someone who doesn't know how interfaces work isn't going to look at 'BeanTransformer' and 'BeanTransformerImpl' and say, "You know what, I need a bean transformer too, but I the BeanTransformerImpl doesn't do what I need it to do; I'll just make another impl of BeanTransformer!" In this world where we've established that they don't know how to use interfaces smartly, what they'll do is make another interface, 'AnotherBeanTransformer', and make their lovely impl class 'AnotherBeanTransformerImpl' and further pollute the already burning trash pile of code. Except now you make everyone's job more difficult. You make it more difficult for the person that does know how to use interfaces, because they have to reconcile this extra interface and refactor it after the fact. You make it more difficult for literally every developer on this project to navigate to the specific code they need. You make it more obnoxious to refactor code. And for what? Interfaces have an explicit purpose. Use them for that purpose. It's not like it's hard to extract an interface out of a class after the fact when you actually need it.
|
# ? Sep 24, 2016 16:26 |
|
Sarcophallus posted:Except now you make everyone's job more difficult. You make it more difficult for the person that does know how to use interfaces, because they have to reconcile this extra interface and refactor it after the fact. You make it more difficult for literally every developer on this project to navigate to the specific code they need. You make it more obnoxious to refactor code. And for what? Interfaces have an explicit purpose. Use them for that purpose. It's not like it's hard to extract an interface out of a class after the fact when you actually need it. Yep, just playing devil's advocate.
|
# ? Sep 24, 2016 20:28 |
|
I'd actually consider a decent heuristic "one interface per piece of functionality." Depending on how you interpret the single responsibility principle, and how religiously you adhere to it, this may end up being one interface per distinct class (distinct meaning classes that don't try to give the same functionality in different ways). However, this may end up being 2-3 interfaces for some classes, or even zero if they're just POD classes or something. More to the point, interfaces should be defined by consumers more than producers. There's not much purpose making an interface that requires methods nobody needs. Instead, your classes and functions elsewhere should be the motivating factor creating interfaces. Meaning: if I have some sort of point class that happens to provide the number of elements and a distance function, there's not necessarily purpose making a Distance and Dimensions interface. Instead, what might motivate those interfaces is if you have a KD tree that wants to work on arbitrary points, you create a Dimension and Distance interface to tell others what functionality you need to work on them, which strikes me as more the point of interfaces than telling a consumer what they need to be able to handle to work on you. That's the kind of coupling interface-focused design is meant to avoid in the first place. (Of course, in practice you probably will end up reusing interfaces in the codebase so you don't need 3 different Dimension functions because 3 different classes needed to know a vector's dimension). E: Admittedly, this is easier in classes with more typeclassy interfaces like Rust, where you can bound a generic on compositions of interfaces rather than needing to write a separate interface that composes all the functionality you need together. At least, IIRC in Java if you need someone to implement interface A,B, and C, you have to make a tag interface that extends A, B, and C, and the implementing class has to explicitly state it's implementing the tag interface, which is a bit messy and less than ideal. Linear Zoetrope fucked around with this message at 20:49 on Sep 24, 2016 |
# ? Sep 24, 2016 20:45 |
|
an interface for everything makes sense in the context of a unit testing philosophy where you only ever test at the class level and mock out all of its dependencies in your test and your testing framework only lets you mock things with an interface the above testing style is however a terrible idea and so an interface for everything is still a bad idea
|
# ? Sep 24, 2016 20:58 |
|
only use interfaces when you actually need an interface some reasons:
invalid reasons:
unfortunately in industry you will find people who probably believe you should slap an interface on everything because *reasons* and judge you negatively if you don't share this belief among many other OOP kool-aid beliefs
|
# ? Sep 24, 2016 21:01 |
|
the industry absolutely adores useless boilerplate that can be autogenerated by an IDE here is the standard industry practice using dependency injection and interfaces in C# to call a module in your own code from some other module in your own code where there's only ever one implementation of the interface: code:
code:
|
# ? Sep 24, 2016 21:12 |
|
The only codebase I've worked in that was riddled with interfaces and heavily unit tested was also constantly full of integration bugs. That said, it would be really handy if the BCL had interfaces for HTTP requests, event logs, other out-of-proc APIs because they are super handy for writing functional tests.
|
# ? Sep 24, 2016 21:14 |
|
automated in-memory tests should instantiate as much of the system or subsystem you are testing and only mock the boundaries (e.g. file and network operations) unit tests should be the exception to the rule if you are narrowing the scope of the test to some complicated calculation or something testing everything at the class level and mocking all its dependencies will result in useless and brittle tests that don't test the important interactions between classes and also unnecessarily make it difficult to refactor or change the code
|
# ? Sep 24, 2016 21:16 |
|
comedyblissoption posted:automated in-memory tests should instantiate as much of the system or subsystem you are testing and only mock the boundaries (e.g. file and network operations) Having trouble finding your shift key? How did you noty die as a baby, considering that you were likely too stupid to find a tit to suck on? (USER WAS PUT ON PROBATION FOR THIS POST)
|
# ? Sep 24, 2016 21:28 |
|
sarehu posted:Having trouble finding your shift key? How did you noty die as a baby, considering that you were likely too stupid to find a tit to suck on? I work in a company where our development is heavily centered around a database that is live 24/7 and gets new data every millisecond, whether it's from customers, employees, batch jobs, imports from external companies or services receiving data. We might have a "Case" object with Customers, Agencies, Employees, CustomerRelations, Activities, and 5-10 other domain entities below it that are tied to the database, and each entity can have between 20 and 100+ data fields. We change our data structure every release, removing or adding fields as necessary to implement new features. It is simply not worth my time mocking and simulating the database, so I always use the database straight up for unittesting (no mocking) as that will give me the best and most realistic results. Other people lucky enough to work on projects that are more static in their data or perhaps not tied to a database as all, will find that creating and maintaining a suite of unittests with mocking or whatever is more worth their time. However, don't forget the number one mantra: Unittests are only as worthwhile as the guy who wrote them. You could write 50 unittests for your class, but that doesn't guarantee that it will be bug free, and especially not that it will be free from semantic errors, which are the most important ones. comedyblissoption posted:invalid reasons:
|
# ? Sep 24, 2016 23:04 |
|
comedyblissoption posted:the industry absolutely adores useless boilerplate that can be autogenerated by an IDE Hmm yeah that second one sure is better in a very narrow set of circumstances that the majority of people won't find themselves in, while the first one is far more flexible and general, hmm makes you think.
|
# ? Sep 25, 2016 00:57 |
|
Yup, super glad I don't work in or with anyone that uses OOP.
|
# ? Sep 25, 2016 03:44 |
|
Posted this in the Game Jobs thread, but the more eyes the better.everythingWasBees posted:So a few game companies are gonna be at a upcoming job fair this Wednesday, and I'm hoping to land a summer internship. There's a good relationship between both the school and game development club and the local companies, with lots of alumni from both at various positions, and employees sometimes working as lecturers. I've never written a resume before, and was hoping I could get some feedback. Because I know it'll come up, I specified C++98 as I haven't touched C++11, and there's apparently no good way to write C# in LaTeX. I have taken, or am taking, Computer Graphics, Animation Programming,and Artificial Intelligence, as well as the standard classes (Physics, Calc classes, data structures, assembly, etc,) although I haven't heard a worthwhile argument in including those on a resume. everythingWasBees fucked around with this message at 18:57 on Sep 25, 2016 |
# ? Sep 25, 2016 08:34 |
|
everythingWasBees posted:Posted this in the Game Jobs thread, but the more eyes the better. This site can’t be reached The webpage at https://www.overleaf.com/docs/6335846hvtprp/pdf.pdf might be temporarily down or it may have moved permanently to a new web address.
|
# ? Sep 25, 2016 13:54 |
|
Gildiss posted:Yup, super glad I don't work in or with anyone that uses OOP. I don't get the antipathy for IoC/DI, in certain contexts it works really well. In a previous place I worked on a .net mvc app, we used one of the standard idiomatic containers and adding new types and wiring was braindead simple. There was literally no time spent doing any drudge work on changing constructor args, lifetime scoping of entities (e.g., instance per request vs shared singleton) was done in one place, the dependency graph was nice/simple/acyclical (impossible to gently caress up because resolution is automatic, via constructor injection only). This meant people were more inclined to factor and split out types because there was zero weight/resistance to doing so in terms of boring code shuffling. In other contexts it's not idiomatic so why do it? Part of what I work on now is a C++ SDK for a cross platform library for high performance simulation. We don't use DI there, and don't use interfaces internally, but we have them at the boundaries of the library for some things. A big reason the comparison featuring this code is such bullshit: code:
It's like arguing that free functions are better than classes, it's just stupid argument to make for the general case. The static class way also sucks because it is surprising that Bar depends on Foo when examining the class constructors, which are the idiomatic mechanism to express dependencies.
|
# ? Sep 25, 2016 17:14 |
|
I agree in practice the boilerplate is not that big a deal. You just learn to live with saying foo 6 times every time you need to declare it as a dependency because the IDE helps autogenerate it for you, but it is still absurd and has no reasonable justification. The language could also require you to put "Java/C# is great and awesome!" at the top of every source file and your IDE could autogenerate it for you, but "it's not a big deal" would not be a valid argument in support of such a requirement.return0 posted:What if Foo and Bar need state and we need to make more than instance? return0 posted:What if Foo.DoSomething() depends on the environment and needs to be stubbed or mocked, or what if it hits a live service (like a payment gateway). return0 posted:The static class way also sucks because it is surprising that Bar depends on Foo when examining the class constructors, which are the idiomatic mechanism to express dependencies. return0 posted:It's like arguing that free functions are better than classes, it's just stupid argument to make for the general case.
|
# ? Sep 25, 2016 18:07 |
|
return0 posted:In other contexts it's not idiomatic so why do it? Part of what I work on now is a C++ SDK for a cross platform library for high performance simulation. We don't use DI there, and don't use interfaces internally, but we have them at the boundaries of the library for some things.
|
# ? Sep 25, 2016 18:14 |
|
This belongs in the coding horrors thread.
|
# ? Sep 25, 2016 18:18 |
|
I think the position I'm taking is more germane to this thread (general advice for new programmers interviewing) than the alternatives, but point taken. I'll stop the poo poo derail.
|
# ? Sep 25, 2016 18:24 |
|
I agree your advice is completely idiomatic and the general standard accepted "best practice" in the C#/java world. I follow it on my team projects at my job. Newbies will not go wrong to following it. It would actually be detrimental to follow my advice as a newbie with other industry programmers since they will argue that you're wrong and view you as problematic. I am just pointing out the idiom is flawed and without justification.
|
# ? Sep 25, 2016 18:31 |
|
I agree. It requires a bit of a nuanced view to figure out when it's best to roll with the idioms, and when it's worth deviating. This applies both technically and politically - don't pick a pointless hill to die on. And definitely don't die on it in an interview when you're just starting out (unless you're super talented, then do whatever).
|
# ? Sep 25, 2016 18:42 |
|
Hughlander posted:This site can’t be reached https://www.overleaf.com/read/ztxhmhhmqgrr This should work.
|
# ? Sep 25, 2016 18:57 |
|
I can only offer the stock-standard completely-unhelpful response that everyone inevitably sees whenever a question of "best practice" comes up: Sometimes you'll want lots and lots of interfaces, sometimes you won't. One of the projects I spend the majority of my time working with is incredibly complex with bits and pieces that need to be swapped in or out. We have an expectation that this pattern is likely to continue, and new stuff that we implement is likely to eventually need alternative implementations that can be swapped in and out using DI. This means we tend to code to interfaces habitually on the code library layer. BUT when we use that code library in an MVC project for example, we'll try to avoid using too many interfaces, particularly when we write the adapter layer between the MVC controllers and the code library/API layer, because generally speaking that code is specific to that particular project and we'll never need another implementation. So we have one project where we do follow the "interface just about every class" pattern and others that consume that project where we don't. There's no strictly correct way to approach it, it's entirely contextual. I know that sounds obvious but the way some people are framing their arguments makes it appear that it's not as obvious as I thought at least.
|
# ? Sep 26, 2016 08:55 |
|
return0 posted:There was literally no time spent doing any drudge work on changing constructor args, lifetime scoping of entities (e.g., instance per request vs shared singleton) was done in one place, the dependency graph was nice/simple/acyclical (impossible to gently caress up because resolution is automatic, via constructor injection only). I'm pretty sure this was a function of your coworkers' competence rather than your choice to use DI.
|
# ? Sep 26, 2016 17:50 |
|
everythingWasBees posted:https://www.overleaf.com/read/ztxhmhhmqgrr Don't list your GPA unless you think it's poo poo hot, even then most normal people don't care. I'd suggest you put the stuff you want to highlight at the top and put the detail there. Your projects section sounds much more interesting than your professional section, you should flip their sizes and go into way more detail about what you accomplished / did in the projects. Also I can't tell what kind of job you're trying to get. You are tailoring your resume to the places that you're applying to right? That's just my $0.02, someone else should probably chime in.
|
# ? Sep 26, 2016 18:39 |
|
Munkeymon posted:I'm pretty sure this was a function of your coworkers' competence rather than your choice to use DI. I've worked in places with... challenging co-workers, and the use of a container was an excellent forcing function to prevent them from concocting all manner of N-phase initialisation : N > 1 devices. That isn't an issue where I am now, but it's still something to keep in mind. You never know when you're going to absorb a number of less skilled developers. If it doesn't hurt the good-developer path (and it can, so you need to be careful) and it protects against some of the worst machinations of the less good developers, it's worth considering.
|
# ? Sep 26, 2016 20:35 |
|
|
# ? Jun 4, 2024 05:06 |
|
return0 posted:I've worked in places with... challenging co-workers, and the use of a container was an excellent forcing function to prevent them from concocting all manner of N-phase initialisation : N > 1 devices. That isn't an issue where I am now, but it's still something to keep in mind. I mean, I managed to create a DI graph cycle one time a couple of jobs ago and only found it because I wrote out a graph that went ~6 hops out of the class the crash actually happened in. It was a big, messy graph that I could not hope to keep in my head, partly because I largely was not responsible for making it. I almost gave up and started looking for a different cause after four hops because it was getting silly. I also wasn't the only one to do it and whatever DI mess we were using made this class of error only show up occasionally or after multiple re-builds, so I guess what I'm trying to get at is that DI isn't magical fix-all fairy dust as I think the bit I quoted kind of implied.
|
# ? Sep 26, 2016 21:04 |