> This is a pain in C# without creating a separate assembly and using the
> internal modifier. Times like these I wish for a logical unit (and
> corresponding access modifier) similar to packages in java. Or the C++
> concept of friend classes.
>
It's funny you say this; as a Java guy, I've been lamenting the fact that
packages are bundled together as scoping and namespacing mechanisms; I much
prefer the .NET approach of separation between lexical and encapsulatory
(namespace and protective) scopes. C++ friends would be nice in places, but
the concept was so badly abused by so many C++ programmers that I'm leery of
adopting it again in .NET.

FWIW, all of these messages demonstrate the subtlety of patterns--which form
you take depends greatly on the context of your need. For example,
1) Will you want or need to shuffle factories around?
2) On whose behalf are the products being created--clients' or frameworks'?
3) Does there need to be some processing surrounding the actual object
instance call?
4) Do we really need to hide the implementation from the client?

In many cases, we're relying on factories where normal constructor calls,
appropriately parameterized, would do:

public class Product
{
  public Product(Factory f)
  { ... use f for whatever ... }
}

Ted Neward
{ .NET && Java } Author, Instructor
http://www.javageeks.com
http://www.clrgeeks.com

----- Original Message -----
From: "Isaac Hepworth" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, August 01, 2002 4:34 AM
Subject: Re: [ADVANCED-DOTNET] Need a C# pattern that returns an Interface


