Where should properties reside when modeling OOP? Small example included - c#

I'm looking to learn how to use interfaces and base classes effectively. I'm not exactly sure where to put common properties? Do only behaviors belong in an interface? If properties such as: Color and MinSpeed shouldn't go in the interface, where should they live? In an abstract class?
public interface IVehicle
{
void Speed();
void Clean();
void Stop();
}
public class Bmw : IVehicle
{
// Because these pertain to every vehicle no matter of maker,
// should these propertes go in the interface? Or in an abstract class?
public string Color { get; set; }
public int MinSpeed { get; set; }
#region IVehicle Members
public void Speed()
{
}
public void Clean()
{
}
public void Stop()
{
}
#endregion
}

Interfaces can be thought of as a contract that must be satisfied by any implementing class. Use it if you want to guarentee that all classes do the same thing—satisfy the same API—but you don't care how they do it. If properties are a part of that API, then by all means include them in your interface.
From your example above, if you want all cars to be guaranteed to have a color and minSpeed, then those properties belong in the interface. If those properties are specific to BMWs alone, then they belong in the BMW class. If those properties belong to some classes but not others, you could create a new interface extending the original one:
public interface IVehicleWithColorAndMinSpeed : IVehicle
{
string Color { get; set; }
int MinSpeed { get; set; }
}
(just don't get carried away with this)
Abstract classes are similar, but allow you to provide a default implementation for your sub classes.
Abstract classes tend to be easier to version, since you can add something new to your API, and provide a default implementation that your existing subclasses will automatically pick up; adding something to an interface immediately breaks all existing classes which implement that interface.

The 'right' answer is entirely dependent on your domain model. What is the problem you're trying to solve? There is no 'right' answer other than the one which solves the particular problem at hand with the greatest:
understandability
maintainability
brevity
isolation
performance
You can probably consider most of those properties to be in order of importance, but they mean different things to different people and there's probably a lot of debate implied there too.
Can you tell us any more about the particular application you imagine these classes to serve?

Related

How can I do a simple effect system with inheritance?

I'm trying to practice with inheritance and just in general having scripts interact with each other and I thought doing a simple effect system could be fun, but I'm a bit stuck on how to structure things.
I keep wanting to do this
public abstract class BaseEffect : ScriptableObject
{
//not sure if this is a good use of enum
public enum EffectType
{
harm, //can be applied to enemies
help, //can be applied to allies
self //can be applied to yourself
}
public string name;
public string description;
public float duration;
public bool canStack; //can the effect be applied multiple times
public EffectType type;
//I'd probably also write my apply and remove effect methods here
}
And then a bunch of derived classes like this
public class TestEffect : BaseEffect
{
//maybe include some variables specific to this effect
//when the effect gets applied have this run every frame to od whatever the effect does
public void DoEffect()
{
}
}
I have a feeling though that this isn't a good way to go about doing this or at least the way I've written it isn't good so looking for some advice to get on the right track
This arrangement may benefit from an abstract method or usage of an Interface consumed by an abstract class to enforce derived classes to respond to events. Speaking of events, you could also wire the derived calls up through events. In simple terms, introduce an abstract method in the base class, which must be implemented in derived classes. Then call the method in the base classes "plumbing" when everything special about the event is ready.
public abstract class BaseEffect : ScriptableObject
{
protected abstract void DoEffect();
private SomeMethod()
{
if(canDoEffect)
DoEffect();
}
}

Unity 3D: Should I make an extensive script or multiple smaller ones for in game items?

Basically I'm trying to create a attatchment system for a 2D platform/shooter game, the weapon system is working great but I want to implement some attachments, diferent barrels, magazines even ammo types.
For the simpler ones that just modify a stat I was thinking of just creating a class or even a struct with all the possible stats (damage, recoil, spread etc) and just setting them to the appropiate values (+1, -5, 0 if it doesn't use it). However, there are some ideas that might require a separate method/function, like shooting different bullets.
My main question is would it be more effective/efficient to just make smaller scripts for the edge cases and a main one for the simple stat changers. Or should I just overload a main script/class with methods for all the possible attachments?
There aren't that many "special" attachments, but i'd like to make a system that expandable if possible.
Im not an expert programmer (I just learned about enums a couple days ago!) so any suggestions are greatly appreciated.
I would use Unity's ScriptableObject class to create an abstract class then inherit from that abstract class to create more spesific classes and abstract classes.
Then I would create my attachments etc. in unity editor and modify whatever value I want from it.
An example armor piece would inherit the following ArmorItem class and use the ApplyEffect method to make the player bigger to show that you can make any type of modification.
ItemBase class
using UnityEngine;
public abstract class ItemBase: ScriptableObject
{
public string ItemName;
public abstract void ApplyEffect();//override this method for any edge case items
}
ArmorItem
public abstract class ArmorItem: ItemBase
{
public float Armor;//use this however you want
}
EdgeCaseArmor
[CreateAssetMenu(menuName = "Items/Armor/EdgeCaseArmor")]
public class EdgeCaseArmor: ArmorItem
{
public override void ApplyEffect()
{
//find player and make it bigger
GameObject.FindGameObjectWithTag("Player").transform.localScale *= 1.5f;
}
}
Obviously you will need to load items and somehow call ApplyEffect. You can do it at the start of the game by adding this to a start method.
var item = Resources.Load("path to your scriptable object that inherits ItemBase") as ItemBase;
item.Activate();
How you load the items and call them is up to you. You will need to save your scriptable objects in Assets>Resources folder(create one if you haven't created one already).
You can also make multiple armors with different names, armor values etc. like this.
Note that if you want to have an armor with no special effect you will need to make ArmorItem a normal class or make a NormalArmor class that inherits ArmorItem. Just leave the ApplyEffect function empty if you don't want any special effects.
This is a fairly general question so keep in mind that you may get several varying opinion-related answers.
With that said, the biggest suggestion that I would give is to look into Inheritance. Using a series of interfaces and classes to more refine the base concept of "item modifications".
For instance, I would create an interface:
interface IItemModification
{
void Apply();
}
Any more refined modification class or interface would implement (in the case of a class) or inherit (in the case of another interface) this interface.
In this example we will just create a base class that implements that interface:
public class ItemModification : IItemModification
{
public void Apply()
{
// Logic to apply modifications to the item.
}
}
In the case above, you now have a very basic class that represents an item modification which contains the implementation of the interface.
Next you might want to go into further detail, perhaps by creating item type implementations:
public class WeaponItemModification : ItemModification
{
public ArmorItemModification(StatModifiers modifiers, AttackType attackType)
{
this.Modifiers = modifiers;
this.Attack= attackType;
}
public AttackType Attack
{
get; set;
}
public StatModification Modifiers { get; set; }
}
public class ArmorItemModification : ItemModification
{
public ArmorItemModification(StatModifiers modifiers, DefenseType defenseType)
{
this.Modifiers = modifiers;
this.Defense = defenseType;
}
public DefenseType Defense
{
get; set;
}
public StatModification Modifiers { get; set; }
}
Of course a logical progression of that would be more specific item types:
public class VestModification : ArmorItemModification
{
public VestModification(StatModification modifiers, DefenseType defenseType, AreaProtectionType areaProtectionType)
{
this.Modifiers = modifiers;
this.Defense = defenseType;
this.AreaProtection = areaProtectionType;
}
public AreaProtectionType AreaProtection
{
get; set;
}
}
These are just some basic examples to point you in the right direction. I would suggest reading up on inheritance concepts to get a better understanding of it.

Accepting multiple similar entities in a Method - Elegant solution

I have two data entities, which are almost similar, design is something like:
public Class Entity1 : Base
{
public int layerId;
public List<int> Groups;
}
Difference is Entity1 has an extra collection of integer Groups
public Class Entity2 : Base
{
public int layerId;
}
These entities are filled as an input from UI using Json, I need to pass them to a processing method, which gives the same Output entity. Method has a logic to handle if List<int> Groups is null, I need to create a method which is capable of handling each of the input in an elegant manner. I cannot just use only Entity1, since they are two different functional inputs for different business process, so using Entity1 as direct replacement would be a mis-representation
Instead of creating overload of the function, I can think of following options:
Use object type as input and typecast in the function internally
I think we can similarly use dynamic types, but solution will be similar as above, it will not be a clean solution in either case, along with the switch-case mess.
What I am currently doing is processing method is like this:
public OuputEntity ProcessMethod(Entity 1)
{
// Data Processing
}
I have created a constructor of Entity1, that takes Entity2 as Input.
Any suggestion to create an elegant solution, which can have multiple such entities. May be using generic, where we use a Func delegate to create a common type out of two or more entities, which is almost similar to what I have currently done. Something like:
Func<T,Entity1>
Thus use Entity1 output for further processing in the logic.
I need to create a method which is capable of handling each of the input in an elegant manner
Create an Interface, or a contract so to speak, where each entity adheres to the particular design. That way common functionality can be processed in a similar manner. Subsequently each difference is expressed in other interfaces and testing for that interface sis done and the differences handled as such.
May be using generic,
Generic types can be tested against interfaces and a clean method of operations hence follows suit.
For example say we have two entities that both have Name properties as string, but one has an Order property. So we define the common interface
public interface IName
{
string Name { get; set; }
string FullName { get; }
}
public interface IOrder
{
decimal Amount { get; set; }
}
So once we have our two entities of EntityName and EntityOrder we can add the interfaces to them, usually using the Partial class definition such as when EF creates them on the fly:
public partial class EntityName : IName
{
// Nothing to do EntityName already defines public string Name { get; set; }
public string FullName { get { return "Person: " + Name; }}
}
public partial class EntityOrder : IName, IOrder
{
// Nothing to do Entity Order already defines public string Name { get; set; }
// and Amount.
public string FullName { get { return "Order: " + Name; } }
}
Then we can process each of them together in the same method
public void Process(IName entity)
{
LogOperation( entity.FullName );
// If we have an order process it uniquely
var order = entity as IOrder;
if (order != null)
{
LogOperation( "Order: " + order.Amount.ToString() );
}
}
Generic methods can enforce an interface(s) such as:
public void Process<T>(T entity) where T : IName
{
// Same as before but we are ensured that only elements of IName
// are used as enforced by the compiler.
}
Just create generic method that will do this work for you:
List<OuputEntity> MyMethod<T>(T value) where T : Base
// adding this constraint ensures that T is of type that is derived from Base type
{
List<OutputEntity> result = new List<OutputEntity>();
// some processing logic here like ...
return result;
}
var resultForEntity1 = MyMethod<Entity1>();
var resultForEntity2 = MyMethod<Entity2>();
P.S. check my answer for this question as you may find it useful too:
map string to entity for using with generic method
You probably want to implement an interface or an abstract class.
From MSDN
If you anticipate creating multiple versions of your component, create
an abstract class. Abstract classes provide a simple and easy way to
version your components. By updating the base class, all inheriting
classes are automatically updated with the change. Interfaces, on the
other hand, cannot be changed once created. If a new version of an
interface is required, you must create a whole new interface.
If the functionality you are creating will be useful across a wide range of
disparate objects, use an interface. Abstract classes should be used
primarily for objects that are closely related, whereas interfaces are
best suited for providing common functionality to unrelated classes.
If you are designing small, concise bits of functionality, use
interfaces. If you are designing large functional units, use an
abstract class.
If you want to provide common, implemented
functionality among all implementations of your component, use an
abstract class. Abstract classes allow you to partially implement your
class, whereas interfaces contain no implementation for any members.
Abstract Class Example
Cat and Dog can both inherit from abstract class Animal, and this abstract base class will implement a method void Breathe() which all animals will thus do in exactly the same fashion. (You might make this method virtual so that you can override it for certain animals, like Fish, which does not breath the same as most animals).
Interface Example
All animals can be fed, so you'll create an interface called IFeedable and have Animal implement that. Only Dog and Horse are nice enough though to implement ILikeable - You'll not implement this on the base class, since this does not apply to Cat.

Is this candidate for abstract class

let's say that I want to collect in one place all common properties and behaviors for all sports. I was thinking to use SportBase as abstract class for this purpose but I'm not sure. I'm trying to understand the differences between Abstract vs Interface usage on this example.
Every sport should have following properties
DateTime Started;
DateTime Ended;
string Name;
What if I declare these properties like integers and later on I decide to use Game object as separated entity like Game StartGame. I do not see clearly which approach to use with high level of abstraction to reduce pain on later modification (this modification can have adding new properties, new behaviors, etc.)
Thanks
if you only have properties and empty methods an interface might be your better choice. if you have some actual code then abstract class is your only option. also remember that you can inherit only one abstract class but implement multiple interfaces.
You can use an interface to provide a contract to code to.
public interface ISportsEvent
{
DateTime Start { get; set; }
DateTime End { get; set; }
string Name { get; set; }
}
but that doesn't give you a reusable implementation
As a general rule you should prefer composition over inheritance.
So its often better to do something like this
public interface EventDetails
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string Name { get; set; }
}
public class SportingEvent
{
public EventDetails Details {get;set;}
}
now this is a bit rough but you can see what I'm getting at.
No, I wouldn't do that. You'll end up creating an abstract God class, which has way to many responsabilities.
I personally would probably make it an abstract class, since not only will your sports share some fields, but they might share some logic too.
Interfaces aren't for seperating out duplicate code, but they're purely for polymorphism.
All an interface does is guarantee that your class will act a certain way. If you plan on putting logic in your base class than you want an abstract class.

To abstract, or not to abstract

thanks in advance for reading this. I don’t fully understand how/when to use abstracts so I am trying to think about it each project I work on to see if it will all click some day Smile | :)
Also, the mix of accessibility levels (private, protected, internal) with keywords static, abstract, and override tend to leave me a little confused. How do I define this method/property/class....
It's not all a big mystery to me but some projects have me coding in circles when dealing with these topics.
With that said,
I have an application that reads an XML document and outputs text and image files. I’m also storing all of the information in a database. I have it working nicely.
The XML has a standard implementation with required fields and is used by multiple organizations to submit data to my app. All organizations should use (at least) the required nodes/elements that are outlined in the XML implementation guide.
So, I want to have a default data object type to be able to derive a specific organization’s data type for required elements. (If this object is going to be used, these are the fields that must be implemented).
If the org. just uses the default requirements, I can use the default object. If they use additional (optional) fields, I’ll have to create a new type inheriting the default type.
My first thought was to use and abstract class that had protected properties for my bare minimum requirements:
public abstract partial class AbstractDataObject
{
protected string DataObjectName;
protected DateTime? DataObjectDate;
etc...
}
Then, if the organization just uses the required elements of the node and no optional elements, I can use a “default” object.
internal partial class DefaultDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
}
But, if an organization uses optional fields of the required node, I can use a derived organization data object.
internal sealed partial class OranizationDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
Do I need the abstract class? It seems to me I can just have a DefaultDataObject (something like):
internal partial class DefaultDataObject
{
public virtual string DataObjectName { get; set; }
public virtual DateTime? DataObjectDate { get; set; }
etc...
}
And then:
internal sealed partial class OranizationDataObject : DefaultDataObject
{
public override string DataObjectName { get; set; }
public override DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
I’m just really trying to understand how to define these objects so I can reuse them per organization. Both ways seem to work, but I am hoping to understand how to define them properly.
Getting the XML into above objects:
public DefaultDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new DefaultDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate =
Program.TryParseDateTime((String)
t.Elements("ChildElement2")
.ElementAtOrDefault(0)
),
etc....
OR
public OranizationDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new OranizationDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate = Program.TryParseDateTime(
(String)t.Elements("ChildElement2")
.ElementAtOrDefault(0)),
DataObjectCode = (String)t.Element("ChildElement3"),
etc....
Again, thanks for reading. Don't forget to tip your wait staff....
Joe
First of all, your base class doesn't need to be abstract if it's a plain DTO class. If you don't have any functionality that needs to be implemented differently by derived classes, you can simply make it a plain base class which will hold common properties.
Next, there is no point in declaring properties in the base class (abstract in your case), if you are going to hide them (using the new keyword). You first code snippet of DefaultDataObject unnecessarily creates a bunch of new properties with the same name. Remove them completely - they are already defined in the base class.
[Edit] I didn't notice this initially, and #svick warned me, that your base class actually contained fields instead of properties, which makes me wonder why you needed to add the new keyword at all. I went over your code quickly and saw them as properties. In any case, you should never expose public fields - at least change them to auto-implemented properties by adding the { get; set; } block.
In other words, this would simply work:
// this doesn't need to be abstract.
// just put all the common stuff inside.
public class BaseDO
{
// as svick pointed out, these should also be properties.
// you should *never* expose public fields in your classes.
public string Name { get; set; }
public DateTime? Date { get; set; }
}
// don't use the new keyword to hide stuff.
// in most cases, you won't need that's behavior
public class DerivedDO : BaseDO
{
// no need to repeat those properties from above,
// only add **different ones**
public string Code { get; set; }
}
As a side note, but nevertheless important IMHO, you should simplify naming (and make it more clearer what your code does). There is no need to repeat "DataObject" in every property name, for example. But since your code is probably only a simplified version, it doesn't matter.
Lastly, have you heard of XmlSerializer? You don't need to traverse the XML elements manually. It is enough to call XmlSerializer to both serialize and deserialize your data.
Everything I need to know I learned from Sesame Street
Scrub your class design hard to make sure you've identified everything that is the same and different. Play computer, so to speak, with your classes and see how they do the same, different, or the same thing but in different ways.
What is the same, different, same but differently will likely change as you play computer.
Think in general terms of the two pillars of OO Classes. Polymorphism and Inheritance
As you do the above that is. Not so much in terms of C# implementation per se.
How things clump into same vs. different will help drive implementation
And it's all relative.
More of same default behavior? Perhaps a concrete base class instead of abstract.
More of same thing, but differently? Perhaps an abstract class instead of concrete base class.
A default way of doing x? Perhaps a virtual method.
Everyone does the same thing, but no two the same way? A delegate perhaps.
Implementation Suggestions
Make methods and fields protected as a default. Private does not get inherited. Designs change, stay flexible. If something just has to be private, fine.
virtual means you can change implementation in a sub class. It does not mean you must.
Folks seem to under-utilize delegates. They're super for polymorphic methods.
There is nothing wrong with public fields. What's the practical difference between a public field and a public auto-implemented property? Nothing. They both directly return (or set) the underlying value. So what's the point of even bothering with properties? If you want to publicly expose an underlying value differently than it's "natural" state. For example, returning a number in a specific format. And of course you can have different properties for the same field.
A Property can have a get without a set. Or vice versa. Also get and set can have different access levels. Often you'll see this as a public get and a protected (or private) set.
It depends on what the derived types will want to do. If they are going to use the default implementation and only expand on it somehow, then having the default class as the non-abstract base class is fine.
On the other hand, if they are most likely going to re-implement the functionality, you should have an abstract base class (or an interface) and a separate default class.
If you for some reason don't know which one is it, you can let the inheritors choose by having an abstract base class and leaving the default class unsealed.
Also, looking at your code, it seems you misunderstand what the various keywords do. Most of the time, you do not want to use new like this. What it does is to define another member with the same name, unrelated to the original one. Also, there's no reason to override something if you don't want to change it. So, if you expect that the derived classes won't have to reimplement the properties, you don't have to make them virtual at all.
An abstract class can already implement things that can be inherited
public abstract class DataObjectBase
{
public string DataObjectName { get; set; }
public DateTime? DataObjectDate { get; set; }
}
A concrete class can add new properties and methods
public class DerivedDataObject : DataObjectBase
{
public int NewProperty { get; set; }
}
The properties DataObjectName and DataObjectDate are already available in the new class, because they are automatically inherited from the base class.
If the abstract class defined an abstract member, however, you would have to implement it in the derived class.
Say the base class defines
public abstract void SomeMethod(string name);
The the derived class has to do this
public override void SomeMethod(string name)
{
...
}
If your base class does not have abstract members, it does not need to be abstract and can play the role of your default data object directly.
The keyword 'partial` is not needed here. It is only useful if you want to split one class into several pieces over several files.
The keyword new is wrong here. It is used to shadow an inherited member. This means that the inherited member will be hidden "behind" the new declaration. What you need, is to override. This does not hide a member, but provide an alternative implementation of the same member in the derived class.

Categories

Resources