Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I would like to explore your thoughts on the below.
If I have essentually a data class
Public Class Package
Public Property Length as decimal
Public property Width as decimal
Public Property Height as decimal
End Class
Now I want a calculated property so I could add this to the class in 3 ways.
Have the class property calculate the result
Public ReadOnly Property Cubic as decimal
Get
Return Length * Height * Width
End Get
Use a calculation class to calculate the result
Public ReadOnly Property Cubic as decimal
Get
Dim Calc as new CalculationClass
return Calc.Cubic(Length, Width, Height)
End Get
I could also as an alternative have the property dumb and it could be calculated outside the class soon after the class is populated by calling the same calculation class in example 2. But outside the data class.
Private LocalCubic as Decimal
Public Property Cubic
Get
Return LocalCubic
End Get
Set(value as Decimal)
LocalCubic=value
End Set
End Property
Although the example above for the calculated property is simple I would also like to consider it may not be. It could be 200 or more lines long to do the calculation and maybe encombusing other properties in a larger DataClass.
There could also be hundreds of package classes created as the program runs.
My understanding of using each one is (Please comment if wrong)
Everything is contained in the class, readable and easy to work with. Each Package Class has its own copy of the calculation so for a simple calculation no problem. But if I have 500 package classes with the 'calculation' taking say 200 lines. It seems to me that a I am 'wasting' memory buy having 500 copies of the large calculation compared to the other methods.
Only one copy of the actual calculation is used as each class refers to the same calculation object. Every other class (500) is using the same code so it is saving on memory. Probably breaks OOP.
Has the advantages of 2) Major disadvantage is that if the Length, With or Height properties change in value at some time after creation and calculation then the Cubic property will be wrong.
Are there any other advantages / disadvantages to the above approaches?
Best Practice?
How do other programmers tackle this?
Thanks
Edit
I think I need to be a bit clearer in my questions above to make it more definative;
A) Does example 2) violate the OOP methodology?
B) Does using 2) create a new instance of the CalculationClass within each package class. Or does each Package class created reuse the same Calculation class code?
I would just make the volume a property of the Package class assuming the packages are all rectangular. Force the properties to be set in the constructor and calculate the Volume in the constructor.
Public Class Package
Public Property Length As Decimal
Public Property Width As Decimal
Public Property Height As Decimal
Public Property Volume As Decimal
Public Sub New(Lgth As Decimal, Wdth As Decimal, Hght As Decimal)
Length = Lgth
Width = Wdth
Height = Hght
Volume = Length * Width * Height
End Sub
End Class
Private Sub Button1_Click(sener As Object, e As EventArgs) Handles Button1.Click
Dim pk As New Package(7, 5, 10)
MessageBox.Show(pk.Volume.ToString)
End Sub
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Trying to create a universal placeholder for all methods in my class instead of having to declare multiple varibles per class, else declaring multiple instances of a class and using its methods can be quite costly
dim beginIndex, endIndex as integer
public sub GetLastFiveLetters(str as string)
' assume string is 10 characters long
beginIndex = 5
endIndex = 10
ResetVariable() 'I want beginIndex and endIndex to be 5 and 10 after I call this method
return = str.substring(5, 10)
end sub
public sub GetFirstFiveLetters(str as string)
'assume string is 10 characters long
beginIndex = 0
endIndex = 5
ResetVariable() 'I want beginIndex and endIndex to be 0 and 5 after I call this method
return = str.substring(0, 5)
end sub
public sub ResetVariables()
beginIndex = 0
endIndex = 0
end sub
The reset variable method is simply there for example purposes, what i want to do is be able to use a variable with multiple values across multiple methods...
So when i call reset variable, even though im technically reseting the variable across all methods, i want to variables to retain their method specific values ... so in the first method even though i called the reset method, i want beginIndex to still be 5 and endIndex to still be 10, it is only in the resetvariable method where beginIndex will be 0 and endIndex will be 0
Regarding storing variables in methods:
... declaring multiple instances of a class and using its methods can be quite costly
WRONG. Variables declared in methods, i.e. local variables, exist only while the method is being executed. On the other hand, variables declared at the class level, i.e. fields, exist for each class instance or object for its the whole life time.
You must make a distinction between the variable declaration and the memory that a variable uses at runtime. The variable declaration itself is not compiled into code. Only the variable accesses (i.e. setting or reading the variable) are. At runtime, local variables start to exist when a method is called and cease to exist after the method returns.
Class fields, however, exist as long as the objects exist, whether a method is being called or not.
I am working in Excel VBA.
This property sets Private Histogram
Private Histogram As Histogram
Public Property Let CreateSB_Solution(DataSet As Histogram)
Set Histogram = DataSet
End Property
This does not property set Private Histogram
Private Histogram As Histogram
Public Property Let CreateSB_Solution(Histogram As Histogram)
Set Histogram = Histogram
End Property
I know I am missing some small nuance but cannot find the proper search criteria to find it.
This does not compile: Method or data member not found.
Private Histogram As Histogram
Public Property Let CreateSB_Solution(Histogram As Histogram)
Set Me.Histogram = Histogram
End Property
The issue is Set Histogram = Histogram - what is being set to what? which histogram is on the left and which is on the right? - In reality both hold the value of the argument as the most local variable wins.
You can make what you have work by changing Private Histogram .. to Public but obviously this has consequences, or you can use indirection within CreateSB_Solution to call a private property to make the assignment.
Perhaps the best solution is to not name things in such a way that can lead to these types of problems in the first place, changing the structure of code simply to accommodate more visually appealing monikers is a bad idea.
Either of the below will fix the problem.
CreateSB_Solution(fromHistogram As Histogram)
Private CurrentHistogram As Histogram
I am fairly new to custom classes in VB.Net and am having a bit of an issue with assigning a value from my class to the class object. See code below:
Public Class NType
Public Const Small As Double = 1
Public Const Medium As Double = 2
Public Const Large As Double = 3
'Another thing I tried...
Public Shared ReadOnly Property _Small As Double
Get
Return Small
End Get
End Property
End Class
However as soon as I do:
Dim NType1 as NType = NType.Small
I get an error to say Value of type 'Double' cannot be converted to 'Harris.NType'
I assume there will be some sort of way to allow this (in a similar vein to how, say Color works)
I think that, from the looks of it, what you actually want is an enumeration rather than a class.
Public Enum NType
Small
Medium
Large
End Enum
Dim nType1 As NType = NType.Small
You can specify the actual values but, generally, those values should be irrelevant and all that matters is that they're unique and don't change. By default, an enumeration is stored as an Integer but you can specify any integral type. By default, the first value is equal to zero and each subsequent value is equal to 1 more than the previous one. You can specify one or more values if you need to though.
Public Enum NType As Short
Small = 1
Medium
Large
End Enum
The values still increment by 1 but will now start at 1 instead of zero. You should only do that if you will be using the same numeric values to represent the same data elsewhere and the two must match. Don't do it just because you can.
I have one class with a private static (shared, since I'm in VB.NET) field and its associated public static property, since it stores one variable that should be the same to all the instances of this class. So far, so good.
The problem arrives when trying to binary serialize these kind of objects, since this shared field is nos being properly stored and returns to its default value when deserializing.
I suppose this is the expected behaviour, so my question is... how can I make a shared field persistent?
I have read some comments to similar questions that say that this is a bad design, but it really makes sense (AFAIK) in my case, since this variable should be the same to all the object, but can be changed by the user and therefore should be stored.
Can you suggest another way of doing it?
Thanks!
EDIT: (sorry, I was in a hurry and couldn't complete my question until now)
My Class looks like this:
Public MustInherit Class NitrogenController
Private _active As Boolean
Private Shared _controlInterval As TimeSpan
Private _lastControlTime As Date
Public Property Active() As Boolean
Public Shared Property ControlInterval() As System.TimeSpan
'other properies that must be persisted
Public Function Control() As Boolean
If Not Now > _lastControlTime.Add(_controlInterval) Or Not _active Then
Return False
Else
DoControl()
_lastControlTime = Now
Return True
End If
End Function
End Class
So, the problem is that I can have several nitrogen controllers, but they should all have the same _controlInterval. That's the reason why I used a shared variable for this. But it does not preserve its value after serialization/deserialization. So... any ideas about how to do this?
Thanks!
I know that it is poor programming and architecture when you have a class object that is only to be used in one place. But I've also been warned about creating an object that is all powerful and that can do too much. So how do I break this down? Here is an example of what I mean - please don't take these things literal as this is only an example.
Anyway I have an object that I am working with which is rather complex. A lot of information is stored in this object and it can perform much manipulation on the data. So, let's call this object Earth.
Public Class Planet
Private _population As UInteger = 0
Public ReadOnly Property Population() As UInteger
Get
Return _population
End Get
End Property
Public Overridable Sub CreatePerson(Optional ByVal numberOfPeople As Integer = 1)
_population += numberOfPeople
End Sub
End Class
Simple enough so far. But I could go on and on with the many things that object could possibly perform. So, in order to keep things from getting too complex I broke down "activites" that would happen during the day and during the night by creating two other Objects: Day and Night (these two are not shown). So now I have an updated Planet class.
Public Class Planet
Private _population As UInteger = 0
Private _day As New Day
Private _night As New Night
Public ReadOnly Property Day() As Day
Get
Return _day
End Get
End Property
Public ReadOnly Property Night() As Night
Get
Return _night
End Get
End Property
Public ReadOnly Property Population() As UInteger
Get
Return _population
End Get
End Property
Public Overridable Sub CreatePerson(Optional ByVal numberOfPeople As Integer = 1)
_population += numberOfPeople
End Sub
End Class
Now, these two classes - Day and Night - will never be used outside of the Planet class. Is this a good way to organize my methods and attributes for this "parent" class Planet? How else would I neatly organize similar?
I've read about refactoring but I don't think this helps my case. I like the idea that I can call on an Planet object like this: Earth.Night.BlowUpMoon.
Think in terms of discoverability. If someone else were to use your object would they know that they have to go to a specific time of day to blow up the moon, which is the same as BirthdayCard.September25th.Send()? Any by "someone else" I also include you in 6 months. Are you organizing for the sake of organizing or are you putting similar methods and properties together in a way that makes sense?
Although your example is contrived, this situation is common practive in Domain Driven Design. Your Planet class would be an aggregate - a root object that manages its own internal entities. Outside the aggregate boundary all interaction is via the root aggregate object.
Refactor your class and split it to several smaller classes, each with a single responsibility. It doesn't matter that each of them will only be used once - the code will still be better, easier to understand, and far more testable.