Is it worth abstracting out Object creation for single classes? - c#

I'm playing around with design patterns, and things are coming along nicely. One thing I'm unsure of is it worth abstracting out Object creation when there is currently only one object?
For example a project I'm working on contains two different user types which are not related in any way. They are IStudent and IStaff. For the application in question, there will never be any other types of user (staff Roles handle all none-student interactions with the system).
In my controllers I could simply:
IStudent student = new Student();
Or I something like this:
public static class UserFactory
{
public static T Create<T>() where T : class
{
if(typeof(T) == typeof(IStudent))
return new Student() as T;
if (typeof(T) == typeof(IStaff))
return new Staff() as T;
throw new Exception("The requested user type is not valid.");
}
}
And then:
IStudent student = UserFactory.Create<IStudent>();
Is this overkill? I'm trying to work out best practice in these situations.

Personally, I use TDD for most development. One thing I like about that is that it provides an answer for your question: "not unless it's required to make a failing unit test pass".
In other words, if you don't need it, then don't do it.

Ok ... you need a factory class, or just, you need to call the constructor.
Why people have fear to call a constructor?
I believe that patterns are good. I believe also that the abuse of them is pure evil :)
If you start to see that your programming paradigm is making your life harder, then abandon that paradigm, not your programmer abilities.
Sometime too much abstraction is just not useful at all.
Being clean and writing clean codes don't means following a pattern, means writing code that makes sense.
The Factory pattern: if we have to write a Factory for the Factory and a Factory for the Factory for the Factory .... until the deadline arrives, when we write the real code?
Since I see system analysts more as architects than bricklayers, i believe that just following some rule cannot make your software good.
People can blame Turing or Church or Goedel if they want, but is not their fault if a software that write software cannot be written :)
We still need our human part to write software, our creativity and imagination and our soul, also if some software engeneer tried to make it a pure mechanical act, programming is still an art in a big part of it.
Conclusion: I believe patterns are very good if used with the right criticism and following always the good programmer's sixth sense :)
I think that programming requires some flexibility, we are not in a perfect world, we have no perfect computer, we are not perfect and our software cannot be perfect and especially machine cannot think, still.
So, calling a constructor is always better than 2000 lines of code to just call a constructor.

In this particular case, your solution provides no benefits over simply calling the constructor. If you have a reason for a factory, then by all means. Otherwise, don't over-complicate your code.
If your controller always knows what kind of User it's going to create (i.e. it's always going to pass in a concrete type in your type parameter), you don't need a factory.

You would generally only use the factory pattern when creating more than one type and you want to hide creation to prevent ugly things like:
if(newPerson == "student")
person = new Student();
else if(newPerson == "Staff")
person = new Staff();
You could then just do:
Person.CreatePerson(newPerson);
Again, this only matters if you have to do if then statements in more than one place.

I would say that your message:
there will never be any other types of user (staff Roles handle all none-student interactions with the system)
Very similar to this one:
640K of memory is all that anybody with a computer would ever need
In other words use simpler code you can, as suggests Sounders, but keep in mind that one day something could change, even if today it seems impossible.
EDIT
If you have a sequence of types (not just 2 ) of completely unrelated classes (from design perspective) Factory pattern applied by you could be pretty suitable IMHO.
Good luck.

Related

StoryQ BDD, Given or When without a body

