Reputation: 1277
Assume we have a class called "MyClass"
Public Class MyClass
End Class
this class has a function called "My function"
Public Class MyClass
Public Function MyFunction()
End Function
End Class
This class has been implemented for some time and its been working fine. Now we need to change the implementation of the function "MyFunction". One option would be to open the source code and change it there. But I'm guessing there has to be a better approach.
Inheritance comes to mind but I don't want to change the derived classes name. I want the name of the class to still remain "MyClass", But I'm guessing the code below will cause an error:
Public Class MyClass
Inherits MyClass
Public Function MyFunction()
End Function
End Class
In other words I'm trying to create a new version of the old class by keeping most of the members the same but just changing a few functions.
To explain the project as a whole, The program is meant for structural design. What it does it designs structural components (i.e columns, beams, slabs, ...). The design procedures are specified by 3rd parties (government regulations). For example: In the year 2007 government regulations specified that column dimensions are to satisfy the equation F:
H*B < Fy^2/L
In the year 2008 they introduced a new function G and they say column dimensions must satisfy this new function:
H*B^2 < Fy^0.5/E+Alpha^2/L
Where H and B are column dimensions.
What I don't want to do is to open the source code every year and make these changes. I want to somehow override the functions that need to be changed without opening the source.
Any Ideas?
Upvotes: 0
Views: 120
Reputation: 12748
The formula is a bit complicated and you'll still need to change some code unless you store these in a database somehow.
An option would be to use inheritance with a factory method.
Public Class BaseClass
Public MustOverride Function MyFunction()
Public Function GetInstance(ByVal year As Integer) As BaseClass
If year = 2007 Then Return New Class2007()
If Year = 2008 Then Return New Class2008()
End Function
End Class
Public Class Class2007
Inherits BaseClass
Public Overrides Function MyFunction()
' H*B < Fy^2/L
End Function
End Class
Public Class Class2008
Inherits BaseClass
Public Overrides Function MyFunction()
' H*B^2 < Fy^0.5/E+Alpha^2/L
End Function
End Class
then, everywhere in your code you use BaseClass never knowing that Class2007 and Class2008 exists
Dim o As BaseClass
o = BaseClass.GetInstance(2007)
o.MyFunction()
Depending on the need, this can also be done with interface.
If you need to store the formulas in the database as string, you'll need to get a parser and this can also be found using 3rd party library. https://stackoverflow.com/questions/1387430/recommended-math-library-for-c-net
Upvotes: 0
Reputation: 26424
The code is generally not supposed to be changed over time. That is - if you wrote code that is guaranteed to break after 2 weeks by itself, you probably should reconsider your design.
As you rules/regulations come out, you usually update your input data (in a form of XML, or a relational database for large amounts of data), and your program would automatically pick those up.
The only case you would update your program under this scenario is when new type of regulations come out. But even in this case the changes are usually minimal.
A good anti-pattern example for this - you have 500 forms, each of them has 500 lines of code, so that's 250000 lines of code in your UI layer. New regulations come out that requires changing 50% of the code in each form. Your impact is 125000, which at 40 lines of code per day would take 8.5 developer-years.
A solution to this would be having a change of 100 lines spread across all forms, adding 1 line in each, or leaving everything as is. Also there will be a data load/conversion procedure from a government/other file, which populates your database in the proper format, updating the values or adding new ones. There may be 10 lines of change in that program, but that's about it, 3 days worth of work, if you believe in 40 LoC per day. Otherwise it still falls under 2 weeks of developer's time.
Depending on how you implement it, the benefit of this approach could be that you support old standards as well, so older input can be matched and production reports can be generated. It is a good practice to be able to back-date your reports, cause sometimes there are issues in report code left unnoticed for months before being discovered.
EDIT: A more structured approach to what I suggested in the comments would be storing expression trees in the DB. Most simple form of it is just a linear workflow, using postfix notation (single table). For example A, B, + C -
is equivalent to A + B - C
. You can then have a user interface for some configuration tool, which only allows user to input values and functions that are applicable. This is assuming applicable values are also stored in DB as parameters (one structural component can have 0...N
of them).
Upvotes: 2
Reputation: 938
Inheritance can do what you want but you need to create a new ancestor, not descendant.
Change the name of the original class to something that denotes that it is a base class. Also, add the MustInherit modifier to the class and Overridable to any of the methods or properties that you may need to override.
One thing to watch for is Private members in this base class. Any members that need to be accessible from the descendant class cannot be Private and must be changed to Protected.
The original class looks like this.
Public MustInherit Class MyBaseClass
Public Overridable Function MyFunction() As String
' code...
End Function
Public Overridable Function AnotherFunction() As String
' code...
End Function
End Class
Now create a new class with the original class's name which inherits from the base class. Override just the members that need to be different.
Public Class MyClass
Inherits MyBaseClass
Public Overrides Function MyFunction() As String
' new code...
End Function
End Class
That will get you started. The Template Pattern will allow you to do more fine grained code changes where only parts of a method need to be changed.
Upvotes: 0