Ok, so working on a dotnet Core 2 console app that I'm designing to run either on Windows or *Nix. Now the the part I'm trying to figure out is I want to only have one code base and let the code determine if it's running on Win then go one path, or if on *Nix go another path.
So what I'm thinking is create an Interface with the way I want the classes for the two paths to look as far as properties and methods, then create a Win and Nix class implementing the interface.
Seems straightforward, but what I am racking my brain on is how exactly do I create the object based on the OS? I have wrapper code for "IsWindows" and "IsNix" that returns a boolean each, so my thought is to use a If statement to do this. Not sure how to create a generic global variable, then instantiate it in the conditional statement.
Maybe I'm off my rocker and trying to do something odd here, if I am I'm not afraid to be told that. My only other thought is to perform the work inside the conditional statement, but that really would negate my desire to create the object in the conditional based on the OS, then call the same code going forward, using the classes that implement the Interface to make the different code calls as appropriate.
So I feel like a complete idiot with brain lock. Simply creating an object of the type of the Interface is all I needed to do, then set it to an instance of the class in the conditional statement. Easy peasy, not sure why I had a brain fart on that one.
Having common interface and two classes implementing it for different OS'es is definitelly good approach. So let's assume you have
public interface IMyInterface
{
void DoSomething();
}
public class WinClass: IMyInterface
{
public void DoSomething()
{
//Implementation of DoSomething for Windows
}
}
public class NixClass : IMyInterface
{
public void DoSomething()
{
//Implementation of DoSomething for *nix
}
}
Common way to instantiate different implementations of interface (or abstract class) based on certain conditions is using Factory pattern. This might look like this:
public static class MyInterfaceFactory
{
public static IMyInterface CreateMyInterface()
{
if (IsWindows)
return new WinClass();
else if (IsNix)
return new NixClass();
else
throw new PlatformNotSupportedException();
}
}
This is the only platform-dependent part of your code, rest of your code will use only IMyInterface and will be platform independent. You can either use this factory whenever you need to create new instance implementing IMyInterface, or you can use Singleton pattern to ensure, that only one objects will be created for entire application:
public static class MyInterfaceSingleton
{
static MyInterfaceSingleton()
{
Instance = MyInterfaceFactory.CreateMyInterface();
}
public static IMyInterface Instance { get; private set; }
// In C# 7, you can use just this instead:
// public static IMyInterface Instance { get; } = MyInterfaceFactory.CreateMyInterface();
}
Your application then simply call MyInterfaceSingleton.Instance.DoSomething(); whenever needed, in a platform independent way.
Related
At my work, I'm trying to create more modular systems, as we tend to use similar mechanics in our games that have minor variances. To do this, I have been making use of interfaces, but have been getting stumped on certain problems, particularly ones relating to the addition of small features.
EXAMPLE:
Take for instance our evolution system. I have created the IEvolvable interface, which has a property for the evolution level and an Evolve() method.
public interface IEvolvable
{
int evolution { get; }
bool IncreaseEvolution(int numEvolutions);
}
I then have an implementation of this interface on a Character class, and based on some conditions via my Evolution handling class, I want to evolve my character.
public class EvolutionHandler
{
public IEvolvable evolvable;
public void TryEvolveCharacter
{
if(someCondition)
{
evolvable.IncreaseEvolution(1);
}
}
}
Then, later down the line, we say, we want the character to evolve based on level! Fantastic. We have an ILevellable interface which contains Level, xp, etc.
public interface ILevellable
{
int Level{ get; }
int MaxLevel{get;}
int XP {get;}
bool LevelUp(int numLevels);
}
We can use this data to control when evolution takes place based on the change in level. But here's my problem:
My evolve handler class interfaces with IEvolvable... not ILevellable... So what do I do?
I can have IEvolvable extend ILevellable or vice-versa... or I can create a new interface which extends IEvolvable and ILevellable. Now I also have to modify my evolve handler to accomodate for these changes.
But what happens if we don't want the evolve handler to take into consideration the Level anymore in our new game? Do use the old code? Was I supposed to extend my old code to include the Ilevellable interfacing?
public interface ILevelEvolver : ILevellable, IEvolvable
{
}
public class EvolutionHandler2
{
public ILevelEvolver levelEvolvable;
public void TryEvolveCharacter
{
if(levelEvolvable.Level > 10)
{
evolvable.IncreaseEvolution(1);
}
}
}
the key words are :
separate what varies from what stay the same
one of SOLID principles : open for extension closed for modification
finally in your case would use Strategy pattern :
public interface IEvilutionChecker{
bool AllowEvolution();
}
public class EvolutionCheckerA : IEvilutionChecker{
private ILevellable levelEvolvable;
public EvolutionCheckerA(ILevellable levelEvolvable){
this.levelEvolvable = levelEvolvable;
}
public bool AllowEvolution(){
return levelEvolvable.Level > 10;
}
}
public class EvolutionCheckerB : IEvilutionChecker{
private IEvolvable evolvable;
public EvolutionCheckerB(IEvolvable evolvable){
this.evolvable = evolvable;
}
public bool AllowEvolution(){
return someCondition;
}
}
public class EvolutionHandler2
{
public IEvolvable evolvable;
public IEvilutionChecker EvolutionChecker {get;set;};
public void TryEvolveCharacter
{
if(EvolutionChecker.AllowEvolution())
{
evolvable.IncreaseEvolution(1);
}
}
}
The interfaces should not extend each other. Keep them separated. Also you should keep concepts separated. By that, EvolutionHandler should only accept IEvolable.
In TryEvolveCharacter method, you can check if the property is a ILevelable.
Take a look at the code:
class EvolutionHandler
{
public IEvolable Evolable { get; set; }
public void TryEvolveCharacter()
{
if (Evolable is ILevelable levelable && levelable.Level > 10)
{
Evolable.IncreaseEvolution(1);
}
else if (someCondition)
{
Evolable.IncreaseEvolution(1);
}
}
}
so at the future, if a character extends ILevelable, that level will be considered, if not, someCondition take place.
Once you are running into these types of issues it becomes evident I think that OOP has limitations, or rather it makes some things too easy. That doesn't mean it should be scrapped entirely and something else adopted, there's a lot we can still use it for. What if rather than using the interface you make meaningful changes to directly you pass around a service interface that acts as an adapter to the internal interface.
public interface IEvolutionService {
TryEvolveCharacter(IEvolvable evolvable);
}
The concrete implementation can have something like
public void TryEvolveCharacter(IEvolvable evolvable){
if (evolvable.Level > 10) {
evolvable.IncreaseEvolution(1);
..Maybe do something new that the IEvolvable just exposed but without changing our consumed interface!
}
}
It does add code and things to make these but you have options there too, a single service can stand in for multiple interfaces, but then you are violating the Single Responsibility Principle in SOLID, and basically just making things more complex than they should in an effort at making it less complex.
You could make this a method on static class, although that interferes with testability, so I'd say refactoring and adding in a new service to handle things like service.TryEvolveCharacter(someIEvolvable). You'd still have to maintain the interface on your public facing service, but that could be more manageable than the raw interface with nothing abstracted in front of it.
I gave my answer to be as close to your question as possible, but to me it is still less than ideal. I would consider having immutable structs (which can have interfaces, and also stick to the L2 CPU cache) for the data and passing those to services (which would be pure functions, that is to say stateless, they only deal with what is passed in). If you are writing game code and performance is an issue then that's going to be very useful.
If you were only using games as a metaphor maybe less so :)
A helpful article on structs, L2, and performance
In many cases, having an interface that includes members which would be meaningful for some implementations but not others can be a better pattern than trying to use different interfaces for different combinations of functionality. As a simple example, if Java or .NET had included in their basic enumerable interface a function to report a count if available, along with one to indicate if and how the count would be performed, then a wrapper class that concatenates two enumerations could efficiently report how many elements were in the combined enumeration if the constituent enumerations supported a count function, and could also let clients know whether its count function would be efficient and/or cacheable.
Another pattern that can be useful is for an interface to include asXX function which a class may implement as either returning a reference to itself (if it supports XX functionality) or constructing a wrapper object of suitable type. If XX is a wrapper-class type, functionality may be added to the wrapper class without having to change the interface that includes the asXX member or implementations thereof.
Introduction
I have a public abstract class, with an abstract method, which I want to call from a worker thread.
When the method is called, the respective instance should be locked down in order to prevent state changes during calculation.
I only want to work with the abstract class, as the implementation of the inheritors is done by third parties.
public abstract class MyClass
{
public abstract MyResult GetData();
}
The problem
My library is used by third parties, I have to assume that they know nothing about the internal implementation of the library.
I don't want to force them to study the documentation of my class, before they are able to implement their own inheritor as I consider this bad form.
My approach
My first idea was to add a protected lock object to the class and lock on it when calling the method.
However, in order for this to be useful, the third party would have to lock on it as well, and thus know about it.
As I don't want to force the third party to know about the internals, I don't like this option.
public abstract class MyClass
{
protected readonly object myLock = new object();
public MyResult GetData()
{
MyResult result;
lock(myLock)
{
result = GetDataInternal();
}
return result;
}
protected abstract MyResult GetDataInternal();
}
Background
I'm working on a data pipeline, which runs on a separate thread.
This pipeline requests data in a specific format and processes it in the background.
Providing the data can take some time and the provided data relies on properties of the objects.
In this case, its a preparation pipeline for 3D models.
The question
How can I lock a whole object without knowing its implementation?
If there is no such way, then is there an agreed upon pattern or something like that for this problem?
My library is used by third parties, I have to assume that they know nothing about the internal implementation of the library.
(..)
When the method is called, the respective instance should be locked down in order to prevent state changes during calculation.
I think that the best way is to .. make them know, and make sure they know that they are responsible for it. You can easily make it intuitive without (much) documentation.
Consider changing your abstract class to something like:
public interface ILockable
{
void FreezeDataForCalculations();
void ThawAfterCalculations();
}
public abstract class MyBaseClass<T> where T:ILockable
{
public abstract T GetData();
}
Usage:
public class MyThingie : MyBaseClass<TheActualData>
{
}
public class TheActualData : ILockable
{
public string Foo {get;set;}
public void FreezeDataForCalculations() { ...???...}
public void ThawAfterCalculations() { ....???.... }
}
Now, you effectively ensured that:
whoever wants to implement it, has to provide his own type, that implements extra interface
whoever implementa that extra interface will notice this two methods, and they will at least think "wtf", and will either understand immediatelly, or will try consulting the documentation
you do no locking for the data, creator of the class is responsible for it
implementor now can choose whever to actually implement freeze/thaw pair, or leave them empty and simply write their own code to not modify the data in the meantime
your code now has to call 'Freeze' and 'Thaw' appropriatelly, and can assume the implementor did what he was expected to
On the contrary, if you can't assume that he did was he was expected to, then change API of your library and don't allow user-defined types, and restrict the API to only your own types that you can ensure that will play nice.
New to OOP here. I have defined an interface with one method, and in my derived class I defined another public method. My client code is conditionally instantiating a class of the interface type, and of course the compiler doesn't know about the method in one of the derived classes as it is not part of the underlying interface definition. Here is what I am talking about:
public interface IFileLoader
{
public bool Load();
}
public class FileLoaderA : IFileLoader
{
public bool Load();
//implementation
public void SetStatus(FileLoadStatus status)
{
//implementation
}
}
public class FileLoaderB : IFileLoader
{
public bool Load();
//implementation
//note B does not have a SetStatus method
}
public enum FileLoadStatus
{
Started,
Done,
Error
}
// client code
IFileLoader loader;
if (Config.UseMethodA)
{
loader = new FileLoaderA();
}
else
{
loader = new FileLoaderB();
}
//does not know about this method
loader.SetStatus (FileStatus.Done);
I guess I have two questions:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC in order to say, "when my app asks
for an IFileLoader type, use concrete class x", as opposed to simply
using an App.Config file to get the setting?
Referring to your two questions and your other post I'd recommend the following:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
You don't necessarily need to find out the concrete implementation at runtime in your client code. Following this approach you kinda foil the crucial purpose of an interface. Hence it's rather useful to just naïvely use the interface and let the concrete logic behind decide what's to do.
So in your case, if one implementation's just able to load a file - fine. If your other implementation is able to the same and a bit more, that's fine, too. But the client code (in your case your console application) shouldn't care about it and just use Load().
Maybe some code says more than thousand words:
public class ThirdPartyLoader : IFileLoader
{
public bool Load(string fileName)
{
// simply acts as a wrapper around your 3rd party tool
}
}
public class SmartLoader : IFileLoader
{
private readonly ICanSetStatus _statusSetter;
public SmartLoader(ICanSetStatus statusSetter)
{
_statusSetter = statusSetter;
}
public bool Load(string fileName)
{
_statusSetter.SetStatus(FileStatus.Started);
// do whatever's necessary to load the file ;)
_statusSetter.SetStatus(FileStatus.Done);
}
}
Note that the SmartLoader does a bit more. But as a matter of separation of concerns its purpose is the loading part. The setting of a status is another class' task:
public interface ICanSetStatus
{
void SetStatus(FileStatus fileStatus);
// maybe add a second parameter with information about the file, so that an
// implementation of this interface knows everything that's needed
}
public class StatusSetter : ICanSetStatus
{
public void SetStatus(FileStatus fileStatus)
{
// do whatever's necessary...
}
}
Finally your client code could look something like the follwing:
static void Main(string[] args)
{
bool useThirdPartyLoader = GetInfoFromConfig();
IFileLoader loader = FileLoaderFactory.Create(useThirdPartyLoader);
var files = GetFilesFromSomewhere();
ProcessFiles(loader, files);
}
public static class FileLoaderFactory
{
public static IFileLoader Create(bool useThirdPartyLoader)
{
if (useThirdPartyLoader)
{
return new ThirdPartyLoader();
}
return new SmartLoader(new StatusSetter());
}
}
Note that this is just one possible way to do what you're looking for without having the necessity to determine IFileLoader's concrete implementation at runtime. There maybe other more elegant ways, which furthermore leads me to your next question.
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC [...], as opposed to simply using an App.Config file to get the setting?
First of all separating of classes' responsibility is always a good idea especially if you want to painlessly unittest your classes. Interfaces are your friends in these moments as you can easily substitute or "mock" instances by e.g. utilizing NSubstitute. Moreover, small classes are generally more easily maintainable.
The attempt above already relies on some sort of inversion of control. The main-method knows barely anything about how to instantiate a Loader (although the factory could do the config lookup as well. Then main wouldn't know anything, it would just use the instance).
Broadly speaking: Instead of writing the boilerplate factory instantiation code, you could use a DI-Framework like Ninject or maybe Castle Windsor which enables you to put the binding logic into configuration files which might best fit your needs.
To make a long story short: You could simply use a boolean appSetting in your app.config that tells your code which implementation to use. But you could use a DI-Framework instead and make use of its features to easily instantiate other classes as well. It may be a bit oversized for this case, but it's definitely worth a look!
Use something like:
if((loader as FileLoaderA) != null)
{
((FileLoaderA)loader).SetStatus(FileStatus.Done);
}
else
{
// Do something with it as FileLoaderB type
}
IoC is normally used in situations where your class depends on another class that needs to be setup first, the IoC container can instantiate/setup an instance of that class for your class to use and inject it into your class usually via the constructor. It then hands you an instance of your class that is setup and ready to go.
EDIT:
I was just trying to keep the code concise and easy to follow. I agree that this is not the most efficient form for this code (it actually performs the cast twice).
For the purpose of determining if a particular cast is valid Microsoft suggests using the following form:
var loaderA = loader as FileLoaderA;
if(loaderA != null)
{
loaderA.SetStatus(FileStatus.Done);
// Do any remaining FileLoaderA stuff
return;
}
var loaderB = loader as FileLoaderB
if(loaderB != null)
{
// Do FileLoaderB stuff
return;
}
I do not agree with using is in the if. The is keyword was designed to determine if an object was instantiated from a class that implements a particular interface, rather than if a cast is viable. I have found it does not always return the expected result (especially if a class implements multiple interfaces through direct implementation or inheritance of a base class).
I have just one method that I need several different classes to access and it just seems lame to make a utility class for just one method. The classes that need to use this method are already inheriting an abstract class so I can't use inheritance. What would you guys do in this situation?
[I]t just seems lame to make a utility
class for just one method
Just do it, it will grow. It always does. Common.Utilities or something of that nature is always necessary in any non-trivial solution.
Keep in mind that a class is just a small, focused machine. If the class only has one method then it's just a very small, focused machine. There's nothing wrong with it, and centralizing the code is valuable.
There is a cheat that you can use :-)
Create an Interface that your classes can "implement" but, create an extension method on that interface, your classes then magically get that method without having to call the utility class...
public Interface IDoThisThing {}
public static void DoThisThingImpl(this IDoThisThing dtt)
{
//The Impl of Do this thing....
}
Now on your classes you can just add the IDoThisThing
public class MyClass, MyBaseClass, IDoThisThing
{
//...
}
and they Get that thing :-)
Note, this is only syntatic sugar around effectively a utility class, but it does make the client code very clean (as just appears as a method on your class).
What do you mean you can't use inheritance?
If you write the method in the abstract class, you can also write the implementation (not everything in an abstract class needs to be abstract).
But generally, it's advisable to have some sort of 'GeneralUtils' class; cause you end up with a few of these functions.
I'd need more info to give a definite answer.
However a well-named class with a single well-named method could work wonders for readability (as compared to an inheritance based solution for instance)
Since you use the term utility method, I'd say create a static class with the static method and be done with it.
can use extension methods...
namespace ExtendMe
{
public interface IDecorate { }
public static class Extensions
{
public static void CommonMethod(this IDecorate o) { /* do stuff */ }
}
public class Blah :IDecorate {}
public class Widget : IDecorate {}
class Program
{
static void Main(string[] args)
{
new Blah().CommonMethod();
new Widget().CommonMethod();
}
}
}
I'd like to override a class method without inheriting the base class because it'd take a lot of time and modifications and, therefore, more and more tests. It's like this:
class TestClass{
public void initialMethod(){
...
}
}
And somewhere on the code, I'd like to do something like this:
public testMethod()
{
return;
}
test(){
changeMethod(TestClass.initialMethod, testMethod);
}
And this changeMethod function would override the TestClass initialMethod so that it'd call testMethod instead.
Inheriting and overriding the method using normal practices is not an option, as this class A is a graphic component and, inhereting it (and changing it) would break lots of code.
Edit: We don't have the base code for the TestClass, so it's not an option to modify the code there defining the initialMethod as a delegate.
Edit 2: Since this is a graphical component, the designer added a lot of code automatically. If I were to inherit this code, I would have to replace all code added by the designer. That's why I wouldn't like to replace this component.
You need the Strategy pattern.
Main steps:
Create an interface with ie. Do() signature
Your initialMethod() should call a strategy.Do(), where strategy is type of your interface
Create a class that implements this interface. Do() is your testmethod now.
Inject into your main class an instance of this class
If the job it's not so big (let's say just a color replacement or something) then I agree with Jhonny D. Cano's solution with C# (anonymous)delegates.
Edit (after edit 2)
May - just as proof-of-concept - you should inherit the class and replace all references from base class to this new. Do this, and nothing else. If it works, you can think about the next steps (new methods or delegates etc.)
You need only a new checkout from your version control system, and if it maybe fails you can abandon it. It's worth trying.
Perhaps you can do it as a delegate.
class TestClass {
public Action myAction;
public void initialMethod(){
...
}
initialMethod
public TestClass() {
myAction = initialMethod;
}
}
and then on TestMethod
public testMethod()
{
return;
}
test() {
testClassInstance.myAction = testMethod;
}
I think your best bet might be to use a AOP framework like LinFu. There's a codeproject article explaining it:
Introducing LinFu, Part VI: LinFu.AOP – Pervasive Method Interception and Replacement for Sealed Types in Any .NET Language
If 'TestClass' is something you defined, you could replace the 'initialMethod' definition with a property and delegate which can then be set to any method with a given signature. (Even anonymous ones.)
class TestClass {
Action _myMethod;
Action MyMethod {
get { return _myMethod; }
set { _myMethod = value; }
}
var tc = new TestClass()
tc.MyMethod = () -> Console.WriteLine("Hello World!");
tc.MyMethod()
The above code is untested.
The short and simple answer is: if you can't adjust the base TestClass code, no, there's no way you can modify the class to replace a method by another. Once we started doing stuff like that, we'd be in a completely different kind of language, like JavaScript.
The longer answer is: it depends on who is calling the replaced method.
If it's other classes, see if you can't implement a Proxy in between them and the unmodifiable concrete class. Whether this is doable depends on whether that class implements interfaces, or is its own interface.
If it's the class itself, then your only option is to decompile and modify the class, at design time using Reflector (or equivalent tools), or at runtime using Reflection.Emit. However, you'd have to be hurting pretty badly to go this route, as it's sure to be painful and brittle.
Unfortunately you still haven't explained what you are trying do and why. Replacing methods on the go is powerful stuff in the languages that permit it directly... There might be mocking libraries that can be twisted sufficiently far to do the reflection stuff, but then you'd be skating on thin ice.
If you don't have the code use Extension Methods.
public void doSmth(this objectYOUWANT arg)
{
//Do Something
}
Here you use the principle Closed for Modification Open for Extension.
This will add functionality to the library you don't have the source code. It's very clean to do it this way.
Edition:
In FrameWork 3.5 there is something new called Extension Methods. These kind of methods adds functionality to a closed Assembly letting you Extend in functionality a closed dll/assembly.
To use this for example you have a dll that you import, that is called Graphics.dll (you have the reference on your project)
First of all you shoud create a new static class called for example Extension:
public static class Extensions
{
}
Second, you want to add extra functionality to a class contained in Graphics.dll named ChartGraph. You will do this:
public static class Extensions
{
public static void draw(this ChartGraph g)
{
// DO SOMETHING
}
}
Third, when you instantiate a new object from the graphics.dll you now will have the new method you have created:
ChartGraph myG = new ChartGraph();
myG.draw();
As you can see there you have added new functionality without much effort without recompiling the dll, this is good if you don't have the source code.