Maybe the title is not so clear. Let me clarify what I'm trying to accomplish.
I have to base classes:
BaseProperties
BaseProblem
BaseProperties contains data about the generation of math problems. For example, in the image above, BasicAdditionProperties contains Addend1 and Addend2, this two objects know about the range of the generated value to represent a BasicAdditionProblem.
So, this is just an idea.. I guess I supposed to pass the abstract class to a factory, and this one should generate the problem (in this case BasicAdditionProblem).
I have read, it's recomended pass these values as the base class. And my main doubt is, when I pass the object BaseProperties to the factory, all the time do I have to cast the object?
Or what ideas can I implement to model this scenario? Or do I have to have a static Factory where maintain and be used as mapping to the concrete factories?
Thanks in advance.
Define an abstract CreateProblem() in the BaseProperties class. This method can be used generically to allow each concrete Properties subclass to provide its own Factory method.
This is similar to using an instance of WebRequest subclass and calling GetResponse() on it and it then returns the coresponding subclass of WebResponse.
This distributed abstract factory approach allows you to add property/problem pairs easily to the system because the code to map the two is solely contained in those two classes.
You could also use a full Abstract Factory implementation where you have PropertyProblemFactory that defines a CreateProperties() and a CreateProblem(). So in your example you would have AdditionFactory that knows how to create the matching set. But this forces you to define an additional class for each Property/Problem pair. It also works best when you have a class that uses the current/selected PropertyProblemFactory, creates a Properties with it, and then immediately uses that same PropertyProblemFactory factory to create the matching Problem. Once you let go of the reference to the factory and solely have just a reference to the Properties, it is harder to re-locate the right factory to create the Problem. (This can be addressed with yet another class to map object types to factories, but the complexity rises. So the first appoach I suggested is better in this kind of situation).
There are multiple solutions for this. It just depends on how you want to program it.
abstract methods in the abstract class must be handled in all classes that inherit from the abstract class. This way you can easily call abstract methods in the factory without casting.
However when you need to use lots of data from just one specific class then it would not be wise to make abstract methods for it and you should just simply cast the object.
So it all depends on how much classes inherit from BaseProperties and how much data in those classes are the same.
Related
I am working on a text-based game using C# and WPF. In this game the player can build different structures, probably around 20 unique ones in total when it's all done. Each structure will share some of the same properties, though with different values (such as the cost to build, etc.), and some will have properties and methods unique to themselves. I am trying to figure out the best, most efficient way to implement this.
I have explored using one class for all of them and using a static method with a parameter determining the desired type to generate an instance of the chosen structure, but think that the unique properties and methods some of the structures have would end up making that approach impractical. I could obviously make each different structure its own class and have about 20 of them, all inheriting from an interface containing common members, but I'm hoping that there's a more efficient way to do this that I'm overlooking.
I'm not looking for any code at this point, just concepts that might simplify this process and aid me in the future.
I recommend you look into Inheritance and Polymorphism.
Inheritance, together with encapsulation and polymorphism, is one of the three primary characteristics (or pillars) of object-oriented programming. Inheritance enables you to create new classes that reuse, extend, and modify the behavior that is defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class. However, inheritance is transitive. If ClassC is derived from ClassB, and ClassB is derived from ClassA, ClassC inherits the members declared in ClassB and ClassA.
Specifically I wouldn't use an interface, but an abstract class (Polymorphism) that has the shared code for multiple methods, but mark them as virtual so that derived(inherited) classes can overwrite the code. Using only an Interface means that you could be duplicating a lot of code.
I have different types of objects representing the same business entity.
UIObject, PowershellObject, DevCodeModelObject, WMIObject all are different representation to the same entity.
So say if the entity is Animal then I have AnimalUIObject, AnimalPSObject, AnimalModelObject, AnimalWMIObject, etc.
Now the implementations of AnimalUIObject, AnimalPSObject, AnimalModelObject are all in separate assemblies.
Now my scenario is I want to verify the contents of business entity Animal irrespective of the assembly it came from. So I created a GenericAnimal class to represent the Animal entity.
Now in GenericAnimal I added the following constructors:
GenericAnimal(AnimalUIObject)
GenericAnimal(AnimalPSObject)
GenericAnimal(AnimalModelObject)
Basically I made GenericAnimal depend on all the underlying assemblies so that while verifying I deal with this abstraction.
Now the other approach to do this is have GenericAnimal with an empty constructor
an allow these underlying assemblies to have a Transform() method which would build the GenericAnimal.
Both approaches have some pros and cons:
The 1st approach:
Pros: All construction logic is in one place in one class GenericAnimal
Cons: GenericAnimal class must be touched every-time there is a new representation form.
The 2nd approach:
Pros: construction responsibility is delegated to the underlying assembly.
Cons: As construction logic is spread accross assemblies, tomorrow if I need to add a property X in GenericAnimal then I have to touch all the assemblies to change the Transform method.
Which approach looks better ?
or Which would you consider a lesser evil ?
Is there any alternative way better than the above two ?
Just to elaborate further based on the comments i received.
I dont have the luxury the modify the structure of underlying objects, ie i cant change AnimalUIObject AnimalPSObject etc. The GenericAnimal is a construct introduced just for validation purposes by me.
I think both approaches are pretty "evil".
I think what you really need is to start with the Animal class as your core class, and make the rest of the classes wrapper classes that use the Animal class to hold the representation. Validation is then performed against the Animal API.
May be an opportunity for an abstract factory pattern ?
I have different types of objects representing the same business
entity. UIObject, PowershellObject, DevCodeModelObject, WMIObject all
are different representation to the same entity.
Take a look to Design Patterns in general and in particular to Structural Pattern.
In my understanding the Decorator Pattern would be useful:
The decorator pattern can be used to extend (decorate) the
functionality of a certain object at run-time, independently of other
instances of the same class, provided some groundwork is done at
design time. This is achieved by designing a new decorator class that
wraps the original class
So it should be the first approach but w/o the cons:
The GenericAnimal class will have a constructor:
GenericAnimal(AnimalObject)
With AnimalObject either an interface or abstract class.
Cons: GenericAnimal class must be touched every-time there is a new
representation form.
If you add another representation form make it implements or extends AnimalObject.
I don't get the connection of Interfaces To polymorphism.
Polymorphism for me is about executing a method in a different way for some different concrete classes using abstract methods or virtual methods+ overriding and therefore this is only linked to inheritance in my vision, but how do you override methods With Interfaces??
How do you use Interfaces for doing same method in different ways and giving the object to decide what to do according to its concrete type?
Thanks
As stated by Andreas Hartl in his article on Inheritance Vs. Interfaces:
Many high-level languages support inheritance and interfaces, and for
someone new to the concepts, it's sometimes not clear which one to
choose. Although languages differ in their exact handling of
inheritance and interfaces, the basics are usually the same, so this
tip should be valid for most languages.
Inheritance means that we derive one class (the derived class) from
another class (the base class). The derived class is an extension of
the base class. It contains all the features (methods and data
members) of the base class, can extend it with new features, and can
reimplement virtual methods of the base class. Some languages, like
C++, support multiple inheritance, where a derived class can have
multiple base classes, but usually inheritance is restricted to a
single base class.
Interfaces can usually only define methods and no data members (but C#
for example allows data members in the form of properties within
interfaces), and a class can always implement multiple interfaces. An
interface contains only method definitions without implementations,
and a class that implements an interface supplies the implementation.
So, using inheritance, you write a base class with method
implementations, and when you derive a class from it, this class will
inherit everything from the base class, and is immediately able to use
its features. An interface on the other hand is just a contract of
method signatures, and a class that wants to implement an interface is
forced to supply the implementations for all methods of the interface.
So when do you use which? In some cases, the language already dictates
what you use: if you need your class to have multiple 'parents', you
cannot use inheritance in languages that don't support multiple
inheritance. And if you want to reuse a library object, you have to
use the fitting concept, depending on if that library object is a
class or an interface.
But which to use if you are free to choose? Basically, base classes
describe and implement common behavior of related types, while
interfaces describe functionality that unrelated types can implement.
Inheritance describes 'is a' relationships, interfaces describe
'behaves like' relationships. For example, say that you are writing a
flight simulator. Your basic entity, which you will for example store
in a list, will be 'Airplane'. Your concrete types will be 'Concorde'
and 'Phantom'. So how should you model the three types? Concorde and
Phantom are related, they both are airplanes and share data, like
'Weight' or 'MaxSpeed' and functionality, like 'Accelerate', so we can
model them with inheritance. 'Airplane' will be the base class with
common data and methods, and 'Concorde' and 'Phantom' will derive from
'Airplane'. We could say that both are specialized airplanes, which is
why it's often said that inheritance means specialization. Now assume
that we also add a class 'Pilot' to our program, and we want to give
the user the ability to save the game and load it later. So when he
saves the game, we need to save the state of all Aircrafts and the
state of all Pilots. And we want to do this in one function that takes
just a list of all saveable objects. So how do we model this? To
answer this, we must take a look at the different types we want to
save. Pilots and Airplanes. It's obvious that they are not related at
all. They share no common data and no common functionality. We can see
that writing a base class 'Saveable' and derive both Pilot and
Airplane from it would make little sense, since no code in Saveable
could be reused by Airplane or Pilot, since both have no common
properties. In this case, an interface is the best solution. We can
write an interface 'ISaveable' with a method Save(). Pilot could then
implement ISaveable.Save() by saving his name, while Airplane could
save its current speed and coordinates.
As you can see, a clear image of the relationship between classes
often makes the choice clear: Use inheritance for related types, where
each derived class 'is a' base class. Use interfaces for unrelated
types which have some common functionality.
Here are some more points to consider with inheritance and interfaces:
Interfaces are fixed. When you change an interface, you have to change every class implementing that interface. But when you change a
base class, every derived class will gain the new functionality, which
can both be good (if you make a bugfix in some base class method
implementation, a derived class using that method will gain the bugfix
without you needing to change it) or bad (if a change in the baseclass
introduces a new bug, all derived classes using the method will be
bugged too).
Interfaces are usually more flexible, since in most languages you can only derive from one class, but implement many interfaces
Interfaces help to protect internal classes: Assume class A has an internal object b of class B. When a method in A returns a pointer or
reference to b, the code that called this method now has access to the
whole object b, which can be dangerous if A only wants to expose
certain members of b. This problem can be solved if you create an
interface I with just the members which are safe to expose. When B
implements this interface, and your method in A returns b via an I
pointer or reference, the outside code can only do what you allow
through the interface.
Polymorphism as a concept does not require inheritance, although in many languages inheritance is the only way to achieve it. Some languages, like smalltalk allow you to polymorphically use any type that implements the same set of members and properties. If it looks like a duck, quacks like a duck, and walks like a duck, you can treat it like a duck.
Polymorphism is simply the ability to treat one object as another object, by providing the same way to access and use it as the original object. This is best illustrated by the Liskov Substitution Principle. This is called the "Interface" or sometimes "Contract", because it defines a "signature" that another object can use to do interesting things to the object.
in C#, you can inherit from interfaces or other (non-sealed) classes. The difference is that an interface does not provide any actual storage or methods (only their "signature"), it is merely a definition. You can't instantiate an interface, you can only instantiate an object that implements an interface.
Classes implement an interface (IDisposable, for instance) in the same way you build a house based on blue prints. If you build two houses with the same blueprints, then each house has the exact same "interface", they may have different color paint, or carpeting, but they function in exactly the same way, yet they are two distinctly different houses, with many differences in how various things might function.
When it comes to C#, just know that an interface says what properties or members an object that implements it MUST have. Likewise, in C#, a big difference is that you can inherit multiple interfaces but only ever a single class. (ie public class Test : BaseClass, IDisposable, ITest, IFooBar)
consider this...
public int SomeMethod(SomeBaseClass object)
{
// Pass in a descendant classe that implements / overrides some method in SomebaseClass
}
public int SomeMethod(ISomeInterface intf)
{
// pass in concrete classes that implement some ISomeInterface function
}
This is the basic essence of polymorphic behavior, a common contract, implemented specifically by a specialist class.
So, hypothetically, I'm building some sort of real estate application in C#. For each type of property, I'm going to create a class such as ResidentialProperty and CommercialProperty. These two classes as well as all other property classes will share some common properties, such as Id, Title, Description, and Address information.
What I would like to be able to do is:
a) return a collection of objects that contain just the basic information
b) be able to either call a method such as GetProperty(id) which will create and return either a ResidentialProperty or CommercialProperty, or call GetProperties() which will return a collection of one or the other, or both.
So with that said, it would probably make sense to create an abstract class called BasicProperty (or PropertyBase) which contains all of the common attributes, and have the ResidentialProperty and CommercialProperty extend from it. This would take care of problem #1, as I could create a method that returns a collection of BasicProperties.
But for #2, being able to return either one property type or the other, I would need an Interface (IProperty), and have the Residential and Commercial classes inherit from it, and then have the GetProperty(id) and GetProperties() return an IProperty object (or because they inherit from IProperty, can I return them as is and not as the Interface?)?
Now if I should use an Interface, what do I do with the BasicProperty class?
- Do I leave it as an abstract and implement the Interface? Or
- Do I leave it as an abstract and all 3 classes implement the Interface? Or
- Do I not create it as an abstract, put all of the basic information into the Interface, and the BasicProperty, ResidentialProperty and CommercialProperty all implement the Interface?
Thanks in advance,
Carl J.
While I feel that defining an interface to begin with is almost always a good idea, just because it helps your code to be flexible in the future, it sounds like in this case you don't actually need to do that. Your GetProperty and GetProperties methods can use your abstract base class as a return value.
Think of it like this: What if I had a method called GetShape? It would presumably return a Shape, right? Let's say Shape is an abstract base class, and some derived classes are Triangle, Square, Circle, etc.
But a triangle is a shape, a square is a shape, and so on--each of these happens to be more than just a shape, but they are shapes nonetheless. So if I say "give me a shape" and you hand me a square, you're doing just as I asked. No funny business there.
This is one of the core underlying principles of OOP: an instance of a derived class is an instance of its base class; it's just also more than that.
From what I can gather, you are talking about two different things here.
Class structure
Data Access of those classes
You are correct in thinking that you should create an abstract class to contain the common properties, that's what inheritance is for :) (among other things)
But I dont see why you can't create a data access class that has a method GetProperty(id) that specifies a return type of PropertyBase
i.e.
public PropertyBase GetProperty(long id)
in the implementation of GetProperty you can construct a ResidentialProperty or CommercialProperty (based on what ever business/database logic you want) then return it, c# allows you to do that.
Perhaps I miss-understood you?
HTH
EDIT::
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
}
}
class DataAccessLayer
{
public PropertyBase GetSomething(int id)
{
if (id > 10)
return new CommercialProperty();
else
return new ResidentialProperty();
}
}
class PropertyBase { }
class ResidentialProperty : PropertyBase { }
class CommercialProperty : PropertyBase { }
}
An abstract class is used to provide common behaviour. An interface is used to provide a specific set of methods and properties, regardless of how they behave.
If your ResidentialProperty and CommercialProperty provide some common behaviour then it probably makes sense to implement this behaviour in an abstract class and have each of them inherit from this class. Presumably they also will have some custom behaviour ,otherwise there is no need to sub-class, it would then be sufficient just to have a PropertyType property to describe which type of Property the instance is.
You can then provide as many interfaces as you feel would be useful, IPropertyBase, IResidentialProperty and/or ICommercialProperty. It really depends on whether you expect this library to be used a base for other implementations which may have the same interface as one or more of your classes, but not the same behaviour as your base abstract class. The other benefit of exposing interfaces which represent your types is easier mocking for unit testing.
It's not really possible to answer this question absolutely because it really depends on how your objects are likely to be used, but I hope this answer provides you with a useful guideline.
It is my opinion that you should avoid using abstract classes unless it absolutely makes sense you should.
A lot of the common behaviour can be given to your entities through aggregation, using components and you can publicise this behaviour through the use of interfaces.
The reason I tend to go down this route, is that once you have an abstract base class, you're tied to using it, as you can't have multiple inheritance.
Sooner or later, you end up with a situation in which you DO want multiple inheritance and you're screwed.
Not that I'm a hardliner on this, because plenty of our code-base does utilise base abstract classes for the above, but those implement the interfaces and all the code enacting on those classes talk to them through the interfaces, so we can switch out the base classes for something more flexible later if necessary.
A quick not about the difference as I see it. You can always use an abstract base class even when you implement interfaces. Interfaces does not help you avoid code duplication which you should (see the DRY principle) but it doesn't force you to derive from anything special which makes them easier to combine with other base classes or interfaces.
An abstract base class on the other hand can remove some duplication and it is easier to change some things in the base without touching the derived classes. The latter is very nice when you implement a class library that others use. If you change things in interfaces in a library, all implementations of that interface needs to change! This might be a very small problem if you only implement an application with a small group of developers. But as other has said, a base class forces you to derive from it and then you cannot derive from something else if that need should appear.
Don't call your base class or interface BasicProperty or PropertyBase, just call it Property. You will not have both a Property and a BasicProperty, will you? You will act with Property classes or interfaces.
An abstract class is almost the same as an interface with the difference that the abstract class can store state in field variables. When your Properties have data like the address that is stored an abstract class with a field is one way to do that.
Now the subclassing of a class is one of the picture book examples of OOD, but there are other ways of differentiating objects than that, look at the decorator and behavior patterns. You should subclass only if you need to override methods of the base class. Have a look at this for example.
Here is the situation for which I am trying to find a suitable design.
I need to store profiles of numbers. A profile is just a series of numbers. They can be of either int, float or decimal type. Each profile has a ProfileDescription field based on an ennumeration.
Each Profile has a collection of ProfileVersion Objects. Each ProfileVersion object has a collection of ProfileValue objects. These ProfileValue objects are where the actual numerical values of the required type are stored.
My initial design idea was to make Profile, ProfileVersion and ProfileValue generic. I hit a problem when I want to have a List of Profiles of different types, which I cannot have. I could use an ArrayList instead, but then i would have to cast out the data within it.
I though it might be possible to make just ProfileVersion and ProfileValue generic, and then have the Profile Object assign a type to the ProfileVersion depending on the value of the ProfileDescription field, but I cannot find a way to do this.
Another thought was I should use a ProfileBase class and then subclass it with either a GenericProfileClass or IntProfile, FloatProfile and DecimalProfile, but this wouldn't really give me any advantage over having each class being generic, as I would have to cast out the subclass each time anyway.
I would appreciate your thoughts on the best design approach for this situation.
Thanks
Grzenio's idea is correct. Each of your profile classes could be made to be implementations of an IProfile object, and then your container could be:
class ProfileList : IList<T> where T: IProfile
Thus the only constraint you'll have is the interface, not the specific type or a casted base class.
As for:
Another thought was I should use a
ProfileBase class and then subclass it
with either a GenericProfileClass or
IntProfile, FloatProfile and
DecimalProfile, but this wouldn't
really give me any advantage over
having each class being generic, as I
would have to cast out the subclass
each time anyway.
The benefits would really depend on the level of abstractions that you make for your classes. If designed properly you can ideally have operation/business logic/or manager classes that can accept any of those base types (again via generics) without having to know the specific cast.
I am not sure if I understand your problem correctly (pasting the code that doesn't work would help), but I think that you could try to create interfaces IProfile, IProfileVersion, etc. and make the generic class inherit the interface Profile<T>:IProfile.
What you are trying to do in not easy anyway, because there is no base numeric type in C# sadly.