开发者

Does ChannelFactory implement a factory pattern?

I’ve started learning WCF and I’m already utterly confused. I did a bit of reading on factory pattern and I can’t figure out how or why does ChannelFactory<> implement it.

Namely, the whole idea of a factory pattern is that factory abstracts the creation and initialization of the product from the client and thus if new type of product is introduced, client code doesn’t need to change and thus can immediately start using the new product.

ChannelFactory<IRequestChannel> factory = new 
                    ChannelFactory<IRequestChannel>(binding, address);
IRequestChannel channel = factory.CreateChannel();

The following is not a valid code, but it’s just used to demonstrate that, as far as I can tell, ChannelFactory doesn’t bring any benefits over directly instantiating specific channel class:

IRequestChannel channel=new RequestChannelClass(binding, address);

a) Only benefit of the first example ( implementing the factory pattern ) is that client code doesn’t need to change in the event that the type of object returned by factory.CreateChannel is changed sometime in the future.

But if that’s the reason for implementing factory pattern, then any method returning an object should implement a factory pattern, just in case the type of returned object ever changes in the future?!

c) Thus, if ChannelFactory<>.CreateChannel really implemented factory pattern, then client code would be able to inform factory.GetFactory (say via parameter) of what type should an object/product returned by factory.CreateFactory be?!

d) Similarly, as far as I can tell, ChannelFactory class also doesn't implement a factory pattern?

thank you

REPLYING TO Justin Niessner:

b) The Factory pattern doesn't necessarily require you to be able to specify the concrete type to be created. It also allows for the factory to determine the concrete type based on the parameters passed to it (in this case, binding and address).

So ChannelFactory.CreateChannel choose a concrete type to return based on binding and address values? I thought it always returns the same concrete type, regardless of address and binding values?!

As I’ve asked the other two posters, would you agree that if ChannelFactory.CreateChannel always returned an instance of the same concrete type, regardless of the binding and address values, then ChannelFactory wouldn’t have a factory pattern implemented?

REPLYING TO Kevin Nelson

A) There are 2 benefits. 1) implementing code doesn't have to change if you start using a new implementation of IRequestChannel.

True, but as I’ve mentioned to other posters, if that’s the only requirement for class to be qualified as a class implementing a factory pattern , then any class with a method ( with an interface type as return type ) that creates and returns a concrete instance, implements a factory pattern? As far as I can tell, factory pattern is when factory produces different products based on values somehow supplied by a client code?!

On the other hand, if I correctly understood Steve Ellinger, then based on binding and address values ( passed to constructor of C开发者_StackOverflow社区hannelFactory), the call to ChannelFactory.CreateChannel will choose the concrete type to return based on binding and address values( supplied to constructor ). If that is the case, then I can understand why we say ChannelFactory implements factory pattern?!

So would you agree that if ChannelFactory.CreateChannel always returned an instance of the same concrete type, regardless of the binding and address values, then ChannelFactory wouldn’t have a factory pattern implemented?

REPLYING TO Steve Ellinger

IRequestChannel is implemented by the abstract class RequestChannel. In .Net 4.0 HttpChannelFactory.HttpRequestChannel, ReliableRequestSessionChannel and StreamedFramingRequestChannel all inherit from RequestChannel. So:

a) You say the only benefit, but actually I think this is a significant benefit. Keep in mind, this also makes WCF extensible and more flexible.

But then we could claim that any class with a method ( with an interface type as return type ) that creates and returns a concrete instance implements a factory pattern?

c) The client code does tell the factory which to return, indirectly by the passed binding and address.

I thought ChannelFactory.CreateChannel will always return in instance of the same concrete type, regardless of the binding and address passed to constructor of ChannelFactory.But you’re saying that based on binding and address values ( passed to constructor of ChannelFactory), the call to ChannelFactory.CreateChannel will return one of the following types: HttpChannelFactory.HttpRequestChannel ,ReliableRequestSessionChannel and StreamedFramingRequestChannel?

If that is the case, then I can understand why we say ChannelFactory implements factory pattern?!

So would you agree that if ChannelFactory.CreateChannel always returned an instance of the same concrete type, regardless of the binding and address values, then ChannelFactory wouldn’t have a factory pattern implemented?

SECOND REPLY TO Steve Ellinger

