I'm trying to find a design pattern or a best practice, or some other solution for a problem with keeping back versions of business logic within my application. Specifically, I am looking to find a way to determine which logic was used to issue an insurance policy.
I currently have code which looks like this:
public double FixedDeductibleSurchageAmount()
{
double percent = FixedDeductibleSurchargePercent();
double base_premium = CollisionPremium() + TheftPremium();
return (base_premium * percent);
}
I am needing to make a change to the business logic so that this function looks more like:
public double FixedDeductibleSurchageAmount()
{
double percent = FixedDeductibleSurchargePercent();
double base_premium = CollisionPremium() + TheftPremium() + MedicalPremium();
return (base_premium * percent);
}
Where I run into trouble is that existing policies should rate with the previous logic. Is there a design pattern for this? If not, are there any good ways to implement it?
Strategy pattern sounds most applicable. Probably you'd need a factory method or some such that takes in a date to return the appropriate strategy.
You're going to have to use additional data of some form to keep track of precisely what algorithm was used to obtain your data; you'll probably need to change your persistence representation to maintain versioning information about the algorithm used to derive your results.
BTW, you might consider making things like MedicalPremium or TheftPremium a Get-only property, rather than a parameterless function. They fit that paradigm very well.
There are any number of ways you can solve this problem. Some examples:
1) Switch to the new code and add a flag to the user data so that MedicalPremium automatically returns 0 for old users. This is particularly easy if you stored your data in XML; the old data just won't have the flag, and it won't affect your deserialization of the data because XML is flexible.
2) Make the class that contains your function MedicalPremium a base class, and make MedicalPremium virtual. Override it in the derived class, which is your new version. Newer users are the derived class. Old users are created as the base class. For the old users, it always returns 0. Properties can also be virtual just as functions can.
If you have a chance to look at Martin Fowler's Patterns of Enterprise Architecture he talks about individual instance methods, which isn't entirely the same as what you have, but is very similar. It's a great book in any case.
In the meantime, I think you might have to start considering your functions as also being data, and store in your database which function was used. You don't need (but may want) to store the function text, but you do need enough information to determine at run time which method to call. You asked about patterns, and obviously you have a strategy pattern going on here, which you could reference, but I don't know if it will be especially helpful.
Yes there is: the Decorator Pattern. You can use this to extend the behavior of a class with additional wrapper classes. In the example below I combine this with the Template Method Pattern to achieve what I believe you are looking for.
public class BaseSurchargePolicy {
protected abstract double BasePremium { get; }
protected abstract double FixedDeductibleSurchargePercent { get; }
public double FixedDeductibleSurchageAmount{
get
{
return (BasePremium * FixedDeductibleSurchargePercent);
}
}
protected ICollection<string> _ProcessorsUsed;
public IEnumerable<string> ProcessorsUsed
{
get { return ProcessorsUsed; }
}
}
public class OldSurchargePolicy : BaseSurchargePolicy
{
protected double BasePremium
{
_ProcessorsUsed.Add(GetType().Name);
return CollisionPremium + TheftPremium;
}
protected double FixedDeductibleSurchargePercent { get; set; }
public double CollisionPremium { get; set; }
public double TheftPremium { get; set; }
}
public class MedicalSurchargeDecorator: BaseSurchargePolicy
{
private BaseSurchargePolicy _wrapped;
private double _medicalPremium;
public MedicalSurchargeDecorator(BaseSurchargePolicy wrapped, double medicalPremium)
{
_wrapped = wrapped;
_medicalPremium = medicalPremium;
}
protected double BasePremium
{
get
{
_ProcessorsUsed.Add(GetType().Name);
return _wrapped.BasePremium + _medicalPremium;
}
}
protected double FixedDeductibleSurchargePercent {
get { return _wrapped.FixedDeductibleSurchargePercent }
}
}
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have a method that is exposed using interface in the business logic layer. It is as follows:
public interface IMyWorkingClass
{
IEnumerable<dynamic> GetSomeList();
}
public class MyWorkingClass : IMyWorkingClass
{
public IEnumerable<dynamic> GetSomeList()
{
dynamic foos = new List<dynamic>();
dynamic item = new ExpandoObject();
item.PropOne = (new Foo()).FooPropertyOne;
item.PropTwo = (new Bar()).BarPropertyOne;
foos.Add(item);
return foos;
}
}
public class Foo
{
public int FooId{get;set;}
public string FooPropertyOne{get;set;}
public string FooPropertyTwo{get;set;}
}
public class Bar
{
public int BarId{get;set;}
public string BarPropertyOne{get;set;}
public string BarPropertyTwo{get;set;}
}
There are a lot of different opinions/preferences out there about dynamic itself. I find them useful. One of my friends said dynamics are good but the way they are used above are not. The argument presented was that the compiler wont catch the things changed on dynamic object. I think the unit tests will be able to catch those. So I disagreed. What is your expert opinion? Thanks in advance :)
Update
Here's bit clearer (hopefully) code:
public interface IMyWorkingClass
{
IEnumerable<dynamic> GetListOfClassesForStudentDynamicReturn();
IEnumerable<StudentClassInfo> GetListOfClassesForStudentStaticReturn();
}
public class MyWorkingClass : IMyWorkingClass
{
public IEnumerable<dynamic> GetListOfClassesForStudentDynamicReturn(Student student)
{
dynamic listOfClasses = new List<dynamic>();
// repository pattern is used in DAL
var datafromDB = (StudentCollegeClassRepo.GetQueryable(x=>x.StudentId==student.StudentId)
.select(item => new {
item.CollegeClassId
,item.CollegeClass.CollegeClassName
,item.IsEnabledForStudent
}).ToList();
foreach (var item in datafromDB)
{
dynamic classWithStudent = new ExpandoObject();
classWithStudent.CollegeClassId = item.CollegeClassId;
classWithStudent.CollegeClassName = item.CollegeClassName;
classWithStudent.IsEnabledForStudent = item.IsEnabledForStudent;
listOfClasses.Add(studentWithClass);
}
return listOfClasses;
}
public IEnumerable<StudentClassInfo> GetListOfClassesForStudentStaticReturn(Student student)
{
// repository pattern is used in DAL
var datafromDB = (StudentCollegeClassRepo.GetQueryable(x=>x.StudentId==student.StudentId)
.select(item => new StudentClassInfo {
CollegeClassId = item.CollegeClassId
,CollegeClassName = item.CollegeClass.CollegeClassName
,IsEnabledForStudent = item.IsEnabledForStudent
}).ToList();
return datafromDB;
}
}
// this class is like a viewmodel
public class StudentClassInfo
{
public int CollegeClassId { get; set; }
public string CollegeClassName { get; set; }
public bool IsEnabledForStudent { get; set; }
}
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
}
public class StudentCollegeClass
{
public int StudentId { get; set; }
public int CollegeClassId { get; set; }
public bool IsEnabledForStudent { get; set; }
}
public class CollegeClass
{
public int CollegeClassId { get; set; }
public string CollegeClassName { get; set; }
}
Hopefully I made things little clearer now. So,method with dynamic return is ok or create a static type and have that returned instead? I am also learning how to ask question properly here.. Thanks for your patience and awesome replies :)
Despite what Skeet says :) I'll add some thoughts here.
If you start down the path of using Dynamics, you must shift your thinking. You don't know what your object is, you only care about what it can do.
You find yourself not needing interfaces rather quickly - and then you ask yourself "WTF am I doing anyway?". Which is always a great question to ask.
And then a shift happens as you start writing more tests to cover up the loss of a compiler check - you start writing methods a bit more clearly. You start relying on Factories and other classes to impose logic on top of these little bits of amorphous dynamic goo.
It's incredibly freeing if you consider the mental shift. For instance you have a "MyWorkingClass" that does something on top of Foo/Bar. If that was a fulfillment class called "Warehouse" that had some methods called "CheckInvetoryOf(dynamic item)" - things start to make a bit more sense.
In the real world you would send in an interface here - probably ITrackable or something - that exposes a very very small subset of what could be used. It would work, but what if you changed your approach later and wanted the Warehouse to ship digital goods - something like downloads?
Your Warehouse class was probably fashioned after a brick and mortar - and making the shift to sending out digital downloads... OH NO!
But if you use dynamics - it's easy. You could simply ask if the item has is an IDigitalGood (for instance) and handle it nicely.
So - the code you wrote is, yes, confusing. If you spend some time with Dynamic languages it will afford you the mental shift to make it not so confusing.
Oh - in terms of "Architecturally Wrong" to do what you did... who knows. If it's confusing, that's not good. If it makes testing hard - that's triple not good. If you get laughed at, you might be on the right track :)
So, you want to create an interface that expose a method that return an unknown IEnumerable? Is there a direct advantage in using the generic version of IEnumerble in this case beside saving some cast/test/overload that you would have to do anyway if you want to use those objects after the method is returned?
While I won't dispute that dynamic can be useful in some case. In my opinion, it often displays a design flaw. Every time I came to use it, I actually sat down and thought if I really needed it. And most of the time, I came to the conclusion that with some simple changes, I could eliminate it and make a cleaner design.
In this case, do you truly need to have a generic type with dynamic? My first and quick guess would be, you can probably use the non-generic IEnumerable.
Or if you want to save some casting, and you have different elements in there, you can find common ground to all element. I see that right now, all your property are string. Or if you want to return combination of elements, you can use some Tuple<>
If you truly end up returning a complete unknown types of lot of different objects, you could use IEnumerable<object>, but then I would question the reason of existence of that interface implementation. I don't remember ever creating an interface that would return object with absolutely any kind of common ground between the different implementation, or even within a single implementation. It could controls, numbers, components, entities... But they tend to share something. If it's properties, you could even pack in some PropertyInfo!
TL:DR; Unless you can present a very clear case where this design pattern would serve a very specific purpose that is unavoidable by any other means, I would recommend not using it. My IEnumerable of 2 cents.
Update
I have a RiskReport type, which gets data from IReportRepository, manipulates the data, and calculates risk according to predefined formula.
One might argument that the RiskReport type should get the data in exact format and not perform the data manipulation. RiskReport should be only concerned with how to calculate data according to formula, Whereas IReportRepository should only return the data required by RiskReport class.
Should a new class be introduced between IReportRepository and RiskReport? Because, currently, the data returned from IReportRepository is manipulated to the required format to calculate the risk.
class RiskReport
{
private IReportRepository reportRepository;
public RiskReport(IReportRepository reportRepository)
{
this.reportRepository = reportRepository;
}
public decimal CalculateDataBasedOnFormula()
{
var result = from d in reportRepository.GetReportRelatedData()
group d by d.Id into dgp //potentially complex grouping
select new
{
TotalPage = dgp.Sum(x=>x.Pages) //potentially complex projection
};
decimal risk= //use the result variable to calculate data based on complex formula not shown here
return risk;
}
}
interface IReportRepository
{
IEnumerable<ReportRelatedData> GetReportRelatedData();
}
public class ReportRepository: IReportRepository
{
public IEnumerable<ReportRelatedData> GetReportRelatedData()
{
//return data from underlying data source
return new BindingList<ReportRelatedData>();
}
}
public class ReportRelatedData
{
public int Id { get; set; }
public int Name { get; set; }
public int Pages { get; set; }
//... more properties here
}
Any idea would be appreciated!
I have a Report type, which gets data from IReportRepository, manipulates the data, and
calculates rate according to predefined formula.
I think the answer is in your first sentence. If you want the code to be good, make it SOLID. "S" stands for Single Responsibility Principle. In other words, if you describe what a class does, don't use the word "and". Change your design accordingly.
I think this is one of those questions where if you ask 1000 devs you could get 1000 answers, but yes, I would say that another class should be used. Here's my justification:
A "math"-ish class could be tested independently
A separate class could be reused, keeping the rest of your code DRY
If the formulas change, refactoring won't be nestled into your report code
If I had to inherit the code base, I would like to see three classes here, so that's what I would like to leave behind for the next dev if I was developing it.
Cheers.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am creating a role playing game for fun and as a learning experience. I am at the point where my character (a wizard) is cast spells. I am using a strategy pattern to set the spell they are going to cast before casting the spell. The reason I went with this approach is because I want to be able to add different spell types later on w/ out having to mess with the character/wizard class.
My question - is this a bad design? Is there a better/cleaner/easier approach for this?
I am trying to stay away from being "that guy" who tries to make everything fit into a design pattern. But in this case I feel like it's a decent fit.
Here is what my code looks like with 2 spells so far
public class Wizard : Creature
{
public List<Spell> Spells { get; set; }
public void Cast(Spell spell, Creature targetCreature)
{
spell.Cast(this, targetCreature);
}
}
public abstract class Spell
{
public string Name { get; set; }
public int ManaCost { get; set; }
public Spell(string name, int manaCost)
{
Name = name;
ManaCost = manaCost;
}
public void Cast(Creature caster, Creature targetCreature)
{
caster.SubtractMana(ManaCost);
ApplySpell(caster, targetCreature);
}
public abstract void ApplySpell(Creature caster, Creature targetCreature);
}
// increases the target's armor by 4
public class MageArmor : Spell
{
public MageArmor() : base("Mage Armor", 4);
public override void ApplySpell(caster, targetCreature)
{
targetCreature.AddAC(4);
}
}
// target takes 7 damage
public class FireBall : Spell
{
public FireBall() : base("Fire Ball", 5);
public override void ApplySpell(caster, targetCreature)
{
targetCreature.SubtractHealth(7);
}
}
now to cast a spell we do something like this:
Wizard wizard = new Wizard();
wizard.Cast(new Spell.MageArmor(), wizard); // i am buffing myself
UPDATE: updated code with some suggestions from the answers below
Following what Willcodejavaforfood said, you could design a SpellEffect class that describes a single effect your spell could have. You can create a "vocabulary" to use to describe:
Attributes for Spell:
Name
Mana cost
Target restriction of the whole spell (player, npc, monster,...)
Total duration of spell (highest of SpellEffect durations) (10 sec, 5 ticks,...)
Casting time
Spell range (5 meters, 65 units, ...)
Fail rate (5%, 90%)
Time to wait before this spell can be cast again (Recast time)
Time to wait before ANY spell can be cast again (Recovery time)
etc...
Attributes for SpellEffect:
Type of effect (defense, offense, buff, debuff,...)
Target of effect (self, party, target, area around target, line to target,...)
Property or stat the effect acts on (hp, mana, max hp, strength, attack speed,...)
How much the effect changes the stat (+10, -500, 5%,...)
How long the effect lasts (10 sec, 5 ticks,...)
etc.
I would imagine that your vocabulary (the words in parentheses above) would be defined in a set of enums. It might also be advisable to create a class hierarchy to represent the SpellEffect types, instead of using an enum for that particular attribute, because there might be a SpellEffect type that doesn't need all these attributes or perhaps there's some kind of custom logic for each basic SpellEffect type that I'm not thinking about. But that also might complicate things too much. KISS principle =).
Anyway, the point is that you are pulling out the specific information on a Spell's effect into a separate data structure. The beauty of this is that you can create 1 Spell class and make it hold a List of SpellEffects to apply upon activation. Then the spell can perform multiple functions (damage enemy and heal player, aka life tap) in one shot. You create a new instance of Spell for each spell. Of course, at some point you will have to actually create the spells. You could easily throw together a spell editor utility to make that easier.
Furthermore, each SpellEffect you define can very easily be written to and loaded from XML by using System.Xml.Serialization's XmlSerializer class. It's a breeze to use on simple data classes like SpellEffect. You can even just serialize your final List of Spell to xml too. For example:
<?xml header-blah-blah?>
<Spells>
<Spell Name="Light Healing" Restriction="Player" Cost="100" Duration="0s"
CastTime="2s" Range="0" FailRate="5%" Recast="10s" Recovery="5s">
<SpellEffect Type="Heal" Target="Self" Stat="Hp" Degree="500" Duration="0s"/>
</Spell>
<Spell Name="Steal Haste" Restriction="NPC" Cost="500" Duration="120s"
CastTime="10s" Range="100" FailRate="10%" Recast="15s" Recovery="8s">
<SpellEffect Type="Buff" Target="Self" Stat="AttackSpeed" Degree="20%" Duration="120s"/>
<SpellEffect Type="Debuff" Target="Target" Stat="AttackSpeed" Degree="-20%" Duration="60s"/>
</Spell>
...
</Spells>
You could also chose to put your data in a database instead of xml. Sqlite would be small, fast, easy, and free. You can also use LINQ to query your spell data from xml or sqlite.
Of course, you could do something similar for your monsters and such, too--at least for their data. I'm not sure about the logic part.
If you use this kind of system, you can get the added benefit of being able to use your Creature/Spell system for other games. You can't do that if you "hard code" your spells. It will also allow you to change the spells (class balancing, bugs, whatever) without having to rebuild and redistribute your game executable. Just a simple xml file.
Holy cow! I'm really excited about your project now and how something like I described could be implemented. If you need any help, let me know!!
It's not particularly clear why you'd want it to be a two stage process unless that's going to be exposed in the UI (i.e. if the user will set the "loaded spell" and can later change their mind).
Additionally, if you are going to have a property rather than just wizard.Cast(new Spell.MageArmor(), wizard), having a SetSpell method is a bit odd - why not just make the LoadedSpell property public?
Finally, do spells actually have any mutable state? Could you just have a fixed set of instances (flyweight/enum pattern)? I'm not thinking of the memory usage here (which is the normal reason for the flyweight pattern) but just the conceptual nature of it. It feels like you want something which is really just like a Java enum - a set of values with custom behaviour. It's harder to do that in C# because there's no direct language support, but it's still possible.
The actual pattern within the spell (having a caster and a target) seems reasonable, although you may find it becomes inflexible if you want to be able to have area effect spells (with a target location rather than a specific creature) or spells which curse/bless items etc. You may also need to pass in the rest of the state of the game world - e.g. if you have a spell to create minions.
I probably would not use subclassing for each spell here. I would try and put it on disk by using XML or JSON and create them dynamically.
--Edit to clarify (hopefully)--
This approach would require to really plan out in advance as much as possible. You would have to defined attributes as:
Name
Description
Duration
Target (self, area, other)
Type (bonus, damage, curse)
Effect (ex: 1d6 frost damage, +2 Armor Class, -5 Damage Resistance)
Wrapping all this behaviour in a generic spell class should make it really flexible and more straight forward to test.
It's natural to encapsulate "Spells" with the Command Pattern (which is basically what you've done). But you run into two problems:-
1) You've got to recompile to add more spells
You can enumerate every possible
action it is possible for a spell to
take, then define the spells in some
external format (XML, Database) which
gets loaded into your application on
startup. Western RPGs tend to be coded like
this - a "spell" consists of "Apply
spell effect #1234 with parameter 1000",
"play animation #2345", etc.
You can expose your gamestate to a scripting
language, and script your spells (you can also
combine this with the first idea so that in most
cases your scripted spells are just calling pre-defined effects in code). Duel of the Planeswalkers
(the M:TG game on X-Box 360) was written broadly with
this approach
Or you can just live with it (I do...)
2) What happens when your spell target isn't a creature?
If you're exposing your gamestate to your spell scripts, this isn't a problem because your scripts can do anything they like within the context of what you're exposing.
Otherwise, you'd be best making a generic type.
I generally do something like the following (and not just in games either, I've been using this kind of pattern to represent behaviours in mutli-agent-systems):-
public interface IEffect<TContext>
{
public void Apply(TContext context);
}
public class SingleTargetContext
{
public Creature Target { get; set; }
}
public class AoEContext
{
public Point Target { get; set; }
}
// etc.
The advantage of this pattern is that it's really flexible for doing those "odd" things that you'd often expect spells to be able to do that more fixed models won't be capable of. You can do things like chain them together. You can have an Effect which adds a TriggeredEffect to your target - good for doing something like a Thorns Aura. You can have an IReversibleEffect (with an extra Unapply method) good for representing buffs.
That article on Duel of the Planeswalkers is really excellent reading though. So good I'll link it twice!
For some reason, "spells" feel more like a command pattern to me. But I've never designed a game so...
The biggest problem I see with this pattern is that all spells have to remember to subtract their mana cost. How about:
public abstract class Spell
{
public string Name { get; set; }
public int ManaCost { get; set; }
public Spell(string name, int manaCost)
{
Name = name;
ManaCost = manaCost;
}
public void Cast(Creature caster, Creature targetCreature)
{
caster.SubtractMana(ManaCost); //might throw NotEnoughManaException?
ApplySpell(caster, targetCreature);
}
protected abstract void ApplySpell(Creature caster, Creature targetCreature);
}
Also, should Wizard extend PlayerCharacter, which would extend Creature?
I think your design looks fine. Since each Spell class is basically a wrapper around a function (this is more properly the Command pattern, not Strategy), you could get rid of spell classes completely and just use functions with a little bit of reflection to find the spell methods and add some metadata to them. Like:
public delegate void Spell(Creature caster, Creature targetCreature);
public static class Spells
{
[Spell("Mage Armor", 4)]
public static void MageArmor(Creature caster, Creature targetCreature)
{
targetCreature.AddAC(4);
}
[Spell("Fire Ball", 5)]
public static void FireBall(Creature caster, Creature targetCreature)
{
targetCreature.SubtractHealth(7);
}
}
First of all: There is always a better/cleaner/easier approach for everything.
But in my eyes you've made a decent abstraction of your challenge which can be a solid base for further improvements.
I might be missing something, but the trio WizardSpells, LoadedSpell, SetSpell seems like it could be clarified. Specifically, I don't see the list being used in your code so far. I would probably add spells available to the Wizard to the list, with LearnNewSpell(Spell newSpell), and check that LoadSpell uses a spell from that list.
Also, you might consider at some point adding some extra info about the type of caster on the Spell, if you are going to have multiple types of Casters.
I tend to think that your spells and items should really not be classes but a composition of effects.
Here's my take on it, feel free to expand. It's basically using a composite approach and a two-phase evaluation of spell effects, so each class can add specific resitance.
[Serializable]
class Spell
{
string Name { get; set; }
Dictionary<PowerSource, double> PowerCost { get; set; }
Dictionary<PowerSource, TimeSpan> CoolDown { get; set; }
ActionProperty[] Properties { get; set; }
ActionEffect Apply(Wizzard entity)
{
// evaluate
var effect = new ActionEffect();
foreach (var property in Properties)
{
entity.Defend(property,effect);
}
// then apply
entity.Apply(effect);
// return the spell total effects for pretty printing
return effect;
}
}
internal class ActionEffect
{
public Dictionary<DamageKind,double> DamageByKind{ get; set;}
public Dictionary<string,TimeSpan> NeutralizedActions{ get; set;}
public Dictionary<string,double> EquipmentDamage{ get; set;}
public Location EntityLocation{ get; set;} // resulting entity location
public Location ActionLocation{ get; set;} // source action location (could be deflected for example)
}
[Serializable]
class ActionProperty
{
public DamageKind DamageKind { get; set; }
public double? DamageValue { get; set;}
public int? Range{ get; set;}
public TimeSpan? duration { get; set; }
public string Effect{ get; set}
}
[Serializable]
class Wizzard
{
public virtual void Defend(ActionProperty property,ActionEffect totalEffect)
{
// no defence
}
public void Apply(ActionEffect effect)
{
// self damage
foreach (var byKind in effect.DamageByKind)
{
this.hp -= byKind.Value;
}
// let's say we can't move for X seconds
foreach (var neutralized in effect.NeutralizedActions)
{
Actions[neutralized.Key].NextAvailable += neutralized.Value;
}
// armor damage?
foreach (var equipmentDamage in effect.EquipmentDamage)
{
equipment[equipmentDamage.Key].Damage += equipmentDamage.Value;
}
}
}
[Serializable]
class RinceWind:Wizzard
{
public override void Defend(ActionProperty property, ActionEffect totalEffect)
{
// we have resist magic !
if(property.DamageKind==DamageKind.Magic)
{
log("resited magic!");
double dmg = property.DamageValue - MagicResistance;
ActionProperty resistedProperty=new ActionProperty(property);
resistedProperty.DamageValue = Math.Min(0,dmg);
return;
}
base.Receive(property, totalEffect);
}
}
Yes, I know, yet another question about mutable objects. See this for general background and this for the closest analogue to my question. (though it has some C++ specific overtones that don't apply here)
Let's assume that the following pseudo code represents the best interface design. That is, it's the clearest expression of the business semantics (as they stand today) into OO type. Naturally, the UglyData and the things we're tasked to do with it are subject to incremental change.
public class FriendlyWrapper
{
public FriendlyWrapper(UglyDatum u)
{
Foo = u.asdf[0].f[0].o.o;
Bar = u.barbarbar.ToDooDad();
Baz = u.uglyNameForBaz;
// etc
}
public Widget Foo { get; private set; }
public DooDad Bar { get; private set; }
public DooDad Baz { get; private set; }
// etc
public WhizBang Expensive1 { get; private set; }
public WhizBang Expensive2 { get; private set; }
public void Calculate()
{
Expensive1 = Calc(Foo, Bar);
Expensive2 = Calc(Foo, Baz);
}
private WhizBang Calc(Widget a, DooDad b) { /* stuff */ }
public override void ToString()
{
return string.Format("{0}{1}{2}{3}{4}", Foo, Bar, Baz, Expensive1 ?? "", Expensive2 ?? "");
}
}
// Consumer 1 is happy to work with just the basic wrapped properties
public string Summarize()
{
var myStuff = from u in data
where IsWhatIWant(u)
select new FriendlyWrapper(u);
var sb = new StringBuilder();
foreach (var s in myStuff)
{
sb.AppendLine(s.ToString());
}
return sb.ToString();
}
// Consumer 2's job is to take the performance hit up front. His callers might do things
// with expensive properties (eg bind one to a UI element) that should not take noticeable time.
public IEnumerable<FriendlyWrapper> FetchAllData(Predicate<UglyDatum> pred)
{
var myStuff = from u in data
where pred(u)
select new FriendlyWrapper(u);
foreach (var s in myStuff)
{
s.Calculate(); // as written, this doesn't do what you intend...
}
return myStuff;
}
What's the best route here? Options I can see:
Mutable object with an explicit Calculate() method, as above
Mutable object where expensive calculations are done in the getters (and probably cached)
Split into two objects where one inherits (or perhaps composes?) from the other
Some sort of static + locking mechanism, as in the C++ question linked above
I'm leaning toward #2 myself. But every route has potential pitfalls.
If you choose #1 or #2, then how would you implement Consumer2's loop over mutables in a clear, correct manner?
If you choose #1 or #3, how would you handle future situations where you only want to calculate some properties but not others? Willing to create N helper methods / derived classes?
If you choose #4, I think you're crazy, but feel free to explain
In your case, since you're using LINQ, you're only going to constructing these objects in cases where you want the calculation.
If that is your standard usage pattern, I would just put the expensive calculation directly in the constructor. Using lazy initialization is always slower unless you plan to have some cases where you do not calculate. Doing the calculation in the getters will not save anything (at least in this specific case).
As for mutability - mutable objects with reference syntax and identity (ie: classes in C#) are really okay - it's more a problem when you're dealing with mutable value types (ie: structs). There are many, many mutable classes in the .NET BCL - and they don't cause issues. The problem is typically more of one when you start dealing with value types. Mutable value types lead to very unexpected behavior.
In general, I'd turn this question upside down - How and where are you going to use this object? How can you make this object the most performant (if it's been determined to be problematic) without affecting usability? Your 1), 3) and 4) options would all make usability suffer, so I'd avoid them. In this case, doing 2) won't help. I'd just put it in the constructor, so your object's always in a valid state (which is very good for usability and maintainability).
I swear I have seen an example of this but have been googling for a bit and can not find it.
I have a class that has a reference to an object and need to have a GET; method for it. My problem is that I do not want anyone to be able to fiddle with it, i.e. I want them to get a read only version of it, (note I need to be able to alter it from within my class).
Thanks
No, there's no way of doing this. For instance, if you return a List<string> (and it's not immutable) then callers will be able to add entries.
The normal way round this is to return an immutable wrapper, e.g. ReadOnlyCollection<T>.
For other mutable types, you may need to clone the value before returning it.
Note that just returning an immutable interface view (e.g. returning IEnumerable<T> instead of List<T>) won't stop a caller from casting back to the mutable type and mutating.
EDIT: Note that apart from anything else, this kind of concern is one of the reasons why immutable types make it easier to reason about code :)
Return a reference to a stripped-down interface:
interface IFoo
string Bar { get; }
class ClassWithGet
public IFoo GetFoo(...);
If the object isn't too complicated/extensive then write an wrapper around it.
for example:
class A {
public string strField = 'string';
public int intField = 10;
}
class AWrapper {
private A _aObj;
public AWrapper(A aobj) {
_aObj = A;
}
public string strField {
get {
return _aObj.strField;
}
}
public int intField {
get {
return _aObj.intField;
}
}
}
So now all you do is give your client code an instance of the AWrapper class so that they may only use what you allow them to see.
this may get a bit complicated and may not scale well if your base class is not set in stone, but for most simple situation it may just do the trick. I think this is called a facade pattern(but don't quote me on that =) )
This isn't possible. Get and set accessors to reference types get and set the reference to the object. You can prevent changes to the reference by using a private (or internal) setter, but you cannot prevent changes to the object itself if it's exposed by a getter.
Your question reads like you're looking for:
public PropertyName { get; private set; }
But then, given the answers so far I'm not sure I'm interpreting your question correctly. Besides, who am I to question Jon Skeet? :)
i agree with ReadOnlyCollection
See my simple code:
private List<Device> _devices;
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices
{
get
{
return (_devices.AsReadOnly());
}
}
ReadOnlyCollection dosen't has Add method so user cant add properties to it.BUT ther is no warranty that if user can modify objects by calling their methods....
I have faced this problem in a certain way.
I have a CategoryViewModel class, which have a property Category that I want private read-only :
public CategoryViewModel
{
private Category { get; }
}
In fact, I want it to be exported as read-only to other class. However I can't do such thing.
In my case (maybe it will help some other guys), I want to add it to a repository. The only way that I've found is to have a function with the repository as param 1, and an Action as param 2 :
public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action)
{
action(repo, Category);
}
Like that, from elsewhere, I can do such thing :
categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));
This can help other to expose there property only for certains cases and can manage them.