Architecture question

M

Morten Wennevik

Hi Tamir,

You can use Interfaces for what you describe.
Define an interface for the common properties/methods and have each class implement that interface.

class ClassA : IMyInterface
{
}
....

Then you can do

IMyInterface m = new ClassA();
IMyInterface m = new ClassB();

The implementation in ClassA and ClassB can be as different as they like, but you can pass objects of both ClassA and ClassB to any method that expects an IMyInterface object.
 
T

Tamir Khason

Question regarding the architecture issues:
I have 2 classes with the ALMOST SAME methods and properties, BUT
inplmentation is completly different. I have to use one of those classes
according some variable (e.g if a=1: myClass = new ClassA else myClass = new
ClassB) - What the best way to implement myClass base class to be able to do
such this (e.g. virtual, abstract, etc...)

TNX
 
G

Guest

Create the interface, then make an abstract class implement it, within which
you would declare your abstrct method, as well as your enums.

Tamir Khason said:
Yes you are right, but my classes have type defenitions (e.g. enums) with
the same name, but different values, in interface I can not define enum and
other type, what to do?
 
T

Tamir Khason

Yes you are right, but my classes have type defenitions (e.g. enums) with
the same name, but different values, in interface I can not define enum and
other type, what to do?
 
R

RayO

You need to make use of dynamic (late) binding. So make
a common base class with virtual members, from which you will
derive your ClassA and ClassB. You will then override the base
class' virtual members in these derived classes. Then you simply
declare myClass as an instance of the base class for the dynamic
binding to kick in at run-time.

RayO
 
R

RayO

Sorry I meant you will declare myClass as a variable
type of the base class. Then when you instantiate
the derived classes into this variable the late binding
will take effect.
 
Z

Zürcher See

Create a Base class and declare evrything virtual so you can override it in
the other two class.
Evrething that is common to all or most classes you can implement in the
BaseClass

public class BaseClass
{
public BaseClass(){}

protected virtual string CommonMethod()
{
//Most of the inherit class use this method, some one have to
override it
return "this is only a test";
}

protected virtual string SpecificMethod(){} //Every class has his own
implementation
}

public class ClassA:BaseClass
{
public ClassA(){}

protected override string SpecificMethod()
{
return "I'm class A!";
}
}

public class ClassB:BaseClass
{
public ClassB(){}

protected override string SpecificMethod()
{
return "I'm class B!";
}
}

public class ClassASpec:ClassA
{
public ClassA(){}

protected virtual string CommonMethod()
{
//Special case
return "this is a special test";
}
}


Tamir Khason said:
Yes you are right, but my classes have type defenitions (e.g. enums) with
the same name, but different values, in interface I can not define enum and
other type, what to do?
 
D

David

Create the interface, then make an abstract class implement it, within which
you would declare your abstrct method, as well as your enums.

It's hard to be definite here since the requirements are vague, but I
suspect that won't work. The problem is that Tamir obviously wants to
use instances of these classes polymorphically, and there's no way to
override the enums (assuming the enums need to be publicly available).

Tamir, except for the enum issue, the idea of an interface is an
excellent one. And I'd suggest that if your enums are changing their
values based on the current instance, then they really shouldn't be
enums, they should be properties of the class in question and included
in the interface.
 
T

Tamir Khason

thnks, but what to do with consts ? I have const a = 0x01; //ClassA and
const a = 0x02;//ClassB L<- Constants can not be abstract or virtual...

--
Tamir Khason
You want dot.NET? Just ask:
"Please, www.dotnet.us "

Zürcher See said:
Create a Base class and declare evrything virtual so you can override it
in
the other two class.
Evrething that is common to all or most classes you can implement in the
BaseClass

public class BaseClass
{
public BaseClass(){}

protected virtual string CommonMethod()
{
//Most of the inherit class use this method, some one have to
override it
return "this is only a test";
}

protected virtual string SpecificMethod(){} //Every class has his own
implementation
}

public class ClassA:BaseClass
{
public ClassA(){}

protected override string SpecificMethod()
{
return "I'm class A!";
}
}

