My understanding of Factory Method Pattern is (Correct me if i am wrong)
Factory Method Pattern
"Factory Method allow the client to delegates the product creation (Instance Creation) to the subclass".
There are two situation in which we can go for creating Factory Method pattern.
(i) When the client is restricted to the product (Instance) creation.
(ii) There are multiple products available.But a decision to be made which product instance
need to be returned.
If you want to create Abstract Method pattern
You need to have abstract product
Concrete Product
Factory Method to return the appropriate product.
Example :
public enum ORMChoice
{
L2SQL,
EFM,
LS,
Sonic
}
//Abstract Product
public interface IProduct
{
void ProductTaken();
}
//Concrete Product
public class LinqtoSql : IProduct
{
public void ProductTaken()
{
Console.WriteLine("OR Mapping Taken:LinqtoSql");
}
}
//concrete product
public class Subsonic : IProduct
{
public void ProductTaken()
{
Console.WriteLine("OR Mapping Taken:Subsonic");
}
}
//concrete product
public class EntityFramework : IProduct
{
public void ProductTaken()
{
Console.WriteLine("OR Mapping Taken:EntityFramework");
}
}
//concrete product
public class LightSpeed : IProduct
{
public void ProductTaken()
{
Console.WriteLine("OR Mapping Taken :LightSpeed");
}
}
public class Creator
{
//Factory Method
public IProduct ReturnORTool(ORMChoice choice)
{
switch (choice)
{
case ORMChoice.EFM:return new EntityFramework();
break;
case ORMChoice.L2SQL:return new LinqtoSql();
break;
case ORMChoice.LS:return new LightSpeed();
break;
case ORMChoice.Sonic:return new Subsonic();
break;
default: return null;
}
}
}
**Client**
Button_Click()
{
Creator c = new Creator();
IProduct p = c.ReturnORTool(ORMChoice.L2SQL);
p.ProductTaken();
}
Is my understanding of Factory Method is correct?
What you have there is actually more of an Abstract Factory Pattern, only that you factory (Creator) is not abstract. The factor method pattern is specifically useful for subclassing:
class A {
public:
A() : m_Member( GetMember() )
{
}
protected:
virtual ISomeInterface * GetMember() { // default impl here }
private:
ISomeInterface * m_Member;
}
Now subclasses of A can override GetMember to make the superclass use a specific implementation of ISomeInterface.
Define an interface for creating an
object, but let subclasses decide
which class to instantiate. Factory
Method lets a class defer
instantiation to subclasses.
more details and example there: http://www.dofactory.com/Patterns/PatternFactory.aspx
Yes, that appears to be a correct way to implement this, although pretty simplistic. In reality, you may want to account for the passing-in of various parameters that may not always be consistent across all types. Dictionaries/Lists/Hashtables/etc. are useful for this, as is serialized items and/or XML and other dynamicish things.
Related
I have different configurations all inheriting from a base configuration that are customized in forms. I want all of these to be handled by a single action result.
[HttpPost]
public IActionResult Register(AbstractBaseConfig config)
{
...do some logic...
return View("../Home/Index");
}
However, this is not possible because you cannot base in abstract classes as a parameter to an action result. Is there any work around for this so I don't need a seperate action result for each configuration? (I still want each configuration to be it's own class, I only need access to the base class methods in the action result logic).
Basically you can't, and the reason is that MVC will try to do new AbstractBaseConfig() as part of the Data Binding process (which parses the URL or the Form Post and puts the results in a concrete object). And by definition, doing new AbstractBaseConfig() is impossible for an abstract class.
It also makes sense for other reasons, I will explain why.
You seem to expect that MVC can determine the class from the parameters that are being passed in. That is not how it works, in fact the opposite is true: the Action Method has to specify the exact class, and then the Binder will instantiate that exact class and try to bind its properties.
Suppose you had this:
public abstract class Thing { public int ID { get;set; } }
public class NamedThing : Thing { public string Name { get;set; } }
public class OtherThing : Thing { public string Name { get;set; } }
and suppose it would be allowed to use:
public IActionResult Register(Thing thing)
then what would you expect to be in thing after Data Binding: a Thing object with only the ID set? Or one of the other object types, with Name set, but how would MVC ever be able to know which class you meant?
So for all these reasons, this is not possible.
You could have a base class inherit the abstract class and all your classes inherit from that base class whilst having that base class as your parameter
Take for example
public abstract class ABase
{
public void stuff()
{
var stuff = string.Empty;
stuff = "hello";
}
public virtual void otherstuff()
{
var stuff = string.Empty;
stuff = "hello";
}
}
public class Base : ABase
{
//empty
}
public class Derived : Base
{
public void mystuff()
{
this.stuff();
}
public override void otherstuff()
{
// Custom code
}
}
public ActionResult Register(Base config)
{
}
Im using asp.net core. Here is the basic way to use model with controller.
public class BookController : Controller
{
private readonly ApplicationDbContext _context { get; set; }
public BookController(ApplicationDbContext context)
{
_context = context;
}
public IActionResult Create(Book model)
{
// adding new model
}
public IActionResult Edit(Book model)
{
// modifying the model
}
public IActionResult Delete(Book model)
{
// removing the model
}
}
My question: when shall/should I implement the code inside the controller? When shall/should I implement it in another class?
Something like this:
public interface IBook
{
int Add(Book book);
int Update(Book book);
int Remove(Book book);
}
public class BookData : IBook
{
private readonly ApplicationDbContext _context { get; set; }
BookData(ApplicationDbContext context)
{
_context = context
}
public int Add(Book model)
{
// ...
return _context.SaveChanges();
}
// other implements...
}
Then, calling it inside controller:
public IActionResult Create(Book model)
{
var bookData = new BookData(_context);
int result = bookData.Add(model);
// ...
}
For the interface, I think it may be useful for the case: I have many controllers that require same action/method names.
Example: MessageController requires 3 actions/methods at least (Create/Add, Edit/Update, Delete/Remove). It's same to NotificationController class, CommentController class...
So, the interface can be improved to:
public interface IMyService<T> where T : class
{
int Add(T model);
int Update(T model);
int Remove(T model);
}
public class MyService<T> : IMyService<T> where T : class
{
private readonly ApplicationDbContext _context { get; set; }
public MyService(ApplicationDbContext context)
{
_context = context;
}
public int Add(T model)
{
Type type = typeof(model);
if (type == typeof(Book))
{
// adding new book model
}
else if (type == typeof(Comment))
{
// adding new comment model
}
// ...
return -1;
}
// other implements...
}
Do I misunderstand something?
If I read it correctly with data classes you actually means repository (which is an abstraction over the persistence layer). You should always encapsulate persistence logic behind a class (be it via repository pattern, command/query pattern or request handler) and use it instead of directly using the context in your service classes.
That being said, you can directly inject your BookData to your controller instead of the ApplicationDbContext. One thing you should consider you lose in your current implementation is the Unit of Work pattern. Right now, every add will instantly persist the data.
This may not be what you want, so you should move the _context.SaveChanges(); outside of the Add/Remove/Update methods and call it explicitly. This allows you to insert i.e. 10 records and if one of them fails, nothing will be persisted to the database.
But if you call _context.SaveChanges(); after each insert and you get an error in the 8th (of 10) records, then 7 get persisted and 3 will be missing and you get inconsistent data.
Controller shouldn't contain any logic at all, only do short validation of the input model (ModelState.IsValid check) and if its okay, call the services which do all the logic and report the result back to the user. Only in very simple tutorials and guides logic is put into the controller action for reasons of simplicity. In real world applications you should never do that. Controllers are much harder to unit test than service classes.
This might sound like a noob question.
class MyClass
{
public List<MyObjects> myObjects;
public MyClass()
{
//...
}
}
class UserClass
{
public void SomeFunction()
{
MyClass obj = new MyClass();
//Should this belong in constructor of MyClass?
obj.myObjects = new List<MyObjects>;
//Should 'SomeFunction' initialize obj.myObjects before using it, or
//should it assume it has been initialized and just use it?
obj.myObjects.Add(..);
}
}
Who is responsible for creation / initialization of MyClass.myObjects, when the default constructor is invoked?
Constructor of MyClass.
User of MyClass.
In general, the constructor of a class should do all work necessary for that class to be in a usable state. In your case here, you should probably provide an accessor method for myObjects. The principles of OOP say to encapsulate data. That means that myObjects should be private. You should only have access to it via accessor methods. By doing that, then you can construct the object and lazily create the list via the accessor method when it is actually needed.
Here is a wiki article dealing with Constructors. It mentions that a properly written constructor will leave the object in a valid state.
EDIT: Encapsulated myObjects with lazy initialization (Note I am assuming C# since your code sample looks kind of like that)
class MyClass
{
private List<MyObjects> myObjects;
public MyClass()
{
//...
}
public void Add(MyObject object)
{
MyObjects.Add(object);
}
private List<MyObjects> MyObjects
{
get
{
if (myObjects == null)
{
myObjects = new List<MyObject>();
}
return myObjects;
}
}
}
I have a dependency with a method that takes a Map as an argument.
public interface Service {
void doSomething(Map<String, String> map);
}
I'd like to write an assertion that this dependency is called with appropriate map contents. Something like this:
#RunWith(JMock.class)
public class MainTest {
private Mockery context = new Mockery();
private Service service = context.mock(Service.class);
private Main main = new Main(service);
#Test
public void test() {
context.checking(new Expectations(){{
oneOf(service).doSomething(with(hasEntry("test", "test")));
}});
main.run();
}
}
Unfortunately, this fails to compile, since hasEntry has wildcards in map generic parameters:
public static <K, V> org.hamcrest.Matcher<java.util.Map<? extends K, ? extends V>> hasEntry(K key, V value);
Is there any way to write a JMock expectaion for map contents?
There isn't a good answer to this as we hit the limits of Java generics. There's a tension between the generics we need for jMock and what we need for assertThat()
I tend to add a helper method, with an expressive name, to force the types.
#Test public void test() {
context.checking(new Expectations(){{
oneOf(service).doSomething(with(mapIncluding("test", "test")));
}});
main.run();
}
#SuppressWarnings({"unchecked", "rawtypes"})
private Matcher<Map<String, String>> mapIncluding(String key, String value) {
return (Matcher)Matchers.hasEntry(key, value);
};
Yes, this is pig-ugly. I can only apologise that this is the best we appear to be able to do. That said, it's rare that I have to go as far as turning off the types, I can give it a name that's meaningful in the domain, and I've localised the unchecking to the helper method.
I ended up creating a method specify() that allows downcasting of generic matchers to more specific ones
public static <T> Matcher<T> specify(final Matcher<? super T> matcher) {
return new TypeSafeMatcher<T>() {
#Override
protected boolean matchesSafely(T item) {
return matcher.matches(item);
}
#Override
public void describeTo(Description description) {
matcher.describeTo(description);
}
};
}
Using this method I can downcast any existing generic matcher, like hasEntry()
public <K, V> Matcher<Map<? extends K, ? extends V>> hasEntry(K key, V value)
to a more specific one in a generic-safe manner, like this:
private static <K,V> Matcher<Map<K, V>> aMapHavingEntry(K key, V value) {
return specify(hasEntry(key, value));
}
Now I can use this specific matcher as an expectation parameter:
context.checking(new Expectations() {{
oneOf(service).doSomething(with(aMapHavingEntry("test", "test")));
}});
Using specify() method I created a bunch of specific matchers for most popular interfaces: Map, Collection, List, Set, like:
private static <K,V> Matcher<Map<K, V>> aMapHavingEntry(K key, V value) {
return specify(hasEntry(key, value));
}
private static <K> Matcher<Collection<K>> aCollectionContainingInAnyOrder(K... items) {
return specify(containsInAnyOrder(items));
}
I also suggested adding the same functionality to JMock, though all I got was silence.
I would like to allow for declarative mixin management in my codebase. I would like to declare an interface like
public interface IMyRepo : IRepository, ICanFindPeopleByName, ICantSing {}
So my classes can consume only the bits of the data access layer they need. In my IoC container I would like to aggregate the implementations of these interfaces into a single instance. However when I do things similar to the referenced threads, the generator throws an exception stating that interfaces are implemented in multiple places. What can I do, other than implementing my own interceptor and passing through?
Relevant Threads:
Help Migrating mixins from Castle.DynamicProxy to DynamicProxy2.
Windsor MixIn is a Singleton?
Better Example (wall of code)
public interface IIceCream {
void Eat();
}
public class IceCream : IIceCream {
public void Eat() { Console.WriteLine("Yummy!"); }
}
public interface ICake {
void NomNom();
}
public class Cake : ICake {
public void NomNom() { Console.WriteLine("Cakey!"); }
}
public interface ISprinkles {
void Oogle();
}
public class Sprinkles : ISprinkles {
public void Oogle(){ Console.WriteLine("Its Pretty!");}
}
public interface IIceCreamWithCakeAndSprinkles : IIceCream, ICake, ISprinkles {}
public class Program
{
public static void Main()
{
var gen = new ProxyGenerator();
var options = new ProxyGenerationOptions();
options.AddMixinInstance(new IceCream());
options.AddMixinInstance(new Cake());
options.AddMixinInstance(new Sprinkles());
var result =
gen.CreateClassProxy(typeof (object), new[] {typeof (IIceCreamWithCakeAndSprinkles)}, options) as IIceCreamWithCakeAndSprinkles;
}
}
throws
InvalidMixinConfigurationException: "The mixin IceCream adds the interface 'ConsoleApplication1.IIceCream' to the generated proxy, but the interface already exists in the proxy's additional interfaces. A mixin cannot add an interface already implemented in another way."
Update to Dynamic Proxy 2.2 or 2.5 It is more permissive and it will let the mixin own the interface and ignore that it was passed again as "additional interface".