Dependency Injection: a discussion of the pros and cons

Which is a perfect example. Walls have similar properties hardness, thickness, etc but they have different material

new ShipWall();
new CastleWall();

Is not reusable

new Wall(new Stone());
new Wall(new Wood());

is. The parts which are relevant to all walls are kept and the parts which are not can be substituted,

1 Like

Ah yes, but you’d never employ someone who builds a castle wall to build a wall on a ship. One is typically a stacked block, the other is a constructed panel. There are completely different skills and materials needed to build it.

My point is, why build in the capability of building a castle wall if you’re only ever going to use it to build ships? That’s extra work that has to be skipped (which does affect performance) that will NEVER be used.

Because I work in a shop where we build thousands of different applications. Having components allows me to take a User and put them in the next application, along with the login providers we’ve built, the registration, the storage facility, the laying out of a room/window, whatever.

I’ve also had to deal with several components changing because the company went with a new third party billing provider, or a new datasource, so we had to swamp those out or rather tell the system to use the new component via DI.

Also, a Wall is a collection of building materials. Your reusable component called a Wall would be a collection of building materials (or really a matrix of them). So a Wall is a Wall. The materials may change, but the wall itself is still a wall. Just like a Window is a Window. Sure the view of the Window on a ship will make it look like a porthole but the properties of it remain consistent. It may have a door, glass, with a width and height of X, etc. How you implement that component in your view is what makes it different from the castle’s window, but the component itself remains the same.

Not really for us… We have no way of writing true unit tests without these hooks. If my registration page was in charge of building the user object, how does one test it? How do you mock the user object that is inside the registration code (or the database connection)? Simple answer: You can’t. If I pass in the user/database object and the registration is purely designed to update the properties, I can now test it.

I don’t disagree there, but that doesn’t change the fact that Tom’s statement isn’t opinion, but rather a fact. He can easily take a Wall from a ship and use it as a Wall in a castle. He simply sends different building materials to the Wall, so it is more fortified, made out of stone and concrete and has a view that outputs it accordingly.

1 Like

But that’s just a separation of concerns issue


new BuildingComponent(new Stacked(), new Wood());
new BuildingComponent(new Panel(), new Wood());

The more you genralise and the smaller your classes are the more easily they can be reused.

1 Like

Because we do use them. A lot. Even in the insurance industry, we have to inject all sorts of things. Coverages by Symbol/Line/Type Of Insurance, by State, by Effective Date, by Term, etc. We are always needing this.

Then Testing is the biggest reason we do it. We can mock our objects for tests allowing us to be 100% certain we fully tested each component, each line.

I don’t write code to build ships or castles, I write code which deals with enterprise data, and which communicates with the user via HTML forms and which stores all data in a relational database. All my classes in the Business layer therefore deal with database tables - not shapes or images or castles or ships. So saying that my software cannot easily be used to switch from building ships to building castles is completely pointless and irrelevant.

BINGO! You’ve hit the nail squarely on the head. That’s precisely the point I have been trying to make.

Do you lack an imagination? As that wasn’t meant to be taken literal. Substitute your business for Ships and substitute business Y for Castle. sigh

As an aside, for someone being in the “career” for 35+ years, I’m sure you don’t need such basic interpretations, as surely you’ve heard these sayings before…

All this is irrelevant to me as I deal only in data which is held in a relational database. Each Model class therefore deals with a single database table, and the differences between different database tables is fairly limited:

  • the database name
  • the table name
  • the table structure
  • custom validation logic and business rules

Just out of interest Tony, do you ever write new software (as opposed to just maintaining your decades-old system that you keep referring to), work with other software engineers, or use 3rd party components?

My applications are built to deal with data in a relational database. If I have designed a database for building ships then it should be obvious that it cannot be used for building something which is not a ship as the data requirements would be totally different. I would therefore design one set of tables for building ships and another set for building castles. Each set of tables would therefore have its own set of screens and business logic. The only commonality between the two sets of data is that they would exist in a relational database, and my framework is geared up to deal with database tables, so all the things which are common between database tables are handled automatically by my framework. That is where reusability comes into play.

I write new software in the form of new modules which I add to my ERP application. Sometimes I add new components to an existing module.

I currently work with a team of developers in the Far East who have developed their own modules on top of my framework and who are now selling my ERP application to several multi-national corporations. THEY would not be using my software to write business-critical applications if they thought it was crap.

I use very few third party components as I prefer to write my own.

I deal with enterprise applications, and my framework was specifically designed to help build and run those applications. My framework contains built in login and Role Based Access Control, Audit Logging and Workflow. Each “application” consists of one or more modules, and each module deals with the tables in a particular database. I have a Data Dictionary which helps build the table class for each database table and the user transactions for each table. The “RAD” in RADICORE stands for Rapid Application Development.

Do not waste your time telling me that my components are not reusable - my entire framework is built around reusable components. I would probably not be wrong in saying that the levels of reusability which I achieve with my framework are far superior to anything which you could achieve.

And here we go again with the insults and ‘holier than thou’ attitude. Talk is cheap, Tony.

