Dependency Injection Breaks Encapsulation

Yeah. It is a fun, but futile effort. :wink:

Scott

You are making a fundamental mistake by assuming that the class deals with database access when in fact it does not. It deals with the Model in the Model-View-Controller design pattern whereas all database access is done in a separate Data Access Object (DAO) where I have a separate class for each DBMS. The Model is therefore concerned with the business rules which need to be processed when writing to or reading from a database table. If you knew anything about the Separation of Concerns you would realise that business rules do not belong in either of the Controller or the View, or even the DAO, so they are, in fact, exactly where they belong - in the Model.

I don’t have complex hierarchies in my applications. Each business entity is a stand-alone class which inherits from nothing but a single abstract table class.

I find the idea of breaking up code into a number of smaller classes to make it “more readable” to be a ridiculous idea. I have already broken my application up into separate classes for the Model, View, Controller and DAO, and if my Model requires 100 lines of code of business rules then I would rather see them in one place than have to keep jumping from one class to another.

There is no limit on the number of methods or properties which a class may contain, nor is there a limit on the number of lines of code that a method may contain. The idea that each method should do “only one thing” can be taken to ridiculous extremes and result in software where each class contains only one method (if it contains more than one then it’s doing more than one thing, right?) and each method contains only one line of code (if it contains more than one then it’s doing more than one thing, right?). I have seen software written to that ridiculous level of separation, and it was infinitely less readable than as mall number of large classes.

I disagree. The golden rule of encapsulation is that ALL the methods and ALL the properties for an entity should be put into a single class. By arbitrarily splitting it into smaller classes just to satisfy a personal whim would violate the rule of encapsulation.

It is not monolithic, nor is it spaghetti code. If you bothered to look at my abstract class you would see that it contains a large number of methods, and each method is concerned with just one step in any particular operation which is activated from a Controller.

DI has nothing to do with encapsulation.

There is no limit on the number of methods that a class may contain, nor on the number of lines of code within a method. There is also one thing you seem to be forgetting - that “monster” class is not a concrete class, it is an abstract class that contains every method that may be used in a concrete class depending on what that class has been requested to do.

DI, like every other design pattern, is only a good idea when used appropriately.

The fact that lots of developers implement DI at every possible opportunity does not mean that it is a good idea. Lots of people some pot, or cheat on their spouses, or fiddle their expenses, but does that make those practices a good idea?

I agree that OOP is about being modular in design, which is why my framework is a combination of the 3 Tier Architecture and the MVC design pattern. I have more reusable code in my PHP framework than I ever did in either of my previous frameworks, and probably much more than in any of the more popular frameworks.

Exactly. It will never be called if all goes well, but it is there just in case something unexpected happens.

And yet you still cannot define what makes DI “Inappropriate” in those scenarios.

Hmm…I think otherwise.

encapsulation means that the internal representation of an object is generally hidden from view outside of the object’s definition.

“internal representation” is another way to say “details”, right?

With dependency injection, the client which uses a module or service doesn’t need to know all its details

sounds like DI supports encapsulation to me. Although one speaks of objects and the other speaks of modules or service, modules and services are also just objects or groups of objects too, right?

Right, there isn’t a written rule and you are again avoiding the point. Your monster class ignores the Single Responsibility Principle.

In object-oriented programming, the single responsibility principle states that every class should have responsibility over a single part of the functionality provided by the software,

Your class has more than one responsibility.

So are you seriously saying, an abstract class is a reason to have 9000 lines of code in it? Because, possibly some of the methods could be used in some concrete class? If you say yes, then you will be sinking even more into your obvious quagmire of ignorance about OOP programming. Funny thing too is, not one instance of the word “abstract” can be found in your abstract class, which means it can be instantiated on its own, which means IT IS NOT an abstract class.

