I like to write many small getter properties that describe exactly what they mean.
However this can lead to repeated, expensive calculations.
Every way I know to avoid this makes the code less readable.
A pseudocode example:
ctor(decimal grossAmount, taxRateCalculator, itemCategory)
{
// store the ctor args as member variables
}
public decimal GrossAmount { get { return _grossAmount, } }
private decimal TaxRate { get { return _taxRateCalculater.GetTaxRateFor(_itemCategory); } } // expensive calculation
public decimal TaxAmount { get { return GrossAmount * TaxRate; } }
public decimal NetAmount { get { return GrossAmount - TaxAmount; } }
In this example it is very obvious what each of the properties do because they are simple accessors. TaxRate has been refactored into its own property so that it too, is obvious what it does. If the _taxRateCalculator operation is very expensive, how can I avoid repeated execution without junking up the code?
In my real scenario I might have ten fields that would need to be treated this way, so ten sets of _backing or Lazy fields would be ugly.
Cache the value
private decimal? _taxRate = null;
...
private decimal TaxRate
{
get
{
if (!this._taxRate.HasValue) {
this._taxRate = _taxRateCalculator.GetTaxRateFor(_itemCategory);
}
return this._taxRate.Value;
}
}
You could create a method which will recalculate your values every time you call here.
The advatage of this solution is
you can recalculate your Properties manually
you can implement some sort of Eventlistner which could easy call your recalculation anytime something happends
.
ctor(decimal grossAmount, taxRateCalculator, itemCategory)
{
// store the ctor args as member variables
recalculate();
}
public decimal GrossAmount { get; private set; }
public decimal TaxAmount { get; private set; }
public decimal NetAmount { get; private set; }
public void recalculate();
{
// expensive calculation
var _taxRate = _taxRateCalculater.GetTaxRateFor(_itemCategory);
GrossAmount = grossAmount;
TaxAmount = GrossAmount * _taxRate ;
NetAmount = GrossAmount - _taxRate;
}
Profile. Find out where the application is spending most of the time, and you'll have places to improve. Focus on the worst offenders, there's no point in performance optimizing something unless it has significant impact on the user experience.
When you identify the hotspots, you've got a decision to make - is the optimization worth the costs? If it is, go ahead. Having a backing field to store an expensive calculation is quite a standard way of avoiding repeated expensive calculations. Just make sure to only apply it where it matters, to keep the code simple.
This really is a common practice, and as long as you make sure you're consistent (e.g. if some change could change the tax rate, you'd want to invalidate the stored value to make sure it gets recalculated), you're going to be fine. Just make sure you're fixing a real performance problem, rather than just going after some performance ideal =)
I don’t think there is a way. You want to cache data without a cache. You could build caching functionality into your GetTaxRateFor(…) Method, but I doubt that this is the only expensive method you call.
So the shortest way would be a BackingField. What I usually do is this:
private decimal? _backingField;
public decimal Property { get { return _backingField ?? (_backingField = expensiveMethode()).Value; } }
Related
I'm migrating a legacy application from C to C# (.NET Core 5), and implementing more modern software development practices. The C application had literally all of its data in structures in RAM, all of which were globally available. This is great for simple applications but violates the heck out of the principle of encapsulation. The closest equivalent of doing this in an object-oriented fashion is to make the datastore static (which I don't want to do, for obvious reasons).
The application at hand is highly technical and involves a great deal of math. The previous application calculated a lot of derived values (sometimes repeatedly!) on demand, however this doesn't take advantage of multi-threading or caching.
To demonstrate a simpler yet analogous example, let's say we have a program to manage the costs associated with a baseball team. A team has its own fixed operating costs, as well as one manager (who has a salary), and zero to many players (who also each have salaries).
This is my redesigned data model:
public class Team {
public int Costs { get; set; }
public Manager Manager { get; set; }
public HashSet<Player> Players { get; set; }
private int _operatingCosts;
public int OperatingCosts {
get {
return this._operatingCosts;
}
private set {
// Note the private setter -- this should only be recalculated within this
// method from its own values.
this._operatingCosts = value;
}
}
}
public class Manager {
public string Name { get; set; }
public int Salary { get; set; }
}
public class Player {
public string Name { get; set; }
public int Salary { get; set; }
}
The C code would have a function that runs and puts its fingers in all of the arrays, finds the appropriate elements, and adds them up. In the rewritten C# code, MOST of these calculations are reasonably simple, so they probably are best implemented as read-only calculated properties.
public class Manager {
public int MonthlySalary {
get {
return this.Salary / 12;
}
}
}
The challenge comes when trying to calculate the total cost of running the team. This might be a complex operation that I don't want to have to run each time, so I'll want to cache a value and only recalculate it when an event fires. We know which variables cause the change, so we can fire the event from within the dependent properties' setters.
public class Team : INotifyPropertyChanged {
private int _costs;
public int Costs {
get {
return this._costs;
}
set {
this._costs = value;
NotifyPropertyChanged(); // Fire recalculation on cost change.
}
}
public int Name {
get; set; // No INotifyPropertyChanged needed; cached values aren't
// dependent on this.
}
private int _totalOperatingCost;
public int TotalOperatingCost {
get {
return this._totalOperatingCost;
}
private set {
this._totalOperatingCost = value;
}
}
protected void RecalculateCosts() {
this._totalOperatingCost = this.Team.Cost + this.Manager.Salary + this.Players.Sum(p => p.Salary);
}
}
This has been working really well with INotifyPropertyChanged -- I fire a PropertyChanged event on fields that should trigger a recalculation, and the recalculation logic is there and in one place, and all is well.
Now here's the problem: what happens if the manager's salary changes?
public class Manager : INotifyPropertyChanged {
private int _salary;
public int Salary {
get {
return this._salary;
}
set {
this._salary = value;
NotifyParentPropertyChanged();
}
}
}
The Manager class does not contain a reference to the Team to which he belongs. There's a lot of potential for error retaining a backreference from the child bean to the parent when the parent knows about its own children. So if I call NotifyPropertyChanged() here, the Manager will update his own calculations but it has no idea it needs to update on the parent. This is also mostly resolvable using events, but there's a big hitch:
public class Team {
public string Name { ... }
private Manager _manager;
public Manager Manager {
get {
return this._manager;
}
set {
if (this._manager is not null) {
this._manager.PropertyChanged -= ProcessParentPropertyChangedEvent;
}
this._manager = value;
NotifyPropertyChanged();
if (this._manager is not null) {
this._manager.PropertyChanged += ProcessParentPropertyChangedEvent;
}
}
}
public Team() {
if (this.Manager is not null) {
this.Manager.PropertyChanged += ProcessParentPropertyChangedEvent;
}
}
public static void ProcessParentPropertyChangedEvent(object sender, EventArgs e) {
// ^^^^^^ THIS IS A STATIC METHOD, so "this" is unavailable.
//
// When called from Manager.Salary, sender.GetType().Name = "Manager" and
// e can ONLY carry information from the Manager and knows nothing about
// the Team.
//
// Literally nothing in this method knows about the current team, or I believe
// can know about the team to which the manager belongs.
}
}
public class Manager {
private int _salary;
public int Salary {
get {
return this._salary;
}
set {
this._salary = value;
NotifyParentPropertyChanged();
}
}
}
The event fires properly but because the callback method is static, there's no link to the Team whose Manager's salary just updated. Player would have a similar problem, there's no way to inform the Team class that a Player's salary updated since the recalculation would take place within a static method.
Similarly, we could need to add or subtract players from the team as well, which should also force a recalculation of our team costs. I've gone down this road some with INotifyCollectionChanged, but no luck -- we still end up in a static method with no information about where the changes need to be applied to.
I believe my options are as follows:
(1) Include backreferences to parent elements. This seems somewhat straightforward, but there is a lot that can go wrong here, and garbage collection may be one of them. There are probably going to be about a million elements in memory, and I'm not sure how well this would perform by everything basically being in a doubly-connected graph.
(2) I've looked into the Mediator pattern, but I'm not convinced this still solves my problems without a great deal of error-prone accounting. It also requires the Mediator class to be injected into all of my data elements, and requires me to use extensions for base .NET generic collections types -- I don't want to be forced to always use custom types like MyPlayersList or similar, instead of the more common List<Player> -- especially when NOT using the custom list would likely end in a subtle and silent bug when a recalculation just didn't quite pull the right values.
What are my options? Am I forced to carry tons of backreferences throughout the model?
Is there a different model for event handling that I'm not aware of? I've been working with INotifyPropertyChanged because I'm used to it from a WPF context and it's really fast -- 1,000,000 calls in 60 ms on my machine. That said I don't know if there are any other event handling paradigms that exist to handle this type of case.
This seems like way too straightforward an issue to not have appeared and been solved by someone else before. Thanks so much!
I have a class that looks like this:
public class House
{
public string Address {get; set;}
private int _numberOfBedrooms;
public int NumberOfBedrooms
{
get { return _numberOfBedrooms; }
set
{
_numberOfBedrooms = value;
_groundPlanIsObsolete |= true;
}
}
private int _numberOfBathrooms;
public int NumberOfBathrooms
{
get { return _numberOfBathrooms; }
set
{
_numberOfBathrooms = value;
_groundPlanIsObsolete |= true;
}
}
private bool _groundPlanIsObsolete;
private myFloorPlan _groundPlan;
public myFloorPlan GroundPlan
{ get
{
if(_groundPlanIsObsolete)
_groundPlan = new myFloorPlan(NumberOfBedrooms, NumberOfBathrooms);
_groundPlanIsObsolete &= false;
return _groundPlan;
}
}
}
new myFloorPlan(NumberOfBedrooms, NumberOfBathrooms) is a very lengthy function.
I want to call it as rarely as possible.
Is this bad design?
I don't like my current design, because from a user point of view, it is not clear, which properties will have an effect on GroundPlan.
This has two disadvantages:
If one of them is not set, and the user tries to get the GroundPlan I could throw an exception, but is there a "nicer" way to let him know before he makes the mistake?
I would like to encourage the user to make up his mind about the number of rooms before calling the GroundPlan, to prevent frequent computationally heavy updates.
Should I indicate this?
Or is this something that should be documented in the comment section of the properties?
And:
How could I indicate this?
Make House immutable and use proper encapsulation.
You can combine immutability with fluent syntax easily in C# to build your object:
House house = new House();
house = house.AddBedrooms(2);
Code for House:
class House
{
int _numberOfBedrooms;
public House()
{
}
public House AddBedrooms(int numberOfBedroomsToAdd)
{
House house = new House();
house._numberOfBedrooms = _numberOfBedrooms + numberOfBedroomsToAdd;
return house;
}
//etc...
}
It's a bit more work, but it provides proper encapsulation. Putting getters/setters on domain objects is nasty. There are more advanced patterns which split the building of the object into a builder but the principle is the same. You could then use fluent syntax on your builder.
I would like to encourage the user to make up his mind about the number of rooms before calling the GroundPlan, to prevent frequent computationally heavy updates.
I would recommend passing NumberOfBathrooms and NumberOfBedrooms through as parameters on the method, that way it's clear to the user what the dependencies are. Or, if you want to keep them as properties perhaps pass them through on the constructor and make the properties read only.
UPDATE
The main questions remain the ones
under the example, but I guess it boils down
to :
**If you have a type where 99% of the values could be represented in one
fast, powerfull type, and only 1% in a
very heavy type, (say int vs.
BigInteger) How to represent it?? **
A school we learned a lot about internal representations, but never how to change it at runtime. I mean : suppose you have a class representing a decimal, but you use an integer to represent it internal, until you actually need a bigger value than the integer, and only than change representation...
I never thought of this before, and when thinkihng of it, I thought that would never work, since all the checks would kill it. But I just did a test since I'm too curious for my own good and there do exist situations when changing of representation is more perormant : given this interface :
interface INumber
{
void add1000();
void SetValue(decimal d);
decimal GetValue();
}
I found the latter of the two implementations to be more powerful in a lot of situations, including this one that I composed to attract as many ideas I could on the matter (not rep, it's community)
1. Representation by only a decimal
public class Number1:INumber
{
private decimal d { get; set; }
public void add1000()
{
d += 1000;
}
public decimal GetValue()
{
return d;
}
public void SetValue(decimal d)
{
this.d = d;
}
}
2. Representation by a decimal and an int
public class Number2:INumber
{
private bool usedecimal;
private int i;
private decimal d;
public void add1000()
{
if (usedecimal)
{
d += 1000;
return;
}
i += 1000;
if (i > 2147480000)
{
d = i;
usedecimal = true;
}
}
public void SetValue(decimal d)
{
try
{
i = (int)d;
}
catch (OverflowException e)
{
this.d = d;
}
}
public decimal GetValue()
{
return Math.Max(i,d);
}
}
}
My question is the following :
This seems sth. I have been missing, but this must be the bleeding obvious. Can anyone help me out with this?
Are there guidelines for mixed representations, when to use them, when not?
How to have a hunch when a mixed represtenation can be faster without benchmarking?
Any examples?
Any patterns?
Any ideas on the matter?
If you have a type where 99% of the values could be represented in one fast, powerfull type, and only 1% in a very heavy type, (say int vs. BigInteger) How to represent it??
BigInteger implementations typically do exactly that; they keep everything in ints or longs until something overflows, and only then do they go to the heavierweight implementation.
There's any number of ways to represent it. A pattern I like is:
public abstract class Thing
{
private class LightThing : Thing
{ ... }
private class HeavyThing : Thing
{ ... }
public static Thing MakeThing(whatever)
{ /* make a heavy or light thing, depending */ }
... etc ...
}
Are there guidelines for mixed representations, when to use them, when not?
Sure. We can easily compile such a list. This technique makes sense if:
(1) the lightweight implementation is much lighter than the heavyweight implementation
(2) the typical usage falls into the lightweight code path most of the time
(3) the cost of detecting the transition is not a significant cost compared to the cost of the heavyweight solution
(4) the more complex two-representation solution is necessary in order to achieve a customer-focused, realistic performance goal.
How to have a hunch when a mixed represtenation can be faster without benchmarking?
Don't. Making performance decisions based on hunches is reasoning in advance of facts. Drive performance decisions on realistic, customer focused, data-driven analysis, not on hunches. If I've learned one thing about performance analysis over the years its that my hunches are usually wrong.
Any examples?
Any number of implementations of BigInteger.
Any patterns?
Beats the heck out of me. I'm not much of one for memorizing pattern taxonomies.
Any ideas on the matter?
See above.
Perhaps you're looking for the Bridge pattern.
When working with Domain Objects, how do you typically unit test a method that calls another method in the object? For example:
public class Invoice
{
public IList<InvoiceLine> InvoiceLines;
public string Company;
public bool IsDiscounted;
public DateTime InvoiceDate;
//...
public GetTotalAmt();
public GetExtendedTotalAmt();
public decimal GetTotalAmt()
{
decimal total;
foreach (InvoiceLine il in InvoiceLines)
{
total += il.Qty * il.Price;
}
return total;
}
public decimal GetExtendedTotalAmt()
{
decimal discount;
if (IsDiscounted)
discount = .05M;
return GetTotalAmt() * discount;
}
}
Unit testing GetTotalAmt() is easy, but with GetExtendedTotalAmt() I'd have to use stub/mock InvoiceLine objects to make it work, when all I really want to do is test that a discount is applied if the IsDiscounted flag is true.
How do other people handle this? I don't think it makes sense to split up the domain object since these methods are both considered part of the core Invoice functionality (and splitting it would likely cause developers to call the wrong method more often).
Thanks!
You could make the GetTotalAmt method virtual and then:
var sut = new MockRepository().PartialMock<Invoice>();
sut.Expect(x => x.GetTotalAmt()).Return(10);
sut.Replay();
var result = sut.GetExtendedTotalAmt();
I would build up a situation which is as simple as possible: only one InvoiceLine with a Quantity and Price of 1.
Something like this:
invoice.Add(new InvoiceLine(new Article("blah", 1M), 1));
Assert.AreEqual(0.95M, invoice.GetExtendedTotalAmt());
When you find that this stuff gets quite complicated, finding errors gets hard etc, then it is a sign that you should split the class (making the calculations on the invoice a strategy or something similar). But as long as it is as simple as you piece of code here, I wouldn't worry about it.
Trying to decipher an appropriate OO design to implement. The basic scenario is that you have a PstnNumber which is essentially a 10 digit phone number that always starts with 0 (e.g. 0195550000). A rule has been introduced to allow auto-correcting of a number if the leading 0 is missing (e.g. 195550000).
START EDIT
I realised the original question may have been misunderstood (thankyou kindly to those whom have answered already), so I have edited to try and better explain the scenario.
END EDIT
I started playing with some preliminary concepts and then thought I would ask if there was a more appropriate way to go or do one of these suffice (on some level)?
Concept 1
public class PstnNumber
{
public virtual string Number { get; set; }
public PstnNumber() { }
public PstnNumber(string number)
{
this.Number = number;
}
}
public class AutoFormattedPstnNumber : PstnNumber
{
public override string Number
{
get { return base.Number; }
set { base.Number = value.PadLeft(10, '0'); }
}
public AutoFormattedPstnNumber() : base() { }
public AutoFormattedPstnNumber(string number)
{
this.Number = number;
}
}
Concept 2 (removed)
Concept 3
public class PstnNumber
{
public bool AutoCorrect { get; set; }
private string number;
public virtual string Number
{
get { return (this.AutoCorrect) ? this.number.PadLeft(10, '0') : this.number; }
set { this.number = value; }
}
public PstnNumber() : this(false) { }
public PstnNumber(bool autoCorrect)
{
this.AutoCorrect = autoCorrect;
}
public PstnNumber(string number) : this(false)
{
this.Number = number;
}
public PstnNumber(string number, bool autoCorrect) : this(autoCorrect)
{
this.Number = number;
}
}
I think Concept 1 may violate the Liskov Substitution rule because the subclass changes the behaviour of the Number property (happy to learn if I've misunderstood that).
Any alternative suggestions would be received happily.
do you have to do the autoformatting when the object is instantiated? If not,
what about:
public class PstnNumber
{
public virtual string Number { get; set; }
public PstnNumber() { }
public PstnNumber(string number) { this.Number = number; }
public AutoFormatNumber { get { return Numer.PadLeft(10, '0'); } }
}
avoid getter-setter-surprise
Avoid getters returning a different value than the one accepted by the setter. Imagine the following snippet:
if (input.Value != current.Number)
{
NumberChangedAgain = true;
current.Number = input.Value;
}
A simple solution would be to make PstnNumber immutable:
temp = PstnNumber.FromString(input.Value);
if (temp != current) { ... }
canonical format
If some data has different representations, there is a lot of advantage to storing it in a canonical representation, and move the format conversions to factory functions and getters / formatters. For example, you don't need to test comparison for short vs. long, long vs. short, short vs. short, long vs. long.
different aspects
Do you need the distinction between an "autoformatted" and a "normal" number, or is this merely a question of input and output - i.e.
does display format (short or long) depend on how the number was entered, or on where it is displayed?
is 0195550000 == 195550000 ?
I'd prefer to fold both classes into one if possible (i.e. when "entered with or without 0 can be forgotten"):
public class PstnNumber
{
private string m_number; // always in long format
public static PstnNumber(string s) { ... } // accepts short and long form
public string Number { get { return m_number; } }
public string AutoFormatted { { get { ... } }
}
Otherwise I'd go with Option 3, but always store the long format in m_number.
In Option 1 and Option 2, you aren't preserving the original number anyway, rendering the subclass worthless (except to know that it was autoformatted at some point, which doesn't seem like useful information). The alternative to make these Options more useful would be to format on Get instead of Set.
Option 3 is therefore the preferred pattern out of these three options, but I would also ask - why can't the PstnNumber also simply detect the number of digits, and autoformat accordingly?
If you follow the rules - there is one that says that "each routine (read class) should do only one thing and do it well".
According to that I would make PstnNumber just hold the number, and create some sort of factory that produces the right number.
Doing both in the same class means that you are weaving domain logic and representation. I prefer them separated.
I'd ask why your class name is so cryptic. "Number" is clear to me, and "P" suggests "phone", but what's the "stn" telling me? A few extra keystrokes would make this class more self-documenting.
I'd also ask about the logic of a default constructor that does not initialize the underlying data members to some value. I think a default constructor should have a sensible default value if possible.
I feel like option 1 is overkill. I don't think inheritance is making this model clearer or better. I don't see how it breaks Liskov substitution, which demands that you can use the subclass in any situation that calls for a base class. The methods map 1:1 as far as I can see. How is Liskov violated?
Option 2 says these are two separate classes with no relationship. That doesn't seem right to me.
All this work suggests that your problem will require that you use both classes. You'll have situations where the leading zero is NOT required and others where it is. Is that true? Or are you always going to require the leading zero?
I don't care for any of your options. I'd prefer an interface or a static factory or even modifying the class you have to anything you've suggested. It feels like a mere formatting issue. Do you store the number with the leading zero? If not, maybe it's just a view concern.
Do you have a really strong reason to have a setter and not have your members final? If not, that's probably a bigger problem than any other variation between the three.
So I'd go for a stateless #3 which means making the number final and gettng rid of the autoFormat variable.
For simplicity I'd just have a getNumberRaw and getNumberFormatted
Better yet, you could have getNumberRaw and getNumber(formatType) where formatType actually contains the code that formats the number since the format may change again in the future and combining formatting (view) with your phone number (model) isn't optimal.
(PS/EDIT): just the fact that a phone number can change is NOT a good reason to have a setter! Creating a new phone number object and replacing the old one will almost always work!
I am not familiar with c#, but I'd do this:
public class PstnNumber {
readonly string number;
public PstnNumber(string number) {
this.number = number;
}
public string getNumber() {
return number;
}
static public PstnNumber createNumber(string number) {
return new PstnNumber(number.PadLeft(10, '0'));
}
}
Of course if I knew how Properties work, I'd probably do it differently :)
I would go with a much simpler version, overriding the ToString method, or even, creating an ToString overload that receives the bool parameter indicating that the number should be formatted.