I would like to do a very simple test for the Constructor of my class,
[Test]
public void InitLensShadingPluginTest()
{
_lensShadingStory.WithScenario("Init Lens Shading plug-in")
.Given(InitLensShadingPlugin)
.When(Nothing)
.Then(PluginIsCreated)
.Execute();
}
this can be in Given or When it... I think it should be in When() but it doesn't really matter.
private void InitLensShadingPlugin()
{
_plugin = new LSCPlugin(_imagesDatabaseProvider, n_iExternalToolImageViewerControl);
}
Since the Constructor is the one being tested, I do not have anything to do inside the When() statement,
And in Then() I assert about the plugin creation.
private void PluginIsCreated()
{
Assert.NotNull(_plugin);
}
my question is about StoryQ, since I do not want to do anything inside When()
i tried to use When(()=>{}) however this is not supported by storyQ,
this means I need to implement something like
private void Nothing()
{
}
and call When(Nothing)
is there a better practice?
It's strange that StoryQ doesn't support missing steps; your scenario is actually pretty typical of other examples I've used of starting applications, games etc. up:
Given the chess program is running
Then the pieces should be in the starting positions
for instance. So your desire to use a condition followed by an outcome is perfectly valid.
Looking at StoryQ's API, it doesn't look as if it supports these empty steps. You could always make your own method and call both the Given and When steps inside it, returning the operation from the When:
.GivenIStartedWith(InitLensShadingPlugin)
.Then(PluginIsCreated)
If that seems too clunky, I'd do as you suggested and move the Given to a When, initializing the Given with an empty method with a more meaningful name instead:
Given(NothingIsInitializedYet)
.When(InitLensShadingPlugin)
.Then(PluginIsCreated)
Either of these will solve your problem.
However, if all you're testing is a class, rather than an entire application, using StoryQ is probably overkill. The natural-language BDD frameworks like StoryQ, Cucumber, JBehave etc. are intended to help business and development teams collaborate in their exploration of requirements. They incur significant setup and maintenance overhead, so if the audience of your class-level scenarios / examples is technical, there may be an easier way.
For class-level examples of behaviour I would just go with a plain unit testing tool like NUnit or MSpec. I like using NUnit and putting my "Given / When / Then" in comments:
// Given I initialized the lens shading plugin on startup
_plugin = new LSCPlugin(_imagesDatabaseProvider, n_iExternalToolImageViewerControl);
// Then the plugin should have been created
Assert.NotNull(_plugin);
Steps at a class level aren't reused in the same way they are in full-system scenarios, because classes have much smaller, more encapsulated responsibilities; and developers benefit from reading the code rather than having it hidden away in the step definitions.
Your Given/When/Then comments here might still echo scenarios at a higher level, if the class is directly driving the functionality that the user sees.
Normally for full-system scenarios we would derive the steps from conversations with the "3 amigos":
a business representative (PO, SME, someone who has a problem to be solved)
a tester (who spots scenarios we might otherwise miss)
the dev (who's going to solve the problem).
There might be a pair of devs. UI designers can get involved if they want to. Matt Wynne says it's "3 amigos, where 3 is any number between 3 and 7". The best time to have the conversations is right before the devs pick up the work to begin coding it.
However, if you're working on your own, whether it's a toy or a real application, you might benefit just from having imaginary conversations. I use a pixie called Thistle for mine.

Where Is the ability to RegisterAll with Registration Contexts (aka Func<T>)?

I can register a single registration item with instanceCreator context (aka Func<T>), but there doesn't seem to be the same allowance with a RegisterAll.
TL;DR - Find the accepted answer and look at update 2 (or skip down to Update 3 on this question)
This is what I want to do:
container.RegisterAll<IFileWatcher>(
new List<Func<IFileWatcher>>
{
() => new FileWatcher(
#".\Triggers\TriggerWatch\SomeTrigger.txt",
container.GetInstance<IFileSystem>()),
() => new FileWatcher(
#".\Triggers\TriggerWatch\SomeOtherTrigger.txt",
container.GetInstance<IFileSystem>())
});
I tried adding an extension based on a previous Stack Overflow answer for multiple registrations, but it seems that last one in wins:
public static class SimpleInjectorExtensions
{
public static void RegisterAll<TService>(this Container container,
IEnumerable<Func<TService>> instanceCreators)
where TService : class
{
foreach (var instanceCreator in instanceCreators)
{
container.RegisterSingle(typeof(TService),instanceCreator);
}
container.RegisterAll<TService>(typeof (TService));
}
}
I'm also curious why there is a need for RegisterAll to exist in the first place. This is the first dependency injection container out of 5 that I've used that makes the distinction. The others just allow you to register multiple types against a service and then load them all up by calling Resolve<IEnumerable<TService>> (autofac) or GetAllInstances<TService> (both SimpleInjector and Ninject).
Update
For more clarity, I'm trying to build a list of items that I can pass to a composite that handles each of the individual items. It suffers from the same problem as the above since it falls into a group of tasks that all get registered to be run based on schedules, triggers, and events (Rx). To remove the register all for a moment and rip out some of the other stuff:
container.Register<ITask>(() => new FileWatchTask(
container.GetInstance<IFileSystem>(),
container.GetInstance<IMessageSubscriptionManagerService>(),
configuration,
container.GetAllInstances<IFileWatcher>()));
You can see that I am grabbing all instances of the previously registered file watchers.
What I need to know is a simple workaround for this issue and when it will be implemented (or if not, why it won't be). I will also accept that this is not possible given the current limitations of Simple Injector's design. What I will not accept is that I need to change and adapt my architecture to meet the limitations of a tool.
Update 2
Let's talk about OCP (Open Closed Principle aka the O in SOLID) and the impression I'm getting in how SimpleInjector breaks this particular principle in some cases.
Open Closed Principle is just that, open for extension, but closed for modification. What this means is that you can alter the behavior of an entity without altering its source code.
Now let's shift to an example that is relevant here:
var tasks = container.GetAllInstances<ITask>();
foreach (var task in tasks.OrEmptyListIfNull())
{
//registers the task with the scheduler, Rx Event Messaging, or another trigger of some sort
task.Initialize();
}
Notice how clean that is. To be able to do this though, I need to be able to register all instances of an interface:
container.RegisterAll<ITask>(
new List<Func<ITask>>{
() => new FileWatchTask(container.GetInstance<IFileSystem>(),container.GetInstance<IMessageSubscriptionManagerService>(),configuration,container.GetAllInstances<IFileWatcher>()),
() => new DefaultFtpTask(container.GetInstance<IFtpClient>(),container.GetInstance<IFileSystem>()),
() => new DefaultImportFilesTask(container.GetInstance<IFileSystem>())
}
);
Right? So the lesson here is that this is good and meeting OCP. I can change the behavior of the task runner simply by adding or removing items that are registered. Open for extension, closed for modification.
Now let's focus on trying to do it the way suggested in the answer below (prior to the second update, which finally answers this question), which the author is giving the impression to be a better design.
Let's start with what the answer from the maintainer mentions is good design for registration. The viewpoint that I'm getting is that I have to make a sacrifice to my code to somehow make the ITask more flexible to work with SimpleInjector:
container.Register<ITask<SomeGeneric1>(() => new FileWatchTask(container.GetInstance<IFileSystem>(),container.GetInstance<IMessageSubscriptionManagerService>(),configuration,container.GetAllInstances<IFileWatcher>()));
container.Register<ITask<SomeGeneric2>(() => new DefaultFtpTask(container.GetInstance<IFtpClient>(),container.GetInstance<IFileSystem>()));
container.Register<ITask<SomeGeneric3>(() => new DefaultImportFilesTask(container.GetInstance<IFileSystem>()));
Now let's see how that makes our design change:
var task1 = container.GetInstances<ITask<SomeGeneric1>();
task1.Initialize();
var task2 = container.GetInstances<ITask<SomeGeneric2>();
task2.Initialize();
var task3 = container.GetInstances<ITask<SomeGeneric3>();
task3.Initialize();
Ouch. You can see how every time I add or remove an item from the container registration, I now need to also update another section of code. Two places of modification for one change, I'm breaking multiple design issues.
You might say why am I asking the container for this? Well this is in the startup area, but let's explore if I wasn't.
So I will use constructor injection to illustrate why this is bad. First let's see my example as construction injection.
public class SomeClass {
public SomeClass(IEnumerable<ITask> tasks){}
}
Nice and clean.
Now, let's switch back to my understanding of the accepted answer's view (again prior to update 2):
public class SomeClass {
public SomeClass(ITask<Generic1> task1,
ITask<Generic2> task2,
ITask<Generic3> task3
) {}
}
Ouch. Everytime I have to edit multiple areas of code, and let's not even get started at how poor this design is.
What's the lesson here? I'm not the smartest guy in the world. I maintain (or try to maintain :)) multiple frameworks and I don't try to pretend I know more than or better than others. My sense of design might be skewed or I might be limiting others in some unknown way that I have not even thought of yet. I'm sure the author means well when he gives advice on design, but in some cases it may come across annoying (and a little condescending), especially for those of us that know what we are doing.
Update 3
So the question was answered in Update 2 from the maintainer. I was trying to use RegisterAll because it hadn't occurred to me that I could just use Register<IEnumerable<T>> (and unfortunately the documentation didn't point this out). It seems totally obvious now, but when people are making the jump from other IoC frameworks, they are carrying some baggage with them and may miss this awesome simplification in design! I missed it, with 4 other DI containers under my belt. Hopefully he adds it to the documentation or calls it out a little better.
From your first example (using the List<Func<IFileWatcher>>) I understand that you want to register a collection of transient filewatchers. In other words, every time you iterate the list, a new file watcher instance should be created. This is of course very different than registering a list with two (singleton) filewatchers (the same instances that are always returned). There's however some ambiguity in your question, since in the extension method you seem to register them as singleton. For the rest of my answer, I'll assume you want transient behavior.
The common use case for which RegisterAll is created, is to register a list of implementations for a common interface. For instance an application that has multiple IEventHandler<CustomerMoved> implementations that all need to be triggered when a CustomerMoved event got raised. In that case you supply the RegisterAll method with list of System.Type instances, and the container is completely in control of wiring those implementations for you. Since the container is in control of the creation, the collection is called 'container-controlled'.
The RegisterAll however, merely forward the creation back to the container, which means that by default the list results in the creation of transient instances (since unregistered concrete types are resolved as transient). This seems awkward, but it allows you to register a list with elements of different lifestyles, since you can register each item explicitly with the lifestyle of choice. It also allows you to supply the RegisterAll with abstractions (for instance typeof(IService)) and that will work as well, since the request is forwarded back to the container.
Your use case however is different. You want to register a list of elements of the exact same type, but each with a different configuration value. And to make things more difficult, you seem to want to register them as transients instead of singletons. By not-passing the RegisterAll a list of types, but an IEnumerable<TService> the container does not create and auto-wire those types , we call this a 'container-uncontrolled' collection.
Long story short: how do we register this? There are multiple ways to do this, but I personally like this approach:
string[] triggers = new[]
{
#".\Triggers\TriggerWatch\SomeTrigger.txt",
#".\Triggers\TriggerWatch\SomeOtherTrigger.txt"
};
container.RegisterAll<IFileWatcher>(
from trigger in triggers
select new FileWatcher(trigger,
container.GetInstance<IFileSystem>())
);
Here we register a LINQ query (which is just an IEnumerable<T>) using the RegisterAll method. Every time someone resolves an IEnumerable<IFileWatcher> it returns that same query, but since the select of that query contains a new FileWatcher, on iteration new instances are always returned. This effect can be seen using the following test:
var watchers = container.GetAllInstances<IFileWatcher>();
var first1 = watchers.First();
var first2 = watchers.First();
Assert.AreNotEqual(first1, first2, "Should be different instances");
Assert.AreEqual(first1.Trigger, first2.Trigger);
As this test shows, we resolve the collection once, but every time we iterate it (.First() iterates the collection), a new instance is created, but both instances have the same #".\Triggers\TriggerWatch\SomeTrigger.txt" value.
So as you can see, there is not limitation that prevents you from doing this effectively. However, you might need to think differently.
I'm also curious why there is a need for RegisterAll to exist in the
first place.
This is a very explicit design decision. You are right that most other containers just allow you to do a bunch of registrations of the same type and when asked for a collection, all registrations are returned. Problem with this is that it is easy to accidentally register a type again and this is something I wanted to prevent.
Further more, all containers have different behavior of which registration is returned when requesting for a single instance instead of requesting the collection. Some return the first registration others return the last. I wanted to prevent this ambiguity as well.
Last but not least, please note that registering collections of items of the same type should usually be an exception. In my experience 90% of the time when developers want to register multiple types of the same abstraction, there is some ambiguity in their design. By making registering collections explicit, I hoped to let this stick out.
What I will not accept is that I need to change and adapt my
architecture to meet the limitations of some tool.
I do agree with this. Your architecture should be leading, not the tools. You should chose your tools accordingly.
But please do note that Simple Injector has many limitations and most of those limitations are chosen deliberately to stimulate users to have a clean design. For instance, every time you violate one of the SOLID principles in your code, you will have problems. You will have problems keeping your code flexible, your tests readable, and your Composition Root maintainable. This in fact holds for all DI containers, but perhaps even more for Simple Injector. This is deliberate and if the developers are not interested in applying the SOLID principles and want a DI container that just works in any given circumstance, perhaps Simple Injector is not the best tool for the job. For instance, applying Simple Injector to a legacy code base can be daunting.
I hope this gives some perspective on the design of Simple Injector.
UPDATE
If you need singletons instead, this is even simpler. You can register them as follows:
var fs = new RealFileSystem();
container.RegisterSingle<IFileSystem>(fs);
container.RegisterAll<IFileWatcher>(
new FileWatcher(#".\Triggers\TriggerWatch\SomeTrigger.txt", fs),
new FileWatcher(#".\Triggers\TriggerWatch\SomeOtherTrigger.txt", fs)
);
UPDATE 2
You explicitly asked for RegisterAll<T>(Func<T>) support to lazily create a collection. In fact there already is support for this, just by using RegisterSingle<IEnumerable<T>>(Func<IEnumerable<T>>), as you can see here:
container.RegisterSingle<IEnumerable<IFileWatcher>>(() =>
{
return
from
var list = new List<IFileWatcher>
{
new FileWatcher(#".\Triggers\TriggerWatch\SomeTrigger.txt", container.GetInstance<IFileSystem>()),
new FileWatcher(#".\Triggers\TriggerWatch\SomeOtherTrigger.txt", container.GetInstance<IFileSystem>())
};
return list.AsReadOnly();
});
The RegisterAll<T>(IEnumerable<T>) is in fact a convenient overload that eventually calls into RegisterSingle<IEnumerable<T>>(collection).
Note that I explicitly return a readonly list. This is optional, but is an extra safety mechanism that prevents the collection from being altered by any application code. When using RegisterAll<T> collections are automatically wrapped in a read-only iterator.
The only catch with using RegisterSingle<IEnumerable<T>> is that the container will not iterate the collection when you call container.Verify(). However, in your case this would not be a problem, since when an element of the collection fails to initialize the call to GetInstance<IEnumerable<IFileWatcher>> will fail as well and with that the call to Verify().
UPDATE 3
I apologize if I gave to the impression that I meant your design is wrong. I have no way of knowing this. Since you explicitly asked about why some features where missing, I tried my best to explain the rationale behind this. That doesn't mean however that I think your design is bad, since there is no way for me of knowing.
let's switch back to what that would look like with the maintainer's view of good design
I'm not sure why you think that this is my view on good design? Having a SomeClass with a constructor that need to be changed every time you add a task in the system is definitely not a good design. We can safely agree on this. That breaks OCP. I would never advice anyone to do such thing. Besides having a constructor with many arguments is a design smell at least. The next minor release of Simple Injector even adds a diagnostic warning concerning types with too many dependencies since this often is an indication of a SRP violation. But again see how Simple Injector tries to ‘help’ developers here by providing guidance.
Still however, I do promote the use of generic interfaces, and that’s a case that the Simple Injector design is optimized for especially. An ITask interface is a good example of this. In that case, the ITask<T> will often be an abstraction over some business behavior you wish to execute, and the T is a parameter object that holds all parameters of the operation to execute (you can see it as a message with a message handler). This however is only useful when a consumer needs to execute an operation with a specific set of parameters (a specific version of T), for instance it wants to execute ITask<ShipOrder>. Since you are executing a batch of all tasks without supplying parameter, a design based on ITask<T> would probably be awkward.
But let's assume for a second that it is appropriate. Let's assume this, so I can explain how Simple Injector is optimized in this case. At the end of this update, I’ll show you how Simple Injector might still be able to help in your case, so hold your breath. In your code sample, you register your generic tasks as follows:
container.Register<ITask<SomeGeneric1>(() => new FileWatchTask(container.GetInstance<IFileSystem>(),container.GetInstance<IMessageSubscriptionManagerService>(),configuration,container.GetAllInstances<IFileWatcher>()));
container.Register<ITask<SomeGeneric2>(() => new DefaultFtpTask(container.GetInstance<IFtpClient>(),container.GetInstance<IFileSystem>()));
container.Register<ITask<SomeGeneric3>(() => new DefaultImportFilesTask(container.GetInstance<IFileSystem>()));
This is a rather painful way of registering all tasks in the system, since every time you change a constructor of a task implementation, you'll have to change this code. Simple Injector allows you to auto-wire types by looking at their constructor. In other words, Simple Injector allows you to simplify this code to the following:
container.Register<ITask<SomeGeneric1>, FileWatchTask>();
container.Register<ITask<SomeGeneric2>, DefaultFtpTask>();
container.Register<ITask<SomeGeneric3>, DefaultImportFilesTask>();
This already is much more maintainable, results in better performance and allows you to do add other interesting scenarios later on such as context based injection (since Simple Injector is in control of the whole object graph). This is the advised way of registering things in Simple Injector (prevent the use of a Func if possible).
Still, when having a architecture where a task is the center element, you would probably add new task implementations quite regularly. This will result in having dozens of registration lines and having to go back to this code to add a line every time you add a task. Simple Injector however has a batch registration feature that allows you to shrink this back to one single line of code:
// using SimpleInjector.Extensions;
container.RegisterManyForOpenGeneric(typeof(ITask<>), typeof(ITask<>).Assembly);
By calling this line, the container will search for all ITask<T> implementations that are located in the interface’s assembly and it will register them for you. Since this is done at runtime using reflection, the line does not have to be altered when new tasks are added to the system.
And since you're talking about the OCP, IMO Simple Injector has great support for the OCP. At some points it even beats all other frameworks out there. When I think about OCP, I particularly think about one specific pattern: the decorator pattern. The decorator pattern is a very important pattern to use when applying the OCP. Cross-cutting concerns for instance should not be added by changing some piece of business logic itself, but can best be added by wrapping classes with decorators. With Simple Injector, a decorator can be added with just a single line of code:
// using SimpleInjector.Extensions;
container.RegisterDecorator(typeof(ITask<>), typeof(TransactionTaskDecorator<>));
This ensures that a (transient) TransactionTaskDecorator<T> is wrapped around all ITask<T> implementations when they got resolved. Those decorators are integrated in the container’s pipeline, which means that they can have dependencies of their own, can have initializers, and can have a specific lifestyle. And decorators can be stacked easily:
container.RegisterDecorator(typeof(ITask<>), typeof(TransactionTaskDecorator<>));
container.RegisterDecorator(typeof(ITask<>), typeof(DeadlockRetryTaskDecorator<>));
This wraps all tasks in a transaction decorator and wraps that transaction decorator again in a deadlock retry decorator. And you can even apply decorators conditionally:
container.RegisterDecorator(typeof(ITask<>), typeof(ValidationTaskDecorator<>),
context => ShouldApplyValidator(context.ServiceType));
And if your decorator has a generic type constraint, Simple Injector would automatically apply the decorator when the generic type constraints match, nothing you have to do about this. And since Simple Injector generates expression trees and compiles them down to delegates, this is all a one-time cost. That doesn’t mean it’s for free, but you’ll pay only once and not per resolve.
There's no other DI library that makes adding decorators as easy and flexible as Simple Injector does.
So this is where Simple Injector really shines, but that doesn't help you much :-). Generic interfaces don't help you in this case, but still, even in your case, you might be able make your registration more maintainable. If you have many task implementations in the system (that is, much more than three), you might be able to automate things like this:
var taskTypes = (
from type in typeof(ITask).Assemby.GetTypes()
where typeof(ITask).IsAssignableFrom(type)
where !type.IsAbstract && !type.IsGenericTypeDefinition
select type)
.ToList();
// Register all as task types singleton
taskTypes.ForEach(type => container.Register(type, type, Lifestyle.Singleton));
// registers a list of all those (singleton) tasks.
container.RegisterAll<ITask>(taskTypes);
Alternatively, with Simple Injector 2.3 and up, you can pass in Registration instances directly into the RegisterAll method:
var taskTypes =
from type in typeof(ITask).Assemby.GetTypes()
where typeof(ITask).IsAssignableFrom(type)
where !type.IsAbstract && !type.IsGenericTypeDefinition
select type;
// registers a list of all those (singleton) tasks.
container.RegisterAll(typeof(ITask),
from type in taskTypes
select Lifestyle.Singleton.CreateRegistration(type, type, container));
This does assume however that all those task implementations have a single public constructor and all constructor arguments are resolvable (no configuration values such as int and string). If this is not the case, there are ways to change the default behavior of the framework, but if you want to know anything about this, it would be better to move that discussion to a new SO question.
Again, I’m sorry if I have annoyed you, but I rather annoy some developers than missing the opportunity in helping a lot others :-)

Delegates (Lambda expressions) Vs Interfaces and abstract classes

I have been looking for a neat answer to this design question with no success. I could not find help neither in the ".NET Framework design guidelines" nor in the "C# programing guidelines".
I basically have to expose a pattern as an API so the users can define and integrate their algorithms into my framework like this:
1)
// This what I provide
public abstract class AbstractDoSomething{
public abstract SomeThing DoSomething();
}
Users need to implementing this abstract class, they have to implement the DoSomething method (that I can call from within my framework and use it)
2)
I found out that this can also acheived by using delegates:
public sealed class DoSomething{
public String Id;
Func<SomeThing> DoSomething;
}
In this case, a user can only use DoSomething class this way:
DoSomething do = new DoSomething()
{
Id="ThisIsMyID",
DoSomething = (() => new Something())
}
Question
Which of these two options is best for an easy, usable and most importantly understandable to expose as an API?
EDIT
In case of 1 : The registration is done this way (assuming MyDoSomething extends AbstractDoSomething:
MyFramework.AddDoSomething("DoSomethingIdentifier", new MyDoSomething());
In case of 2 : The registration is done like this:
MyFramework.AddDoSomething(new DoSomething());
Which of these two options is best for an easy, usable and most importantly understandable to expose as an API?
The first is more "traditional" in terms of OOP, and may be more understandable to many developers. It also can have advantages in terms of allowing the user to manage lifetimes of the objects (ie: you can let the class implement IDisposable and dispose of instances on shutdown, etc), as well as being easy to extend in future versions in a way that doesn't break backwards compatibility, since adding virtual members to the base class won't break the API. Finally, it can be simpler to use if you want to use something like MEF to compose this automatically, which can simplify/remove the process of "registration" from the user's standpoint (as they can just create the subclass, and drop it in a folder, and have it discovered/used automatically).
The second is a more functional approach, and is simpler in many ways. This allows the user to implement your API with far fewer changes to their existing code, as they just need to wrap the necessary calls in a lambda with closures instead of creating a new type.
That being said, if you're going to take the approach of using a delegate, I wouldn't even make the user create a class - just use a method like:
MyFramework.AddOperation("ThisIsMyID", () => DoFoo());
This makes it a little bit more clear, in my opinion, that you're adding an operation to the system directly. It also completely eliminates the need for another type in your public API (DoSomething), which again simplifies the API.
I would go with the abstract class / interface if:
DoSomething is required
DoSomething will normally get really big (so DoSomething's implementation can be splited into several private / protected methods)
I would go with delegates if:
DoSomething can be treated as an event (OnDoingSomething)
DoSomething is optional (so you default it to a no-op delegate)
Though personally, if in my hand, I would always go by Delegate Model. I just love the simplicity and elegance of higher order functions. But while implementing the model, be careful about memory leaks. Subscribed events are one of the most common reasons of memory leaks in .Net. This means, suppose if you have an object that has some events exposed, the original object would never be disposed until all events are unsubscribed since event creates a strong reference.
As is typical for most of these types of questions, I would say "it depends". :)
But I think the reason for using the abstract class versus the lambda really comes down to behavior. Usually, I think of the lambda being used as a callback type of functionality -- where you'd like something custom happen when something else happens. I do this a lot in my client-side code:
- make a service call
- get some data back
- now invoke my callback to handle that data accordingly
You can do the same with the lambdas -- they are specific and are targeted for very specific situations.
Using the abstract class (or interface) really comes down to where your class' behavior is driven by the environment around it. What's happening, what client am I dealing with, etc.? These larger questions could suggest that you should define a set of behaviors and then allow your developers (or consumers of your API) to create their own sets of behavior based upon their requirements. Granted, you could do the same with lambdas, but I think it would be more complex to develop and also more complex to clearly communicate to your users.
So, I guess my rough rule of thumb is:
- use lambdas for specific callback or side-effect customized behaviors;
- use abstract classes or interfaces to provide a mechanism for object behavior customization (or at least the majority of the object's primary behavior).
Sorry I can't give you a clear definition, but I hope this helps. Good luck!
A few things to consider :
How many different functions/delegates would need to be over-ridden? If may functions, inheretance will group "sets" of overrides in an easier to understand way. If you have a single "registration" function, but many sub-portions can be delegated out to the implementor, this is a classic case of the "Template" pattern, which makes the most sense to be inherited.
How many different implementations of the same function will be needed? If just one, then inheretance is good, but if you have many implementations a delegate might save overhead.
If there are multiple implementations, will the program need to switch between them? Or will it only use a single implementation. If switching is required, delegates might be easier, but I would caution this, especially depending on the answer to #1. See the Strategy Pattern.
If the override needs access to any protected members, then inheretance. If it can rely only on publics, then delegate.
Other choices would be events, and extension methods as well.

C# Object construction outside the constructor

When it comes to designing classes and "communication" between them, I always try to design them in such way that all object construction and composing take place in object constructor. I don't like the idea of object construction and composition taking place from outside, like other objects setting properties and calling methods on my object to initialize it. This especially gets ugly when multiple object try to do thisto your object and you never know in what order your props\methods will be executed.
Unforunatly I stumbl on such situations quite often, especially now with the growing popularity of dependecy injection frameworks, lots of libraries and frameworks rely on some kind of external object initialization, and quite often require not only constructor injection on our object but property injection too.
My question are:
Is it ok to have objects that relly on some method, or property to be called on them after which they can consider them initialzied?
Is ther some kind of pattern for situations when your object acting is receiver, and must support multiple interfaces that call it, and the order of these calls does matter? (something better than setting flags, like ThisWasDone, ThatWasCalled)
Is it ok to have objects that relly on some method, or property to be called on them after which they can consider them initialzied?
No. Init methods are a pain since there is no guarantee that they will get called. A simple solution is to switch to interfaces and use factory or builder pattern to compose the implementation.
#Mark Seemann has written a article about it: http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling.aspx
Is there some kind of pattern for situations when your object acting is receiver, and must support multiple interfaces that call it, and the order of these calls does matter? (something better than setting flags, like ThisWasDone, ThatWasCalled)
Builder pattern.
I think it is OK, but there are implications. If this is an object to be used by others, you need to ensure that an exception is thrown any time a method or property is set or accessed and the initialization should have been called but isn't.
Obviously it is much more convenient and intuitive if you can take care of this in the constructor, then you don't have to implement these checks.
I don't see anything wrong in this. It may be not so convinient, but you can not ALWAYS use initialization in ctor, like you can not alwats drive under green light. These are dicisions that you made based on your app requirements.
It's ok. Immagine if your object, for example, need to read data from TCP stream or a file that ciuld be not present or corrupted. Raise an exception from ctor is baaad.
It's ok. If you think, for example, about some your DSL language compiler, it can looks like:
A) find all global variables and check if there mem allocation sum sutisfies your device requierements
B) parse for errors
C) check for self cycling
And so on...
Hoe this helps.
Answering (1)
Why not? An engine needs the driver because this must enter the key for the car, and later power-on. Will a car do things like detecting current speed if engine is stopeed? Or Will the car show remaining oil without powering-on it?
Some programming goals won't be able to have their actors initialized during its object construction, and this isn't because it's a non-proper way of doing things but because it's the natural, regular and/or semantically-wise way of representing its whole behavior.
Answering (2)
A decent class usage documentation will be your best friend. Like answer to (1), there're some things in this world that should be done in order to get them done rightly, and it's not a problem but a requirement.
Checking objects' state using flags isn't a problem too, it's a good way of adding reliability to your object models, because its own behaviors and consumers of them will be aware about if things got done as expected or not.
First of all, Factory Method.
public class MyClass
{
private MyClass()
{
}
public Create()
{
return new MyClass();
}
}
Second of all, why do you not want another class creating an object for you? (Factory)
public class MyThingFactory
{
IThing CreateThing(Speed speed)
{
if(speed == Speed.Fast)
{
return new FastThing();
}
return new SlowThing();
}
}
Third, why do multiple classes have side effects on new instances of your class? Don't you have declarative control over what other classes have access to your object?

