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 7 years ago.
Improve this question
I have been developing in C# for around 12 months now (from scratch, no previous dev experience apart from a little bit of PHP script hacking) and I like to think I have developed my skills to a level which I can write an app and it perform its function perfectly.
however, I am still a little confused about best coding practises, I understand that this code is bad:
class Example1
{
public static Alert GenerateAlert()
{
Alert AlertObject = new Alert();
AlertObject.AlertDatetime = DateTime.Now;
AlertObject.AlertHasRecords = false;
return AlertObject;
}
}
If for example AlertDatetime requires more than a simple line like DateTime.Now; I will end up bulking out a massive function. not good!
However, I cant see a problem with the following two examples (I favour Example 2)
class Example2
{
public static Alert AlertObject = new Alert();
public static Alert GenerateAlert()
{
PopulateAlertDate();
CheckForAlertRecords();
return AlertObject;
}
private static void CheckForAlertRecords()
{
AlertObject.AlertHasRecords = false;
}
private static void PopulateAlertDate()
{
AlertObject.AlertDatetime = DateTime.Now;
}
}
class Example3
{
public static Alert GenerateAlert()
{
Alert AlertObject = new Alert();
AlertObject.AlertDatetime = PopulateAlertDate();
AlertObject.AlertHasRecords = CheckForAlertRecords();
return AlertObject;
}
private static bool CheckForAlertRecords()
{
return false;
}
private static DateTime PopulateAlertDate()
{
return DateTime.Now;
}
}
Is one example better than the other, and if so why? or is there a completely different way of doing it?
Your first example is fine.
If, at a later time, AlertDateTime requires a more complex function to be initialized, you can always refactor your code to something like example 3. Until then, respect the KISS (Keep it simple) and YAGNI principles.
Note that the interface (the publicly available methods and their signature) does not change between examples 1 and 3. This is a good thing. It means that you can move between those styles without having to modify the code that uses your class.
Example 2, however, has a lot of problems:
The information hiding principle basically says that you should not expose something publicly without a good reason. Why would you store your newly generated Alert in a publicly accessible "global variable"?
Example 2 behaves differently: If you call GenerateAlert twice, it will return a reference to the same Alert object both times. (Think about what happens if you call it once today and again tomorrow.)
As a side note, the naming of your methods in Example 3 can be improved. Try to think of each method in isolation: PopulateAlertDate() does not populate the alert date. It returns a date that can be used to populate an alert date. The name GetDefaultAlertDate() might be more appropriate.
+1 for the great answer of Heinzi.
I'll add that in example 3 you are using a variation of the Façade pattern. You are wrapping a class with its complicated & repeated initializing logic, and also hide the interface of this object and expose new methods instead. If later you have several different ways to create the same object, you should consider the Factory pattern.
Pay attention: you should firstly favor placing some of the code in the original class' constructor, if there is no reason of using another variation at a time.
Example 2 resembles the Singleton anti-pattern, which serves another purpose - keeping one instance of a class. This is usually done for services you prefer being created once and for all. Even then, you better look at Dependency Containers for greater unit testing capabilities.
If there's more logic in these functions than just assigning true or false, you might want to use a factory and interfaces. A completely abstracted code following the solid principles would look like:
public class AlertFactory : IAlertFactory {
IAlertDatePopulator alertDatePopulator;
IAlertRecordsChecker alertRecordsChecker;
public AlertFactory(IAlertDatePopulator alertDatePopulator, IAlertRecordsChecker alertRecordsChecker) {
this.alertDatePopulator= alertDatePopulator;
this.alertRecordsChecker = alertRecordsChecker;
}
public Alert GenerateAlert() {
Alert alertObject = new Alert();
alertObject.AlertDatetime = alertDatePopulator.Populate();
alertObject.AlertHasRecords = alertRecordsChecker.Check();
return alertObject;
}
}
with
interface IAlertFactory { Alert GenerateAlert(); }
interface IAlertDatePopulator { DateTime Populate(); }
interface IAlertRecordsChecker { bool Check(); }
You can then add concrete implementations for these interfaces, for example:
public class DateTimeNowAlertDatePopulator : IAlertDatePopulator {
public DateTime Populate() { return DateTime.Now; }
}
public class SomeCalculationAlertDatePopulator : IAlertDatePopulator {
public DateTime Populate() { return /* something calculated */; }
}
resp.
public class AlwaysFalseAlertRecordsChecker : IAlertRecordsChecker {
public bool Check() { return false; }
}
public class SomeCalculationAlertRecordsChecker : IAlertRecordsChecker {
public bool Check() { return /* something calculated */; }
}
Then you can create configured factories:
public class DateNowAndRecordsFalseAlertFactory : AlertFactory {
public DateNowAndRecordsFalseAlertFactory ()
: base (new DateTimeNowAlertDatePopulator(), new AlwaysFalseAlertRecordsChecker()) { }
}
public class DateNowAndCalculatedRecordsAlertFactory : AlertFactory {
public DateNowAndCalculatedRecordsAlertFactory ()
: base (new SomeCalculationAlertDatePopulator(), new AlwaysFalseAlertRecordsChecker()) { }
}
And then just use your factory:
var alertFactory = new DateNowAndRecordsFalseAlertFactory ();
var myAlert1 = alertFactory.GenerateAlert();
var alertFactory2 = new DateNowAndCalculatedRecordsAlertFactory();
var myAlert2 = alertFactory2.GenerateAlert();
etc. This seems a lot of code for a simple functionality, but if you expect a lot of extensions with lots of logic coming up, then this is clean code following the open/close principle (to be open for extensions (by just adding new interface implementations) but closed for modifications (not needing to modify existing code anymore)).
Most effective when used with dependency injection. You'd then configure your factory like this:
public class DateNowAndRecordsFalseAlertFactory : AlertFactory {
public DateNowAndRecordsFalseAlertFactory (DateTimeNowAlertDatePopulator alertDatePopulator, AlwaysFalseAlertRecordsChecker alertRecordsChecker)
: base (alertDatePopulator, alertRecordsChecker) { }
}
And just do:
var alertFactory = someDiContainer.Resolve<DateNowAndRecordsFalseAlertFactory>();
You are trying to instantiate an object and I don't see a point of having static method for that (there is an answer already with factory, do you really need that?)
In place where you have to create this object simply do
var alert = new Alert();
If you want to customize some of properties after object is created with default values, then here is shortcut
var anotherAlert = new Alert() { AlertDatetime = DateTime.Now };
Normally you should create instance of object in the way usable at most, so if you always have to construct it with current date, this is what constructor normally does:
public class Alert
{
// do not add class name to property
public DateTime DateTime {get; set;}
// this don't need initialization if default value is false
public bool HasRecords {get; set;}
public Alert()
{
DateTime = DateTime.Now;
}
}
Related
I'm making a card game where I assign random effects to cards, so I need to load the effect's code at runtime with just the class name.
I don't know if my abstract class and child are done properly, and I also don't exactly know how to get the class needed from a path.
I know Resouces.Load won't work but I'll leave it there to convey what I wanna do more easily.
public class GameManager : MonoBehaviour
{
public Effect effect;
...
effect = Resources.Load<Effect>("Card/Effects/" + c.cardActual.effect1);
if (effect.Execution())
{
StartCoroutine(TargetAndCastSpell(c,p));
}
This is the code for my abstract class
public abstract class Effect : MonoBehaviour
{
public string targetType;
public List<int> availableTargets;
public int effectTier;
public PlayerHolder playerTarget;
public CardPhysicalInstance minionTarget;
public PlayerHolder caster;
public void EffectX(PlayerHolder PlayerTarget, CardPhysicalInstance MinionTarget)
{
}
public bool Execution()
{
return false;
}
}
And lastly the child I want to load in runtime
class Spark : Effect
{
string targetType = "any";
//Deal 1 damage to any target
public bool Execution ()
{
bool canTarget = false;
caster = GameManager.singleton.currentPlayer;
availableTargets = SpellHelper.AvailableTargets();
if (targetType == "any") //Placeholder check
{
canTarget = true;
caster.playerState = GameManager.PlayerState.targeting;
}
return canTarget;
}
...
Any help is deeply appreciated, thanks and sorry about my clear lack of understanding of abstract classes.
Based on comments, I think Overriding is the Droid you are looking for. With Polymorphy there is two ways different Implementations can be resolved.
hiding is possibly by default. However, it is also pretty much useless. It is one of those things we thought we need and now everyone adds it to their OOP language. But aside from not using hiding when I wanted to overwrite, I have never had any use for it.
Overriding is the important thing. However, overriding has to be allowed for a function in the base class that first added it.
In Effect:
//Stil work how it does, but now can be overridden
public virtual bool Execution()
{
return false;
}
In Spark:
//We are actually overriding - not just hiding - Effect.Execution() here
public override bool Execution ()
{
bool canTarget = false;
caster = GameManager.singleton.currentPlayer;
availableTargets = SpellHelper.AvailableTargets();
if (targetType == "any") //Placeholder check
{
canTarget = true;
caster.playerState = GameManager.PlayerState.targeting;
}
return canTarget;
}
You can assign a Spark to a Effect variable, call Execution() and Polymorphy will deal with calling the version of Spark.
Add anotehr Effect sub-class? As long as it also overrides Execution() it works the same.
The Effect version could be empty/turned abstract. Or be kept as a default version for all subclasses.
With hiding you would have to cast it back to Spark to get access to it's variant of the Method. Wich is just extra work with no apparent advantage.
I've been working on a Discord bot and one of my abstract classes that represents servers ("Bot Contexts") contains the following data.
public virtual Command[] ContextSpecificCommands { get; } = null;
In user-defined Contexts I expect them to override this (if the server that has this code needs to). There's an issue, however, which is that I expect Commands to be singletons in the scope of a Context. This means that CommandFoo can exist only once in CoolContextNumberOne, and can also exist in CoolContextNumberTwo (as a separate instance of CommandFoo), but a single context cannot have two instances of CommandFoo in it.
My issue comes in with the behavior of getters. If the user does this...
public override Command[] ContextSpecificCommands => new Command[] {
new CommandFoo()
};
Then this will instantiate CommandFoo every time ContextSpecificCommands is referenced.
Is there any way to ensure that ContextSpecificCommands is cached in-line so that it only instantiates that container array once? I'd like to avoid requiring the user to specify a field and point to that field if possible.
This code was for the intellectual exercise, it is not recommended!
If you are willing to force the implementors of your BotContexts to use a specific form, then you can insert a type of singleton pattern into the property definition.
Consider:
public static class Singleton {
public static T For<T>(Func<T> makeSingleton) => Singleton<T>.For(makeSingleton);
}
public static class Singleton<T> {
static Dictionary<Func<T>, T> Cache = new Dictionary<Func<T>, T>();
public static T For(Func<T> makeSingleton) {
T singleton;
if (!Cache.TryGetValue(makeSingleton, out singleton)) {
singleton = makeSingleton();
Cache[makeSingleton] = singleton;
}
return singleton;
}
}
Now you can use this like so:
public class CoolContextNumberOne : BotContexts {
public override Command[] ContextSpecificCommands => Singleton.For(() => new Command[] { new CommandFoo() });
}
public class CoolContextNumberTwo : BotContexts {
public override Command[] ContextSpecificCommands => Singleton.For(() => new Command[] { new CommandFoo() });
}
Each CoolContext will create one instance of CommandFoo regardless of how many times ContextSpecificCommands is called.
Since in C# the use of a new expression will always generate a new object, it is difficult (impossible?) to see how you could have the code the same and figure out when to generate a new object and when to return an existing object (e.g. if a Command was actually a proxy object). If you didn't mind a dependency on optimization being enabled, StackFrame and GetILOffset could help, but would probably fail in debug mode. And be very brittle.
It may be possible to hide the use of Singleton in the types of Commands by using dynamic and Expando but that seems like an even worse idea.
This is not natively possible without adding extra code.
In order for a result to cache, a separate backing field must be created and the code must be set up to work with this field.
In order to resolve my dilemma, I have altered my code from:
// User will override this.
public virtual Command[] ContextSpecificCommands { get; } = null;
To:
// User will override this.
protected virtual Command[] ContextSpecificCommands { get; } = null;
// These control the cache.
private bool HasPopulatedCommandCache = false;
private Command[] CommandCache = null;
// Things will reference this to get ahold of commands.
public Command[] Commands {
get {
if (!HasPopulatedCommandCache) {
HasPopulatedCommandCache = true;
CommandCache = ContextSpecificCommands;
}
return CommandCache;
}
}
This allows the code to meet all of the goals specified in my original question. The user's class can use an in-line expression to define their commands without the worry of this array being instantiated every time it is referenced.
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 6 years ago.
Improve this question
I'm working on an Card Game development in C#, and I don't know how to do the following:
I have my Card class, which has a List of actions that are attacks in which that card can perform.
These attacks are a custom class named Act (in which I called Rules in the example).
When I load my cards I call an Inicialize method that I created that inicialize the List of cards, as well as the List of Attacks of each card.
I Want to be able to express my Attacks as an multiple Method call with parameters that will be called only when I call that Attack for execute.
For example, something like that
ActionList = new List<CardRule>();
ActionList.Add(new CardRule()
{
Description = "Cause 20 damage, then causes burn status.",
Rules = Damage(20).CauseStatus(Status.Burn);
});
I want to define the action(which I called Rules) as an multiple method call, passing parameters,
And call that Rules.Execute() to perform all method call, etc..
I Know that its something related to delegates, but I don't know how to do this calling multiple methods with predefined parameters.
Thank you in advance and sorry for bad english, I'm new at Stack Overflow also..
Regards,
What you're looking for isn't actually a delegate, but a class which tracks what needs to be done. This is a pattern used often by fluent APIs, but it's relatively simple to create something for your example.
For your example, you may have an IActionConfiguration interface, for example:
public interface IActionConfiguration
{
void PerformAction(MyTarget target);
}
Now, you'll want a few different implementations. For example, one which represents damage:
class DamageActionConfiguration : IActionConfiguration
{
private int m_damageStrength;
public DamageActionConfiguration(int strength)
{
m_damageStrength = strength;
}
public void PerformAction(MyTarget target)
{
target.Health -= strength;
}
}
And another one to represent a status effect:
class CauseStatusActionConfiguration : IActionConfiguration
{
private Status m_status;
public CauseStatusActionConfiguration(Status status)
{
m_status = status;
}
public void PerformAction(MyTarget target)
{
target.StatusEffects.Add(m_status);
}
}
Now, you'll also one an implementation which represents multiple actions.
class CompositeActionConfiguration : IActionConfiguration
{
private IActionConfiguration m_firstWrappedConfiguration;
private IActionConfiguration m_secondWrappedConfiguration;
public CompositeActionConfiguration(IActionConfiguration first, IActionConfiguration second)
{
m_firstWrappedConfiguration = first;
m_secondWrappedConfiguration = second;
}
public void PerformAction(MyTarget target)
{
m_firstWrappedConfiguration.PerformAction();
m_secondWrappedConfiguration.PerformAction();
}
}
This is incredibly simplified, but good enough for our example. Now you have a class (CompositeActionConfiguration) which can represent multiple actions - all you need is the magic that lets you chain them together easily.
public static class ActionRules
{
//First, you want a few static methods which can start a chain:
public static IActionConfiguration Damage(int strength)
{
return new DamageActionConfiguration(strength);
}
public static IActionConfiguration Status(Status status)
{
return new CauseStatusActionConfiguration(status);
}
// Next, some extension methods which allow you to chain things together
// This is really the glue that makes this whole solution easy to use
public static IActionConfiguration WithDamage(this IActionConfiguration source, int strength)
{
return new CompositeActionConfiguration(source, Damage(strength));
}
public static IActionConfiguration WithStatus(this IActionConfiguration source, Status status)
{
return new CompositeActionConfiguration(source, Status(status));
}
}
That's it. This gives you a solution which does more or less what you want. You would define your Rules property as an IActionConfiguration, then you can consume it like this:
var card = new CardRule()
{
Description = "Cause 20 damage, then causes burn status.",
Rules = ActionRules.Damage(20).WithStatus(Status.Burn);
};
card.PerformAction(target);
I have an entity called "Set" which contains Cards. Sometimes I want to see the entire card and its contents (card view), when sometimes I just want to know how many cards are in the Set (table views). In my effort to keep things DRY, I decided to try and re-use my SetDto class with multiple constructors like this:
public class SetDto
{
public SetDto()
{
Cards = new List<CardDto>();
}
// Called via SetDto(set, "thin")
public SetDto (Set set, string isThin)
{
var setDto = new SetDto()
{
SetId = set.SetId,
Title = set.Title,
Details = set.Details,
Stage = set.Stage,
CardCount = set.Cards.Count
};
return setDto;
}
// Called via SetDto(set)
public SetDto(Set set)
{
SetId = set.SetId;
UserId = set.UserId;
Title = set.Title;
Details = set.Details;
FolderId = set.FolderId;
Stage = set.Stage;
IsArchived = set.IsArchived;
Cards = new List<CardDto>();
foreach (Card card in set.Cards)
{
Cards.Add(new CardDto(card));
}
}
/// property definitions
I originally had two different DTOs for sets - ThinSetDto and FullSetDto - but this seemed messy and tougher to test. Does the above solution seem ok, or am I breaking a known best-practice? Thank you for your time!
I would create three methods in the SetManager class (a class handling CRUD operations) not in the DTO.
The dto shold have no such a logic inside. Anyway I agree with you that the replication is useless (and evil).
public class BaseSetDTO
{
public BaseSetDTO()
{
Set();
}
internal virtual void Set()
{
//Do your base set here with base properties
}
}
public class SetDTO : BaseSetDTO
{
internal override void Set()
{
//Do a full set here
}
}
Create a base class, then let your types handle what they are supposed to set. Create a new on for your ThinSetDTO and override again.
Instead, I would prefer extension method by declaring all properties in Set class and modifying the properties by passing required parameters. Otherwise initialize a baseDTO and have various versions by adding required properties and call extension method to create required version DTO and return baseDTO.
public static Set SetDto(this Set set, bool isThin)
{
if(isThin)
{
}
return objSet;
}
A common solution to this is to have the repository (or equivalent) return the 'flavor' of the DTO/entity you want by either having different access methods ie: Get() ... GetSet(), or to enumerate your 'flavors' of the entity in question and pass that to your 'Get' (or equivalent) method ie:
enum ContactCollectionFlavors { Full, CountOnly, CountWithNames .... }
...
foo = ContactRepository.GetByLastName('Jones', ContactCollectionFlavors.CountWithNames);
This can get a little messy, from experience the entity in question should have some way of knowing what 'flavor' it is, which smells bad since it breaks encapsulation and seperation of concerns - but in my opinion its better hold your nose and keep some out of band data, so that later you can have lazy loading of the entity allowing you to turn 'light flavors' into fully populated entities.
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 4 years ago.
Improve this question
I started designing a small application and have some architecture-related questions.
I have some basic entities, which I'm willing to model - Repository and Indicator.
Repository is basically a facade using the Repository Pattern, which is able to retrieve / store arbitrary entities using some database holder (right now it's NHibernate-driven, but I guess that's not actually important).
The Indicator may be called the logical core of my application. It is used to combine abstract values and the exact time at which that value was achieved (so it forms and operates on Value - Time pairs).
I am willing to make this Indicator as generic as possible, still I think my current solution is a big fail :)
See the following chunks of code:
public interface IIndicator<T>
{
IEnumerable<T> RetrieveValues(DateTime start, DateTime end);
}
// Should also have something like indicator wrapper / proxy stub here - anything
// that represents the 'IIndicator' interface acts through that proxy and
// caches the evaluated data using it.
This is a basic attempt to implement the indicator (right now this can actually be considered as a mock):
public class Indicator<TValue> :
// Self-referencing generic parameter.
IIndicator<Indicator<TValue>.TimestampProxy>
{
// Proxy, which is used to add the timestamp to
// every indicated value.
public class TimestampProxy
{
public TValue Value;
public DateTime Time;
public TimestampProxy(DateTime time, TValue value)
{
Time = time;
Value = value;
}
}
private readonly IRepository repository;
public Indicator(IRepository repository)
{
this.repository = repository;
}
public IEnumerable<TimestampProxy> RetrieveValues(DateTime start, DateTime end)
{
// Note the custom time stamp comparation in the lambda
// expression. Comparation includes the 'start' and 'end' limits.
IQueryable<TimestampProxy> queryable = repository.Retrieve<TimestampProxy>(
x => x.Time.CompareTo(start) >= 0 && x.Time.CompareTo(end) <= 0);
return queryable.ToList();
}
}
Now - this might look fine, but I'm absolutely sure that the TimestampProxy used is really evil.
It also makes the things hard to understand (for example, method signature IEnumerable<TimestampProxy> RetrieveValues(...) would probably result in a "wtf?!" phrase from a person who examines the code).
Unfortunately, I can't come up with a better solution / global redesign - could you advice me how to do it or simply tell some ideas about how this kind of feature should be done?
Thanks.
How about refactoring the RetrieveValues method back into the Repository itself and going with a much simpler Indicator class that basically replaces your TimestampProxy class.
public class Indicator<T>
{
public DateTime Timestamp { get; set; }
public T Value { get; set; }
}
public class Repository
{
public IEnumerable<Indicator<T>> RetrieveIndicators<T>( DateTime start, DateTime end )
{
// determine table to query based on type T
// query and convert objects to Indicator<T>
// return collection
}
}
One thing that bothers me is that in making it generic you've lost the connection to the DB table. It might be better to simply define an interface that all of your specific DB objects implement and use partial implementations to map the actual "value" onto the Value property.
public interface Indicator<T>
{
DateTime Timestamp { get; }
T Value { get; }
}
public partial class TemperatureIndicator : Indicator<double>
{
public double Value { get { return this.Temperature; } }
}
Now have your repository implement methods that return objects of each type -- which can be used as (in .NET 4 or cast to in lower versions) objects of the interface type for common operations.