I have been following this discussion with great interest since it started, because I thought I would learn a lot from it. But there’s nothing that turns me off more quickly than arrogance and people who claim to be far superior to others in an area. I am sure that everyone still has room to learn.

4 Likes

Yeah the thread seems to have strayed from what I’d hoped it would be. Perhaps we could get things back on a more useful track… are there any particular aspects to the topic that you’d like to discuss?

So do I :smile:. The framework I built at my prior job continues to be used to this day and processes 10’s of thousands transactions daily. Sometimes hourly (depending on the work they are doing). All of the components for it though could be rearranged to run an entirely different application and not just used for Insurance related operations.

Does it rely a lot on DI, yep! Why? Because it was test driven development and DI helped me solve how to test every aspect of my code thoroughly and in a practical way. Need to run your tests on a build server and mock the database so your tests can components can actually achieve what they need to do? Sure no problem, let me mock my database object and send that into the appropriate components. Need to prove that a component will fail in its responsible way if the database is down or has bad data? Sure, let’s mock the bad database connection and pass it in.

DI has been a huge benefit to me and the way that I code as I can write better tests. Better tests means I can churn out changes quicker, as I simply write a new test for the upcoming change, write the code, and then verify all tests still pass. If they do, I didn’t break anything! :slight_smile: QA runs through their regression and integration tests (either in an automated fashion or manually) and things continue to move forward with ease.

Since going this route, the number of bugs produced from my changes have been zero. We’ve found issues with requirements or maybe a requirement was written incorrectly, but from what the requirements had, their test cases/scenarios, and the final result of development, zero bugs.

I unfortunately can’t say the same for some of the legacy systems that our devs do not write tests for, are riddled with tightly coupled dependencies, and although they “function”, the amount of time spent on fixing bugs, adding/updating functionality there is cost heavy and typically results in a new bug or two or dozen that most of the time gets caught in QA, but have edge cases that make it to Production as well.

So although I understand your framework doesn’t need it, mine and the confidence I have in it does and has saved the company a lot of money by letting them shift their focus from 20-25% of your time spent on bugs, to using that for new features.

That may be my experience and your experience may be entirely different, but if I were to start a project again from the ground up, I’d still follow a Test Driven Development path and ensure that my components can be fully tested and that would mean the usage of DI as a must.

This example is irrelevant and does not address my point at all. We’re talking about the pros/cons of DI in general. I don’t want specific implementation details. However, I’ll bite. How do do you assign validation rules to a table? What if you have a rule that is relevant to mutliple tables (e.g. names cannot contain numbers)?

I gave you this list before, but here it is again, not that you’ll read it.

Abebe et al (2008) Lexicon Bad Smells in Software http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=5328733&url=http%3A%2F%2Fieeexplore.ieee.org%2Fxpls%2Fabs_all.jsp%3Farnumber%3D5328733
Hevery, M (2008) Flaw: Brittle Global State & Singletons. http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/
Hevery, M (2008) Singletons are Pathological Liars http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
Densmore, S (2004) http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
IBM (2012) Avoid modification of global and static variables http://www-01.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.dapip.doc/ids_dapip_0673.htm
Sayfan, M (n.d.) Avoid Global Variables, Environment Variables, and Singletons https://sites.google.com/site/michaelsafyan/software-engineering/avoid-global-variables-environment-variables-and-singletons
Radford, M (2003) SINGLETON - the anti-pattern! http://accu.org/index.php/journals/337
Yegge, S (2004) Singleton Considered Stupid https://sites.google.com/site/steveyegge2/singleton-considered-stupid

Included in that list are IBM, MSDN, Hevery who is a lead programmer at Google and some academic journals.

This again has turned into another useless discussion and why I said Tony doesn’t deserve even the thread.

This reminds me of a great Mark Twain quote.

“Never argue with a fool, onlookers may not be able to tell the difference.”

Scott

This thread is getting quite interesting, so here are my two cents:

Nope, people have been giving you explanations after explanations on precisely why Singleton is bad. But you dont remember them, since you refuse to listen, and instead consider their comments as personal insults. It does not matter whether you hear them or not, they do objectively exist anyway, which makes your point invalid. Singleton is an antipattern and there’s no room for even arguing on this aspect. I think you should understand better if you start to take constructive criticism nicely and do not hold this ‘I have much longer programming experience than you’ attitude.

Dependency Injection has A LOT to do with encapsulation, because it offers a way to achieve better information hiding. The alternative to Dependency Injection, your singleton(which are effectively glorified global variables), it totally breaks encapsulation. I cant say DI is a perfect solution, but at least it does not break encapsulation like Singleton does.

First of all, can you define what is ‘superiority’? And next, what is this so-called level of reusability in your framework?

Anyway I agree with @WebMachine that this thread has gone in an unfavorable direction and that it has strayed from the original intention by the OP @fretburner. But anyway, I dont see it really going anywhere, until Tony realizes that the counter-arguments and constructive criticisms are not meant for personal insulting, but for valid discussion. Or maybe, Tony actually does this on purpose since if he acts like he ‘is angered or hurt by insulting comments’, he will have a better chance to digress(like he did at post #46) and make the rest of us lose focus on what we are discussing. umm smart strategy if you ask me.