Reputation: 1
Clearing things on the beggining:
I understand how to apply OCP to code below (virtual class, DI and so on, there are tons of resources on web about that)
I know (but do not understand) arguments why I need to apply OCP (3 that mainly occur on web are listed below)
I think I am missing the point because I do not have big enough commercial experience.
What I don't understand in OCP are the arguments/consequences (mentioned below) found in all articles regarding OCP
Violating OCP is bad because:
1. You need to write test for old class - it is bad, better to write test for new class.
I do not understand why it is bad?
In both cases I need to write new test. Either for new class or for old class.
2. You need to redeploy application If there are two clients: A (which do not need new functionality) and B (who wants new functionality)
2.1 When I am violating OCP by modifying base class.
client A - do not need to redeploy - because he don't need new functionality
client B - need to redeploy - to get new functionality
2.2 When I am not violating OCP by adding derived class.
client A - do not need to redeploy - because he don't need new functionality
client B - need to redeploy - to get new functionality
I do not understand why I need to redeploy whole application? In both cases it is the same situation- client A do not need to redeploy, client B need to get redeployed application.
3. You can introduce a mistake to the working system But I can also do that when I will put new functionality in it, can't I?
Can you help me understand the meaning of these points above? I was using following example from website
public enum InvoiceType
{
Final,Proposed
};
public class Invoice
{
public InvoiceType InvoiceType { get; set; }
public double GetDiscount(double amount,InvoiceType invoiceType)
{
double finalAmount = 0;
if (invoiceType == InvoiceType.Final)
{
finalAmount = amount - 100;
}
else if(invoiceType == InvoiceType.Proposed)
{
finalAmount = amount - 50;
}
return finalAmount;
}
}
Upvotes: 0
Views: 535
Reputation: 4109
Let me try to give you some insight, however I'm not going to cover all the problems you've mentioned.
First and most important. Tests. Typical enterprise app contains ~10000-~20000 unit tests, not considering data randomization (if any, which is rarely the case: OO-programmers haven't discover tools like Haskell's QuickCheck
). And those tests are typically kind of entrance to the hell. Hundreds of mocks wired up in a given sequence, complicated dependency injections just to "make it work" and other kind of setups mixed up with test implementation heavily relied on the helpful methods of the... test classes or somewhat class SuchKindOfTestsUtilities
. In most cases there is either no time to cleanup tests frequently, or people just don't care: somewhy it is assumed that tests can contain duplicate of code, violate well-known principles of clean code without any consequences...
Now imagine you have to introduce new functionality. There is time pressure. There are tens of classes and stuff you're not quite familiar with. And you got choice like Neo: either green (don't like blue color) or red, where "green" represents "DO NOT CHANGE WHAT IS WORKING UNLESS ABSOLUTELY NECESSARY!!!" paradigm; indeed, "freezing" existing things, especially poorly coded, is the best way to go unless your manager and business ready to wait (and to pay) for a long refactorings (which they usually consider a time-waster).
And that one is just a tip of the iceberg ;)
Upvotes: 1