public class ClassB:BaseClass
{
public ClassB(){}

protected override string SpecificMethod()
{
return "I'm class B!";
}
}

public class ClassASpec:ClassA
{
public ClassA(){}

protected virtual string CommonMethod()
{
//Special case
return "this is a special test";
}
}
 
T

Tamir Khason

Thank you for response:
The requirements are simple, this like drivers (in Win32)

I need to do something like

Person per;
if(a == 1)
per = new Person1();
else
per = new Person2();

Console.WriteLine(per.ActThis(per.ToDo.work,10));


Following the example of such thing:

class Class Person1
{
private const c = 0x00;
private const c1 = 0x01;
private const c2 = 0x02;

public enum ToDo {sleep = c1; work = c2; eat = 0x03};

public uint ActThis(ToDo todo, uint spend)
{
return todo*spend+c;
}
}

class Class Person2
{
private const c = 0x12;
private const c1 = 0x00;
private const c2 = 0x04;

public enum ToDo {sleep = c1; work = c2; eat = 0x10};

public uint ActThis(ToDo todo, uint spend)
{
return todo/spend*c;
}
}
 
Z

Zürcher See

This is a way you can implement it

public class Person
{
protected int c=0;
protected int sleep=0;
protected int work=0;
protected int eat=0;

public enum ToDo {Sleep,Work,Eat};

public virtual int ConvertToDoToValue(ToDo toDo)
{
switch(toDo)
{
case ToDo.Sleep: return sleep;
case ToDo.Work: return work;
case ToDo.Eat: return eat;
}
}

public int ActThis(ToDo toDo,int spend){return -1;}
}


public class Person1:person
{
public Person1()
{
this.c=0;
this.sleep=1;
this.work=2;
this.eat=3;
}

public override int ActThis(ToDo toDo, int spend)
{
return this.ConvertToDoToValue(toDo)*spend+this.c;
}
}

public class Person2:person
{

public Person2()
{
this.c=12;
this.sleep=0;
this.work=4;
this.eat=10;

}

public override int ActThis(ToDo toDo, int spend)
{
return this.ConvertToDoToValue(toDo)/spend*this.c;
}
}
 
T

Tamir Khason

rather warp way... :(
Are there more "elegant" way to do this?
In this style I can simple add cases all over clients and just do it
straight way...
 
R

RayO

You don't need to implement reflection for this
(polymorphism/dynamic binding) to work.

RayO
 
D

David

Thank you for response:
The requirements are simple, this like drivers (in Win32)

I need to do something like

Person per;
if(a == 1)
per = new Person1();
else
per = new Person2();

Console.WriteLine(per.ActThis(per.ToDo.work,10));

<snip the code>

OK, at first glance and not really knowing the details, to me the design
just doesn't smell right. What you're essentially doing here is having
the person objects advertise the parameters to their internal
calculations, and then the callers pass in those parameters and
essential control the actions.

I'd suggest that each object should know how to calculate an action on
its own. In other words, the caller may ask a Person1 to Sleep, but
exactly what that means is the business of the Person1 object itself.
In other words...

public interface IPerson
{
int Sleep(int amount);
int Work(int amount);

.... and so on.

public class Person1 : IPerson

private const workConstant = 0x02;
int Work(int amount)
{
return amount * workConstant;
}

....

Two other quick points. I wonder whether these Action routines really
need to return anything. It seems they may be merely changing the state
of the current Person, and the caller doesn't necessarily need to know
the results immediately. It's hard to say though.

Also, depending on your needs, having a single ActThis (or PerformAction
perhaps?) function might be preferable. In that case, go ahead and
define an enum for the actions, but the should may be identical in each
class. Don't use the enum for calculating values, the enum is only used
for specifying an action while the individual Person1/Person2 classes
know how to calculate an appropriate result based on the action.
 
K

Kevin Yu [MSFT]

Hi Tamir,

Have you tried to use an abstract class as base and derive from it to
achieve this? I think it will be more graceful than using an interface.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top