> This is a pain in C# without creating a separate assembly and using the
> internal modifier. Times like these I wish for a logical unit (and
> corresponding access modifier) similar to packages in java. Or the C++
> concept of friend classes.
>
> As it is, I use something similar to your example. As written I think
> your code has some problems with the specification "the objects should
> not be created outside of one static function". For example,
> 1) clients can create a MyItfImplementorA simply by calling
> MyItfImplementorA.Create(TheFactory.Instance())
> 2) clients can create a MyItfImplementorA by calling
> MyItfImplementorA.Create(null)
> 3) clients can implement their own class which implements
> IMyInterfaceFactory and call MyItfImplementorA.Create(myNewFactory)
> Also, your factory singleton isn't thread-safe ;-)
>
> The code below is a slightly tighter version of the same principle.
>
> public interface IMyInterface { void Run(); }
>
> public class MyClass: IMyInterface {
>         private MyClass() {}
>         public void Run() { /* whatever */ }
>         public static MyClass Create( MyFactory factory ) {
>                 if (factory == null) throw new Exception("Nice try");
>                 return new MyClass();
>         }
> }
>
> public sealed class MyFactory {
>         private static MyFactory _instance = new MyFactory(); //
> singleton
>         private MyFactory() {}
>         public static IMyInterface CreateMyInterface() {
>                 // logic for which concrete class
>                 // to instantiate goes here ...
>                 return /* for example */ MyClass.Create(_instance);
>         }
> }
>
> It is now impossible for clients to create a MyClass without using
> MyFactory.CreateMyInterface(). And note that MyFactory is sealed, so
> clients can't extend it and pass in an instance of their descendent
> class to MyClass.Create().
>
> Cheers,
>
> Isaac
>
> > -----Original Message-----
> > From: Moderated discussion of advanced .NET topics.
> > [mailto:[EMAIL PROTECTED]] On Behalf Of Stoyan Damov
> > Sent: 01 August 2002 09:23
> > To: [EMAIL PROTECTED]
> > Subject: Re: [ADVANCED-DOTNET] Need a C# pattern that returns
> > an Interface
> >
> >
> > Well, I guess it could look a little bit strange but it works and I
> > can't come up with a better idea, and because I am not as
> > articulate in
> > explanations as I wish, here's the commented code:
> >
> >
> > using System;
> >
> > namespace TestPattern
> > {
> >
> > // the interface
> > public interface IMyInterface
> > {
> >         void Run ();
> > }
> >
> >
> > // you'll get the idea below
> > public interface IMyInterfaceFactory
> > {
> > }
> >
> >
> > // an implementor
> > public class MyItfImplementorA : IMyInterface
> > {
> >         // note, the constructor is private
> >         private MyItfImplementorA () {}
> >
> >         public void Run ()
> >         {
> >                 Console.WriteLine ("Running MyItfImplementorA");
> >         }
> >
> >         // see? only the factory is allowed to call this method
> >         public static IMyInterface Create
> > (IMyInterfaceFactory factory)
> >         {
> >                 return (new MyItfImplementorA ());
> >         }
> > }
> >
> >
> > // another one
> > public class MyItfImplementorB : IMyInterface
> > {
> >         private MyItfImplementorB () {}
> >
> >         public void Run ()
> >         {
> >                 Console.WriteLine ("Running MyItfImplementorB");
> >         }
> >
> >         // see? only the factory is allowed to call this method
> >         public static IMyInterface Create
> > (IMyInterfaceFactory factory)
> >         {
> >                 return (new MyItfImplementorB ());
> >         }
> > }
> >
> >
> > // this is the factory and it is singleton
> > public class TheFactory : IMyInterfaceFactory
> > {
> >         private static TheFactory instance = null;
> >         private static int x = 1; // no special purpose
> >
> >         private TheFactory ()  // private ctor (singleton)
> >         {
> >         }
> >
> >         public static TheFactory Instance ()
> >         {
> >                 if (instance == null)
> >                         instance = new TheFactory ();
> >                 return (instance);
> >         }
> >
> >         // this is your static method
> >         public static IMyInterface CreateInstance ()
> >         {
> >                 switch (x)
> >                 {
> >                         case 1:
> >                                 x ++; // this is just to imitate your
> > logic where different objects are created...
> >                                 return MyItfImplementorA.Create
> > (Instance ());
> >                         case 2:
> >                                 x --; // here too...
> >                                 return MyItfImplementorB.Create
> > (Instance ());
> >                         default:
> >                                 return (null);
> >                 }
> >         }
> > }
> >
> >
> > public class Test
> > {
> >         public Test ()
> >         {
> >         }
> >
> >         public void Run ()
> >         {
> >                 IMyInterface [] itfs = new IMyInterface []
> >                 {
> >                         TheFactory.CreateInstance (),
> >                         TheFactory.CreateInstance ()
> >                 };
> >
> >                 for (int i=0; i<itfs.Length; i++)
> >                         itfs [i].Run ();
> >         }
> >
> >
> >         static void Main (string [] args)
> >         {
> >                 new Test ().Run ();
> >         }
> >
> > }
> >
> >
> > }
> >
> > Hope that helps,
> >
> > Stoyan Damov
> >
> > -----Original Message-----
> > From: Michael Potter [mailto:[EMAIL PROTECTED]]
> > Sent: Thursday, August 01, 2002 5:11 AM
> > To: [EMAIL PROTECTED]
> > Subject: [ADVANCED-DOTNET] Need a C# pattern that returns an Interface
> >
> >
> > I have a static method that will return an object of IMyInterface. It
> > will create the best 1 of many mutually exlusive objects that
> > implement
> > IMyInterface.  The object created depends upon the available hardware
> > resources.
> >
> > The objects should not be created outside of the one
> > static function. How do I hide the constructor of the
> > objects (that implement IMyInterface) from the rest of
> > the world and yet, allow them to be exposed to the one
> > static creation method?
> >
> > Any ideas?
> > Mike P
> >
> >
> >
> > __________________________________________________
> > Do You Yahoo!?
> > Yahoo! Health - Feel better, live better http://health.yahoo.com
> >
> > You can read messages from the Advanced DOTNET archive,
> > unsubscribe from
> > Advanced DOTNET, or subscribe to other DevelopMentor lists at
> > http://discuss.develop.com.
> >
> > You can read messages from the Advanced DOTNET archive,
> > unsubscribe from Advanced DOTNET, or
> > subscribe to other DevelopMentor lists at http://discuss.develop.com.
> >
>
> You can read messages from the Advanced DOTNET archive, unsubscribe from
Advanced DOTNET, or
> subscribe to other DevelopMentor lists at http://discuss.develop.com.
>

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to