a) So depending on the binding and address values, ChannelFactory.CreateChannel returns either HttpRequestChannel ,ReliableRequestSessionChannel or StreamedFramingRequestChannel? Or may it also return some other types also?

b) if client code will always use channel instance of the same type (say HttpRequestChannel ), then there's nothing wrong if instead of using ChannelFactory.CreateChannel we directly instantiate HttpRequestChannel instance:

 HttpRequestChannel channel = new HttpRequestChannel( ... )  

c) BTW - any idea why msdn doesn't contain any entries describing HttpRequestChannel ,ReliableRequestSessionChannel and `StreamedFramingRequestChannel' classes?


IRequestChannel is implemented by the abstract class RequestChannel. In .Net 4.0 HttpChannelFactory.HttpRequestChannel, ReliableRequestSessionChannel and StreamedFramingRequestChannel all inherit from RequestChannel. So:

a) You say the only benefit, but actually I think this is a significant benefit. Keep in mind, this also makes WCF extensible and more flexible.

c) The client code does tell the factory which to return, indirectly by the passed binding and address. I for one would not want to go through all my code to change a concrete type because Microsoft decided to obsolete the one I was using.

d) Yes, given the structure mentioned at the start, this is a typical Factory pattern implementation.

Edit:

a factory pattern?

But then we could claim that any class with a method ( with an interface type as return type ) that creates and returns a concrete instance implements a factory pattern?

Not necessarily, to quote the Design Patterns book: the abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.

So would you agree that if ChannelFactory.CreateChannel always returned an instance of the same concrete type, regardless of the binding and address values, then ChannelFactory wouldn’t have a factory pattern implemented?

Yes

Edit2:

a) It can return other types because it is possible to create custom bindings in WCF

b) & c) HttpChannelFactory.HttpRequestChannel is a protected class, ReliableRequestSessionChannel and StreamedFramingRequestChannel are internal classes; this is why you can't find them on msdn, and also why you can't instantiate these classes directly. I found out about them via Reflector, my point in mentioning them is that ChannelFactory does not necessarily return the same concrete type all the time


The Factory pattern is used to return a Concrete Implementation of a more generic class/interface.

In this case, ChannelFactory is returning a concrete implementation of IRequestChannel. Nowhere in any of your code are you telling the factory which concrete class to return which is what makes this a Factory. As for your points:

a) It is often considered good coding practice to return the least specific type possible. If you can get away with returning an instance of an interface, do it. It will reduce maintenance headaches in the future.

Keep in mind though that returning the least specific type has nothing to do with the Factory pattern. The Factory pattern is specific to the creation of an instance of an object.

b) The Factory pattern doesn't necessarily require you to be able to specify the concrete type to be created. It also allows for the factory to determine the concrete type based on the parameters passed to it (in this case, binding and address).

c) Yes, the ChannelFactory does implement the Factory pattern.


There are others that are probably more efficient with patterns (and explaining them) than I am, but here goes:

A) There are 2 benefits. 1) implementing code doesn't have to change if you start using a new implementation of IRequestChannel. 2) This also enables you to make Mock objects. In your unit test project, you tell your ChannelFactory to instantiate a Mock IRequestChannel. This way, you can focus your unit test onto just the specifics of the method you are testing rather than having to create a behemoth test that instantiates real instances of everything, etc. (If you're unfamiliar, look up Test Driven Development (TDD), Inversion of Control (IoC), and Dependency Injection (basically a subset of IoC).

B) I would say that you generally want to use the factory pattern between layers, not within layers. E.g. your service layer would implement a factory for your repository layer classes. This way, if your ICustomerRepostory changes from an NHibernateCustomerRepository to a CouchDBCustomerRespository...your service layer doesn't have to know anything about this change.

Other poster answered the other issues, I think...so I'll leave C & D alone.

REPLY EDIT:

So would you agree that if ChannelFactory.CreateChannel always returned an instance of the same concrete type, regardless of the binding and address values, then ChannelFactory wouldn’t have a factory pattern implemented?

Sorry, probably over my head as to the semantics of it...but to my understanding, the point isn't so much whether it does return more than one concrete class, but in its ability to return a different concrete class if the need arises. If it's not able to produce different concrete classes, then it wouldn't be a factory...but if it "can" produce different concrete classes if and when the need arises, then it is a factory pattern. Beyond that, I'll have to declare ignorance...and even in that, I'm not saying I can't be wrong.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