I want to have some factory (doesn't matter if Abstract Factory pattern or Factory Method - looks like the second is specific form of the first one. In my case only one object should be created). The thing is that although created products are similar, they depends on some arguments.
How to prepare this architecture in compliance with design patterns?
Current approach below
public abstract class Product {}
public class MyProduct : Product
{
public bool Abc { get; set; }
}
public class YourProduct : Product {}
public abstract class ProductFactory
{
//in some cases parameter not in use
public abstract Product Create(HelpData additionalData);
}
public class MyProductFactory : ProductFactory
{
public override Product Create(HelpData additionalData)
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory : ProductFactory
{
//unused parameter
public override Product Create(HelpData additionalData)
{
return new YourProduct();
}
}
public class HelpData
{
public bool SomethingImportantForMyProduct { get; set; }
}
EDIT
I see it's not clear so will repeat.
Usually I'm not using patterns just because of using them. But this problem seems not to be border case. Looks rather quite frequent. Going further I believe there's design pattern suitable to this, but I'm not sure which one. For now looks like abstract factory is not right choice.
Don't use design-patterns because you're using design-patterns. Always have in mind when to use one and when not. In your circumstances at least the abstract factory-pattern is wrong, as it assumes all factories to work with the same parameters. So if you have different parameters you surely need different factories.
However there's no way for the abstract factory to guess how to get an instance of a HelpData in some case but not in the other, so either pass it to every abstract factory or completely omit this further abstraction and stay with two independent factories:
public abstract class Product {}
public class MyProduct : Product
{
public bool Abc { get; set; }
}
public class YourProduct : Product {}
public class MyProductFactory
{
public Product Create(HelpData additionalData)
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory
{
//unused parameter
public Product Create()
{
return new YourProduct();
}
}
public class HelpData
{
public bool SomethingImportantForMyProduct { get; set; }
}
Exposing a parameter only used within one factory to all factories isn't a good idea.
Besides this just imagine you don't have factories but any other classes that have a Create-method, where one needs a parameter, but the other one does not. Why should those two classes derive from the same base-class (in your case the abstract factory), when the don't have any common members? There's apparently no reason for this, so don't overcomplicate things just for the sake of using a pattern which doesn't fit.
Depending on where and how you retrieve additional data you could inject that data to the factory which will use it to construct the object:
public abstract class ProductFactory
{
public abstract Product Create();
}
public class MyProductFactory : ProductFactory
{
private HelpData additionalData;
public MyProductFactory(HelpData additionalData)
{
this.additionalData = additionalData;
}
public override Product Create()
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory : ProductFactory
{
public override Product Create()
{
return new YourProduct();
}
}
Instead of passing HelpData to constructor of a factory you could inject a service that knows how to retrieve HelpData specific to the object being created. You could pass some other parameter to Create method if it is used for both factories.
I have also googled a bit and found good answer that explains why not https://stackoverflow.com/a/6241219/2138959. Passing a dictionary or a type that has property of dictionary type is also and option but in such approaches client has too much knowledge of a type it want to be created to use abstract factory.
Related
I have the following builder/factory which abstracts a serializeable model from a class.
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
}
}
And I have a concrete implementation of IFooModel like so:
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
}
public class ConcreteFooModel : IFooModel
{
public string AbstractedData1 { get; set; }
public string AbstractedData2 { get; set; }
public int AbstractedData3 { get; set; }
public bool ExtraData1 { get; set; }
}
Now arises the issue, I am struggling to find a way to not reference any concrete implementations in my builder/factory method, e.g.
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
var model = new ConcreteFooModel(someClass.data1, someClass.data1); // Aaargh
}
}
Something about this code is smelly to me, perhaps this is the only way, but I don't like the idea of being forced into referencing the concrete implementation to instantiate the data class, IFooModel.
This gets more complex if I now introduce another data holder interface into the IFooModel
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
IBarData BarData { get; }
}
public interface IBarData
{
// some data in here
}
Forcing me then to create another concrete reference for the nested interface
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
Is there a better way to do this while still sticking to the SOLID principle and IoC?
What's important is to look at this from the perspective of the class that depends on IFooModel That's probably the first place where you want to prevent coupling.
You can accomplish that by injecting the factory into the class that needs it, like this:
public class NeedsFooFactory
{
private readonly IFooBarFactory _factory;
public NeedsFooFactory(IFooBarFactory fooBarFactory)
{
_factory = factory;
}
public void WhatEverThisClassDoes(IFoo foo)
{
var fooBar = _factory.Create(foo);
// Do something
}
}
Now the class that depends on the factory is decoupled from any implementation. You can substitute or mock another implementation of the factory that returns a different implementation of IFooModel.
Something to stop and think about at this point: Do you need an abstraction for ConcreteFooModel at all? If it's just a class that holds data then maybe you don't.
Getting back to the factory: Now that you can replace the factory with any implementation, this becomes less of a concern:
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
This implementation of the factory returns a specific concrete implementation of IFooModel. Is that bad? At some level classes are going to deal with concrete classes. In this case I think it's okay because this factory is doing what it's supposed to do. You don't have to worry that it's coupled to ConcreteFooModel. If you want a class that returns a different implementation you could create a different implementation of IFooBarFactory that returns a different implementation of IFooModel.
Again, this becomes even less of a concern if you question whether you need an abstraction for your foo model. Quite possibly the concrete class is all you need, and what matters is that you can have different implementations of the factory that populates it.
I've used this pattern many times in a variety of places, usually alongside a plugin pattern.
Some example ways I've used it are for messaging systems, such as creating subscribers to various types of unrelated messages. I've also used it for generic integration workflows that each need a differently shaped context object.
Basically the pattern consists of defining a blank marker interface for a message or context. Then defining a high level workflow interface that works with the message/context interface. You can then use a factory to get a concrete instance of the workflow, and if needed, the workflow can also be responsible for parsing its message / context from a common data format.
Next, you create an abstract generic base workflow whose responsibilty is just to map calls to the interface methods, which pass around the useless marker interface, into calls to abstract methods that take the concrete version of the message/context.
Hopefully that makes sense. I'll provide a code example below. I'd love to know if this pattern has a name because I've noticed that I've used it about 4-5 times now. Also, I'm just fleshing out how to explain the pattern, so if anything about my explanation doesn't make sense please let me know that as well.
The main point is that you can have multiple classes with different method signatures that can still be called via a common interface:
End Result
public class ConcreteA : Base<MessageA>
{
public void Process(MessageA message){...}
public MessageA Parse(IDictionary data){...}
}
public class ConcreteB : Base<MessageB>
{
public void Process(MessageB message){...}
public MessageB Parse(IDictionary data){...}
}
//And both can by called by...
public void Main(){
var data = GetDataFromIntegrationSource(someContext);
IWorkflow impl = Factory.GetConcrete(someContext);
//So in your classes you're able to work with strongly typed parameters,
//But in the consuming code you still can use a common interface
//Consuming code never even knows what the strong type is.
IMessage msg = impl.Parse(data);
impl.Process(msg);
}
FULL EXAMPLE
High Level Interfaces
public interface IGenericeMarkerInterface
{
}
public interface IGenericWorkflow
{
void Process(IGenericeMarkerInterface messageOrContext);
IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat);
}
Abstract Base for Mapping to Concrete Methods
public abstract class GenericWorkflowBase<T> : IGenericWorkflow where T : IGenericeMarkerInterface
{
public void Process(IGenericeMarkerInterface messageOrContext)
{
Process((T)messageOrContext);
}
public IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat)
{
return DoParse(commonDataFormat);
}
public abstract void Process(T messageOrContext);
public abstract T DoParse(IDictionary<string, string> commonDataFormat);
}
Mapping Attributes
public class MappingAttributeUsedByFactoryAttribute : Attribute
{
public WorkflowType SomePropertyForMapping { get; set; }
}
Concrete Implementations
public class SomeRandomlyShapedMessageOrContext : IGenericeMarkerInterface
{
public int ID { get; set; }
public string Data { get; set; }
}
[MappingAttributeUsedByFactory(WorkflowType.IntegrationPartnerB)]
public class ConcreteWorkflow : GenericWorkflowBase<SomeRandomlyShapedMessageOrContext>
{
public override void Process(SomeRandomlyShapedMessageOrContext messageOrContext)
{
//TODO: process the strongly typed message
}
public override SomeRandomlyShapedMessageOrContext DoParse(IDictionary<string, string> commonDataFormat)
{
//TODO: parse the common data into the strongly typed message
}
}
Factory
public static class WorkflowFactory
{
public static IGenericWorkflow Get(WorkflowType workflow)
{
//TODO: find the concrete workflow by inspecting attributes
}
}
Example Usage
public static class Program
{
public static void Main(string[] args)
{
//this could be driven by a UI or some contextual data
var someSortOfWorkflowIdentifier = (WorkflowType)args[0];
var data = GetSomeDictionaryOfData();
var workflow = WorkflowFactory.Get(someSortOfWorkflowIdentifier);
workflow.Process(workflow.Parse(data));
}
}
Yes, it's exactly same as you named it: Marker interface
i have another question open here on SO and after thinking about it, i may be approaching this in the wrong way.
i have 4 classes, that have the same properties and methods.
some of the classes, have their own properties and methods ( not overrides of the existing ones ).
currently i create each class as:
public class ClassOne
{
public ClassOne()
{
}
public int ID {get;set;}
// More properties here
public void Set(){
// Do Stuff to save this
}
// More Methods here
}
cant i create one class that will generate all of the 4 classes?
and in the classes themselfs i only create specific properties/methods for that class?
repeating the code seems very odd to me, im sure there must be a way to do this, just dont know how.
Your situation is one of the main reasons why inheritance was invented. So with that, you can write
public class Base
{
// Properties and methods common to all
}
public class ClassOne : Base
{
// Properties and methods specific to ClassOne
}
public class ClassTwo : Base
{
// Properties and methods specific to ClassTwo
}
public class ClassThree : Base
{
// Properties and methods specific to ClassThree
}
public class ClassFour : Base
{
// Properties and methods specific to ClassFour
}
As requested, more code, using interfaces and abstract classes:
An interface is just a blueprint, defining what properties and methods are required to be compatible with other "BaseClasses"
public interface IBaseClass
{
public int ID {get;set;}
public void Set();
}
Abstract classes can contain code, but can not be instantiated, they are form of starting point for a class, but not a complete class themselves.
public abstract class ABaseClass : IBaseClass
{
public int ID {get;set;}
public void Set(){
// Do Stuff to save
}
}
Each class inherits from the abstract class and can then override and implement whatever it wants, customizing it however is necessary.
public class ClassOne : ABaseClass
{
}
public class ClassTwo : ABaseClass
{
}
public class ClassThree : ABaseClass
{
}
public class ClassFour : ABaseClass
{
}
ps. not entirely sure if my syntax is 100% correct
Could you simply make a base class with your properties and inherit from that class?
Why not use inheritance??
public class ClassOne
{
public ClassOne()
{
}
public virtual int ID {get;set;}
// More properties here
public virtual void Set(){
// Do Stuff to save this
}
// More Methods here }
public class ClassTwo : ClassOne
{
public string ClassTwoString { get; set; }
}
public class ClassThree : ClassOne
{
public string ClassThreeString { get; set; }
}
Can you make them all inherit off of the same class? If so, that sounds ideal.
Barring the possibility of making them inherit, you could write an interface that describes the methods and properties which each of them use. Then you can call each instance of the class through the same interface.
Barring again that possibility, you could write a reflective assignor/accessor. But you shouldn't do that.
I have a database table which contains an ID column and a Name column. I am tasked with designing a program that accepts one of the IDs as an argument to Main().
Bold is edit 2
I need to use that ID which must exist in the database, to correspond to some code to run. Each row in the table corresponds to slightly different code, but a lot of them share a lot of code. I need a design that will minimize code duplication.
So far what I've developed is an abstract base class that has an abstract Int32 field ID to enforce derived classes having their corresponding ID in the database. That way I can reflect over the derived classes to find the one whose ID matches the Main() argument and instantiate that class. Then I just call the virtual methods from Main() which runs the most derived code that has been defined.
public abstract class Base {
public abstract Int32 Id { get; }
public void Foo() {
// Do something
}
}
public class Derived {
public override Int32 Id { get { return 42; } }
public void Foo() {
// Do something more specific
}
}
Does anyone have any better ideas how to achieve what I want? I like the idea of keeping the ID right in the class definition, but I'm open to changing that if it makes sense.
Thanks!
EDIT:
One thing I don't like about this is that I have to reflect over each derived type and instantiate that type to check the ID. Does anyone have a better idea on how to do that?
Instead of using a property to define the ID of the class, use a custom attribute. That way, you don't have to instantiate the object to check what its ID is.
When your program runs, it can scan the assembly for all classes with that attribute tag, and find the one with the matching ID, instantiate that class, and then run it's Foo method. If you perform this kind of lookup multiple times per application run, you could instatiate all the classes with your custom attribute and then put them into a Dictionary to provide quick lookups by ID.
Your code might look something like this:
[AttributeUsage(AttributeTargets.Class)]
public class CommandAttribute {
public CommandAttribute(int id) {
ID = id;
}
public int ID { get; private set; }
}
public abstract class Command {
public abstract void Execute();
}
[Command(2)]
public class MyCommand : Command {
public override void Execute() {
//Do something useful
}
}
The other advantage of using a custom attribute is that you have to explicitly tag everything that is a candidate for being instantiated and executed by ID, rather than assuming than anything derived from your base class is a candidate. If you are sharing code between the classes, you might want to make a common base class for them that derives from your base class, but should not be instantiated or executed on its own.
One thing I don't understand is, what is the point of the "Name" field if the class you want to run is identified by the ID? If you can decide what the name of each ID is, then you could use the name field as the fully qualified type name of the class you want to execute, which then avoid having to scan through all the types in your assembly (or application domain, depending upon the scope of your search). That setup is a bit more prone to typos, however.
It sounds like you need to implement a factory pattern.
I would define an interface:
public interface IWidget
{
void Foo();
}
Then the base class:
public abstract class WidgetBase : IWidget
{
public void Foo()
{
this.Bar()
}
protected virtual void Bar()
{
// Base implementation
}
}
The factory:
public static WidgetFactory
{
public static IWidget Create(int id)
{
// Get class name from id, probably use the name in your database.
// Get Type from class name
// Get constructor for Type
// Create instance using constructor and return it.
}
}
A derived class:
public class DerivedWidget : WidgetBase
{
protected override void Bar()
{
// call base implementation
base.Bar();
// derived implementation
}
}
In your main:
public void Main(int id)
{
var widget = WidgetBase.Create(id);
widget.Foo();
}
I like #Xint0's idea of using a Factory for this kind of task, but I thought I'd still contribute another answer.
A better way to implement your original design would be to pass the ID to the base constructor as follows:
public abstract class Base {
public Int32 Id { get; private set; }
protected Base(Int32 id) {
this.Id = id;
}
public void Foo() {
// Do something
}
}
public class Derived : Base {
public Derived : base(42) {}
public void Foo() {
// Do something more specific
}
}
I have a design issue and am looking for the best design solution. I have added an example of the issue below.
public interface IVehicle<T>
{
int GetEngineSize();
}
public class Car : IVehicle<Car>
{
public int GetEngineSize()
{
throw new NotImplementedException();
}
public bool HasSpolier()
{
return true;
}
}
public class Bus : IVehicle<Bus>
{
public int GetEngineSize()
{
throw new NotImplementedException();
}
}
public abstract class BaseController<T>
{
public IVehicle<T> Repository { get; set; }
}
public abstract class CarController : BaseController<Car>
{
public CarController()
{
// How can I access the HasSpolier method from the IVehicle<T> without having to cast the Interface to concrete class Car
bool result = Repository.HasSpolier();
}
}
I'm not sure your generics are doing what you want here.
If instead of
IVehicle<T> Repository {get; set;}
You did
T Repository {get; set;}
You could make
public abstract class BaseController<T> where T : IVehicle
To ensure that they're of the IVehicle Interface
Then you'd have a typed repository and get access to your spoiler method.
You're doing IVehicle<Bus> but at least in the sample code, the T is never used in the interface. At this point the T is worthless.
Unless you implement the method in the interface, you can't access it without casting it to another class.
You'd have to cast your Repository to Car.
It would make using your interface pointless as the dependency on the implementation which you're trying to remove is re-introduced.
Also the type parameter on your interface isn't required, you don't use it anywhere else in the interface...
public interface IVehicle
{
int GetEngineSize();
}