Isn't there a point where encapsulation gets ridiculous?

For my software development programming class we were supposed to make a "Feed Manager" type program for RSS feeds. Here is how I handled the implementation of FeedItems.
Nice and simple:
struct FeedItem {
string title;
string description;
string url;
}
I got marked down for that, the "correct" example answer is as follows:
class FeedItem
{
public:
FeedItem(string title, string description, string url);
inline string getTitle() const { return this->title; }
inline string getDescription() const { return this->description; }
inline string getURL() const { return this->url; }
inline void setTitle(string title) { this->title = title; }
inline void setDescription(string description){ this->description = description; }
inline void setURL(string url) { this->url = url; }
private:
string title;
string description;
string url;
};
Now to me, this seems stupid. I honestly can't believe I got marked down, when this does the exact same thing that mine does with a lot more overhead.
It reminds me of how in C# people always do this:
public class Example
{
private int _myint;
public int MyInt
{
get
{
return this._myint;
}
set
{
this._myint = value;
}
}
}
I mean I GET why they do it, maybe later on they want to validate the data in the setter or increment it in the getter. But why don't you people just do THIS UNTIL that situation arises?
public class Example
{
public int MyInt;
}
Sorry this is kind of a rant and not really a question, but the redundancy is maddening to me. Why are getters and setters so loved, when they are unneeded?
It's an issue of "best practice" and style.
You don't ever want to expose your data members directly. You always want to be able to control how they are accessed. I agree, in this instance, it seems a bit ridiculous, but it is intended to teach you that style so you get used to it.
It helps to define a consistent interface for classes. You always know how to get to something --> calling its get method.
Then there's also the reusability issue. Say, down the road, you need to change what happens when somebody accesses a data member. You can do that without forcing clients to recompile code. You can simply change the method in the class and guarantee that the new logic is utilized.
Here's a nice long SO discussion on the subject: Why use getters and setters.
The question you want to ask yourself is "What's going to happen 3 months from now when you realize that FeedItem.url does need to be validated but it's already referenced directly from 287 other classes?"
The main reason to do this before its needed is for versioning.
Fields behave differently than properties, especially when using them as an lvalue (where it's often not allowed, especially in C#). Also, if you need to, later, add property get/set routines, you'll break your API - users of your class will need to rewrite their code to use the new version.
It's much safer to do this up front.
C# 3, btw, makes this easier:
public class Example
{
public int MyInt { get; set; }
}
I absolutely agree with you. But in life you should probably do The Right Thing: in school, it's to get good marks. In your workplace it's to fulfill specs. If you want to be stubborn, then that's fine, but do explain yourself -- cover your bases in comments to minimize the damage you might get.
In your particular example above I can see you might want to validate, say, the URL. Maybe you'd even want to sanitize the title and the description, but either way I think this is the sort of thing you can tell early on in the class design. State your intentions and your rationale in comments. If you don't need validation then you don't need a getter and setter, you're absolutely right.
Simplicity pays, it's a valuable feature. Never do anything religiously.
If something's a simple struct, then yes it's ridiculous because it's just DATA.
This is really just a throwback to the beginning of OOP where people still didn't get the idea of classes at all. There's no reason to have hundreds of get and set methods just in case you might change getId() to be an remote call to the hubble telescope some day.
You really want that functionality at the TOP level, at the bottom it's worthless. IE you would have a complex method that was sent a pure virtual class to work on, guaranteeing it can still work no matter what happens below. Just placing it randomly in every struct is a joke, and it should never be done for a POD.
Maybe both options are a bit wrong, because neither version of the class has any behaviour. It's hard to comment further without more context.
See http://www.pragprog.com/articles/tell-dont-ask
Now lets imagine that your FeedItem class has become wonderfully popular and is being used by projects all over the place. You decide you need (as other answers have suggested) validate the URL that has been provided.
Happy days, you have written a setter for the URL. You edit this, validate the URL and throw an exception if it is invalid. You release your new version of the class and everyone one using it is happy. (Let's ignored checked vs unchecked exceptions to keep this on-track).
Except, then you get a call from an angry developer. They were reading a list of feeditems from a file when their application starts up. And now, if someone makes a little mistake in the configuration file your new exception is thrown and the whole system doesn't start up, just because one frigging feed item was wrong!
You may have kept the method signature the same, but you have changed the semantics of the interface and so it breaks dependant code. Now, you can either take the high-ground and tell them to re-write their program right or you humbly add setURLAndValidate.
Keep in mind that coding "best practices" are often made obsolete by advances in programming languages.
For example, in C# the getter/setter concept has been baked into the language in the form of properties. C# 3.0 made this easier with the introduction of automatic properties, where the compiler automatically generates the getter/setter for you. C# 3.0 also introduced object initializers, which means that in most cases you no longer need to declare constructors which simply initialize properties.
So the canonical C# way to do what you're doing would look like this:
class FeedItem
{
public string Title { get; set; } // automatic properties
public string Description { get; set; }
public string Url { get; set; }
};
And the usage would look like this (using object initializer):
FeedItem fi = new FeedItem() { Title = "Some Title", Description = "Some Description", Url = "Some Url" };
The point is that you should try and learn what the best practice or canonical way of doing things are for the particular language you are using, and not simply copy old habits which no longer make sense.
As a C++ developer I make my members always private simply to be consistent. So I always know that I need to type p.x(), and not p.x.
Also, I usually avoid implementing setter methods. Instead of changing an object I create a new one:
p = Point(p.x(), p.y() + 1);
This preserves encapsulation as well.
There absolutely is a point where encapsulation becomes ridiculous.
The more abstraction that is introduced into code the greater your up-front education, learning-curve cost will be.
Everyone who knows C can debug a horribly written 1000 line function that uses just the basic language C standard library. Not everyone can debug the framework you've invented. Every introduced level encapsulation/abstraction must be weighed against the cost. That's not to say its not worth it, but as always you have to find the optimal balance for your situation.
One of the problems that the software industry faces is the problem of reusable code. Its a big problem. In the hardware world, hardware components are designed once, then the design is reused later when you buy the components and put them together to make new things.
In the software world every time we need a component we design it again and again. Its very wasteful.
Encapsulation was proposed as a technique for ensuring that modules that are created are reusable. That is, there is a clearly defined interface that abstracts the details of the module and make it easier to use that module later. The interface also prevents misuse of the object.
The simple classes that you build in class do not adequately illustrate the need for the well defined interface. Saying "But why don't you people just do THIS UNTIL that situation arises?" will not work in real life. What you are learning in you software engineering course is to engineer software that other programmers will be able to use. Consider that the creators of libraries such as provided by the .net framework and the Java API absolutely require this discipline. If they decided that encapsulation was too much trouble these environments would be almost impossible to work with.
Following these guidelines will result in high quality code in the future. Code that adds value to the field because more than just yourself will benefit from it.
One last point, encapsulation also makes it possible to adequately test a module and be resonably sure that it works. Without encapsulation, testing and verification of your code would be that much more difficult.
Getters/Setters are, of course, good practice but they are tedious to write and, even worse, to read.
How many times have we read a class with half a dozen member variables and accompanying getters/setters, each with the full hog #param/#return HTML encoded, famously useless comment like 'get the value of X', 'set the value of X', 'get the value of Y', 'set the value of Y', 'get the value of Z', 'set the value of Zzzzzzzzzzzzz. thump!
This is a very common question: "But why don't you people just do THIS UNTIL that situation arises?".
The reason is simple: usually it is much cheaper not to fix/retest/redeploy it later, but to do it right the first time.
Old estimates say that maintenance costs are 80%, and much of that maintenance is exactly what you are suggesting: doing the right thing only after someone had a problem. Doing it right the first time allows us to concentrate on more interesting things and to be more productive.
Sloppy coding is usually very unprofitable - your customers are unhappy because the product is unreliable and they are not productive when the are using it. Developers are not happy either - they spend 80% of time doing patches, which is boring. Eventually you can end up losing both customers and good developers.
I agree with you, but it's important to survive the system. While in school, pretend to agree. In other words, being marked down is detrimental to you and it is not worth it to be marked down for your principles, opinions, or values.
Also, while working on a team or at an employer, pretend to agree. Later, start your own business and do it your way. While you try the ways of others, be calmly open-minded toward them -- you may find that these experiences re-shape your views.
Encapsulation is theoretically useful in case the internal implementation ever changes. For example, if the per-object URL became a calculated result rather than a stored value, then the getUrl() encapsulation would continue to work. But I suspect you already have heard this side of it.

Categories