What kind of argument is that? DI is a great design pattern!!! I thought we had that understood. The fact it might not be useful everywhere does not take away from its usefulness. And you compare DI to smoking pot? Could it be you’ve smoked some before you wrote your answer? LOL! :smiley:

You are claiming to have more reusable code than today’s frameworks, yet you believe in 9000 line classes as being “ok”? Right. I am not going to try and prove you wrong, but I don’t believe you are right for one minute. Your stuck in a lonely world Tony. I wish you’d come out of it.

Scott

I have defined it several times in this discussion, so I suggest that you learn to read.

You defined it as:

Which as I said is utterly meaningless without something to quantify it. As I said twice it’s like saying “Whether or not the car is more appropriate than a is appropriate than a bike boils down to a simple question - how many passengers will be travelling. If the answer is “more than one” then a car is appropriate.”. It, like your argument about DI falls flat because it doesn’t define what appropriate is and it’s not a case for the bike when the car can be used for one or more passengers. You need to somehow define WHY DI is less appropriate (or another solution is more appropriate) to make your case. Just saying “Because it is” is nonsensical. You need to actually describe how you’re measuring “appropriateness” in order to claim that “X is more appropriate than Y when Z is true”, which you have not done.

It’s a circular argument… and doesn’t actually define why that is the case. Please learn to read.

The original definition of encapsulation was limited to implementation hiding, not information hiding. The two are entirely separate. The fact that some people choose to redefine what it means to suit their own purposes does not change the original definition, and that is the only one that I am prepared to accept.

You can think what you like, but it does not change the fact that encapsulation was defined many years before DI was even thought about, so to say that encapsulation requires DI is plainly wrong. It is as daft as saying that any design pattern which uses objects or classes is part of encapsulation.

Just because they use terminology which has some similarities does not necessarily make it right to say that they are identical, or inextricably tied together.

It depends on your definition of SRP. As a guideline as use this definition provided by Robert C. Martin in this article at http://blog.8thlight.com/uncle-bob/2014/05/01/Design-Damage.html

That is why I have my GUI, business rules and database access in separate modules. This is the classic definition of the 3 Tier Architecture around which my framework is based. I have actually taken it further by splitting the Presentation Layer into two which then form the View and Controller of the MVC design pattern. All the Models then exist in the Business Layer, and all database access is done within the Data Access layer.

That “monster” class of mine is an abstract class which is inherited by every Model class. It does not contain anything which belongs in either the View, the Controller, or the DAO, therefore it is perfectly valid. I am correct according to Robert C. Martin’s definition, and I’m afraid that his definition carries more weight than yours.

Right. That is 9000 lines of reusable code which exists in an abstract class and which is inherited by every Model class in my application. I have over 300 Model classes, so it means that the code is reused over 300 times.

I also have 1 DAO which is shared by every Model in my application. Do you?

I also have 40 Controllers which are shared by every user transaction (of which there are over 2,000) in my application. Do you?

I also have 3 View components - one for HTML, one for PDF and one for CSV - which are shared by every user transaction within my application. Do you?

Unless you can match my levels of reusability you have no right to lecture me on how to write reusable code.

If you cannot understand what that means then I shall not waste any more of time in trying to educate you. You clearly have a closed mind and no amount of logical argument will have any effect on you.

We agree to disagree, so unless you have something new to bring to the discussion I shall ignore you.

If you need 2000 variants of anything you do not have reusable code. If you had reusable code you would reuse existing “user transactions” rather than needing new ones each time.

Your code violates SRP and a 9000 line class is inherently a bad idea. Listen to Scott, he’s pointing you in the right direction. If you actually accepted criticism rather than trying to defend your bad decisions you’d be better off.

1 Like

What a cop out. You are wrong, you cannot back up your arguments so you choose to ignore me.

Play the “LALALA FINGERS IN EARS” game all you want, it just prooves to me and everyone else that you are incapable of backing up your claims.

Tony your argument is this:

“I always travel by bike”
“It’s more appropriate than a car because I am the only passenger”
—Why is it more appropriate?
“Because I am the only passenger”
–why isn’t a car appropriate
“Because I am the only passenger”
– But you can still use a car can’t you?
“Yes but I am the only passenger so I dont”
–Why can’t you use a car
“I can”
–So why don’t you
“Because I’m the only passenger”
–But that’s not stopping you use a car

Can you honestly not see why this argument makes no sense? Of course you can but you simply can’t admit when you’re wrong.

Your argument is non-existent and you know it.

Where was that ever said? I said it supports encapsulation and I even added “indirectly”, knowing that it is sort of bending the definition of encapsulation. Still, DI supports the concept of modularity, which encapsulation supports too and that is how I see they are in common NOT identical or inextricably tied together. You seem to read things that aren’t there and get defensive or argumentative about unsaid things unnecessarily.

I’ll get to the rest of your reply later.

Scott

Tony’s argument is so futile at this point he’s resorting to misrepresenting everyone else’s points.

So you pull out two sentences out of a blog post that says MVC is a good design, because it separates concerns and then you say, well, because old Uncle Bob says that is a good design, then my 9000 line class is also a good design? Am I understanding you correctly? Because, it is totally bogus logic.

The blog post by Uncle Bob was about a design that was way too coupled to the Rails framework. It had nothing to do with what good separation of responsibility is all about and what it means to code structure. It is speaking at the architectural level of design. It’s the difference between a strategy and tactic. Strategy is MVC. Tactic is splitting code into smaller chunks with a clear and singular “reason for change” (which is also from Uncle Bob). Your 9000 line class has a good number of reasons to change.

If the functionality of the “custom button” changes, your 9000 line class would need changes. What the heck does a custom button have to do with a “Table” object anyway?
If you decided to change the form data to add xml, your 9000 line Table class would need changes.
If something changed in the internationalization (language system), your 9000 Table line class would need changes.
If something changes in the scrolling thingamajiggybopper, then your 9000 line Table class would need changes.
If task initialization needs changing, your 9000 line Table class would need changes.
If your file system tasks need changing, your 9000 line Table class would need changes.
If your “popups” need changing (popups? WTF? :flushed:), your 9000 line Table class needs changing.
If your search needs changing, your 9000 line Table class needs changing.
If your validation requirements change, your 9000 line Table class needs changing.
If anything with your _cm customizable what-ever-it-is needs changing, your 9000 line Table class needs changing.
If something in the DDL logic changes, then your 9000 line Table class needs changing.
If something with the DML logic needs to be changed, your 9000 line Table class needs changing.
Oh, and of course, if something with your Table logic changes, then you need to change your monster class.

Scott

2 Likes

FYI Tony was correctly told that his definition of Encapsulation (and OO concepts in general) were flawed almost a decade ago: http://bytes.com/topic/php/answers/569321-php-5-classes-public-protected-private/2 and he hasn’t budged an inch or learnt anything since then.

Off-Topic

With the recent update members now have the option in their Profile Preferences

Oh My. :open_mouth:

Scott

:wink:

1 Like

I disagree. Uncle Bob’s article clearly identifies that the GUI, business rules and database access should be separate, and that is exactly what I have done.

Just because you think that does not make it true. That abstract class contains code that may be needed in any Model class, and none of that code belongs in an alternative class such as the View, Controller or DAO.

Incorrect The custom button code in the abstract class is just an empty wrapper for application-specific code which goes in the concrete class.

Each of my Model classes represents both a business object and a database table, and an operation on one of my Model classes may have a custom button on the screen. If such a button is pressed in activates the customButton() method in the Model class in order to execute whatever business rules have been defined.

No it wouldn’t. All XML generation and SL transformation is performed in a separate View object.

Wrong on every count. If you bothered to look at my code with an unbiased eye you would see that most of the methods in the abstract class are empty. This means that at runtime nothing happens unless the concrete class contains code for that method.