Hi
I have a common model for a Data Access Layer scenario. I have an abstract
base class, called DalBase which contains a list of abstract methods. Lets
call them:
public abstract void Shine();
public abstract void Flow();
public abstract void Float();
I then have an inherited class, called DalMain which contains the concrete
implementations of these methods
DalMain : DalBase
{
public override void Shine()
{
...
}
public override void Flow()
{
...
}
public override void Float()
{
...
}
}
I have a third class, DataAccessBaseClass, which has a static method called
GetDalLayer() which checks that the type of DalMain is DalBase, and if it
is, returns the type of the DalMain class. The beauty of this is, if I need
to call Flow() in a business class, all I need to do is:
DalBase dal = DataAccessBaseClass.GetDalLayer();
//dal is now of type DalMain
dal.Flow();
and this will call the Flow() in the DalMain class. All nice and good!
However, I am in a team environment, and I have a 100+ abstract methods in
DalBase. Which means that DalMain is in constant demand and causing a
development bottleneck.
I want to split up DalMain into separate "responsible" classes, so as to
share out the functionality and place less of a burden on the editing of the
DalMain class by the entire team.
What do I need to do to retain the same mode of invoking the DalBase
methods, but from concrete implementations in these classes:
public class Moon
{
public override void Shine()
{
...
}
}
public class Liquid
{
public override void Flow()
{
...
}
}
public class Balloon
{
public override void Float()
{
...
}
}
I want to be able to call the Flow() method
DalBase dal = DataAccessBaseClass.GetDalLayer();
dal.Flow();
and this will call the Flow() in the Liquid class - which now has the
implentation for Flow(). And the same for the other methods in the Moon and
Balloon classes.
What should I do? 9 1627
If you are using .NET 2.0, check out partical classes.
John Puopolo
"Codex Twin" <co***@more.com> wrote in message
news:eZ**************@tk2msftngp13.phx.gbl... Hi
I have a common model for a Data Access Layer scenario. I have an abstract base class, called DalBase which contains a list of abstract methods. Lets call them: public abstract void Shine(); public abstract void Flow(); public abstract void Float();
I then have an inherited class, called DalMain which contains the concrete implementations of these methods
DalMain : DalBase { public override void Shine() { ... }
public override void Flow() { ... }
public override void Float() { ... } }
I have a third class, DataAccessBaseClass, which has a static method
called GetDalLayer() which checks that the type of DalMain is DalBase, and if it is, returns the type of the DalMain class. The beauty of this is, if I
need to call Flow() in a business class, all I need to do is:
DalBase dal = DataAccessBaseClass.GetDalLayer(); //dal is now of type DalMain dal.Flow();
and this will call the Flow() in the DalMain class. All nice and good!
However, I am in a team environment, and I have a 100+ abstract methods in DalBase. Which means that DalMain is in constant demand and causing a development bottleneck.
I want to split up DalMain into separate "responsible" classes, so as to share out the functionality and place less of a burden on the editing of
the DalMain class by the entire team.
What do I need to do to retain the same mode of invoking the DalBase methods, but from concrete implementations in these classes:
public class Moon { public override void Shine() { ... } }
public class Liquid { public override void Flow() { ... } }
public class Balloon { public override void Float() { ... } }
I want to be able to call the Flow() method
DalBase dal = DataAccessBaseClass.GetDalLayer(); dal.Flow();
and this will call the Flow() in the Liquid class - which now has the implentation for Flow(). And the same for the other methods in the Moon
and Balloon classes.
What should I do?
Codex Twin <co***@more.com> wrote:
<snip> However, I am in a team environment, and I have a 100+ abstract methods in DalBase. Which means that DalMain is in constant demand and causing a development bottleneck.
I want to split up DalMain into separate "responsible" classes, so as to share out the functionality and place less of a burden on the editing of the DalMain class by the entire team.
A couple of possibilities:
1) Don't have a single base class in the first place - split it into
several. This sounds like it would be a good idea anyway.
2) Change DalBase to several interfaces, and have a proxy class which
implements all the interfaces. Split DalMain into several smaller
classes, each implementing a single interface. The proxy class would
create an instance of each of the smaller classes, and forward the
method calls for each interface to the appropriate implementation.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote: A couple of possibilities:
1) Don't have a single base class in the first place - split it into
several. This sounds like it would be a good idea anyway.
2) Change DalBase to several interfaces, and have a proxy class which
implements all the interfaces. Split DalMain into several smaller
classes, each implementing a single interface. The proxy class would
create an instance of each of the smaller classes, and forward the
method calls for each interface to the appropriate implementation.
Jon
Thanks! I really like the sound of the second idea you've explained.
From my reading of your solution and the Proxy design pattern (which I
looked up), this is my understanding of your suggestion:
1) The DalBase class is changed to smaller interfaces:
IDalBalloon and IDalLiquid
They contain definitions for Float() and Flow() respectively.
2) Split DalMain into smaller classes each implementing a smaller interface:
// Balloon - now contains a concrete implementation of Float()
public class Balloon : IDalBalloon
{
public void Float()
{.}
}
//Liquid - now contains a concrete implementation of Flow()
public class Liquid : IDalLiquid
{
public void Flow()
{.}
}
3) Have one proxy which implements all the interface and creates an instance
of the individual classes:
public class DalProxy : IDalBalloon, IDalLiquid
{
//Members
//some form of instantiation
Balloon balloon = new Balloon();
//cast to IDalBalloon to check if it is an IDalBalloon
IDalBalloon isBalloon = balloon as IDalBalloon;
Liquid liquid = new Liquid();
//cast to IDalLiquid to check if it is an IDalLiquid
IDalLiquid isLiquid = liquid as IDalLiquid;
Public void Float()
{
if (isBalloon != null)
isBalloon.Float();
else
throw new Exception("Balloon must
implement IDalBalloon");
}
Public void Flow()
{
if (iLiquid != null)
isLiquid.Flow();
else
throw new Exception("Liquid must
implement IDalLiquid");
}
}
4) Then in a client.
DalProxy p = new DalProxy;
//invoke Flow()
p.Flow();
//invoke Float()
p.Float();
This solves the first of my two problems: that of having a logical layer of
classes which do all the concrete implementation and have to be
interchangeable. In other words I can now have a library of SQL classes:
(SqlBalloon implementing IDalBalloon) and an alternative library of Oracle
classes (OracleBalloon implementing IDalBalloon).
However, using one single Proxy class (DalProxy) for invoking the methods
would present the same problem of having one DalMain, that I faced in my
solution. It means that the development bottleneck of having the team lining
up to edit DalProxy would still be there!
But the good thing is, I can have a number of specialist Proxy classes,
DalBalloonProxy and DalLiquidProxy which each implements the IDalBalloon and
IDalLiquid interfaces respectively, and each is responsible to their methods
specifically.
Thanks again.
Reposted, with improved formatting.
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote: A couple of possibilities:
1) Don't have a single base class in the first place - split it into several. This sounds like it would be a good idea anyway.
2) Change DalBase to several interfaces, and have a proxy class which implements all the interfaces. Split DalMain into several smaller classes, each implementing a single interface. The proxy class would create an instance of each of the smaller classes, and forward the method calls for each interface to the appropriate implementation.
Jon
I really like the sound of the second idea you have explained above.
From my reading of your solution and the Proxy design pattern (which I
looked up), this is my understanding of your suggestion:
1) The DalBase class is changed to smaller interfaces:
IDalBalloon and IDalLiquid
They contain definitions for Float() and Flow() respectively.
2) Split DalMain into smaller classes each implementing a smaller interface:
// Balloon - now contains a concrete implementation of Float()
public class Balloon : IDalBalloon
{
public void Float()
{.}
}
// now contains a concrete implementation of Flow()
public class Liquid : IDalLiquid
{
public void Flow()
{.}
}
3) Have one proxy which implements all the interface and creates an instance
of the smaller classes:
public class DalProxy : IDalBalloon, IDalLiquid
{
//Members
//some form of instantiation
Balloon balloon = new Balloon();
//cast to IDalBalloon to check if it is an IDalBalloon
IDalBalloon isBalloon = balloon as IDalBalloon;
Liquid liquid = new Liquid();
//cast to IDalLiquid to check if it is an IDalLiquid
IDalLiquid isLiquid = liquid as IDalLiquid;
Public void Float()
{
if (isBalloon != null)
isBalloon.Float();
else
throw new Exception("Must implement IDalBalloon");
}
Public void Flow()
{
if (iLiquid != null)
isLiquid.Flow();
else
throw new Exception("Must implement IDalLiquid");
}
}
4) Then in a client.
DalProxy p = new DalProxy;
//invoke Flow()
p.Flow();
//invoke Float()
p.Float();
This solves the first of my two problems: that of having a logical layer of
classes which do all the concrete implementation having to be
interchangeable. In other words I can now have a library of SQL classes:
(SqlBalloon implementing IDalBalloon) and an alternative library of Oracle
classes (OracleBalloon implementing IDalBalloon).
However, using one single Proxy class (DalProxy) for invoking the methods is
not solving the problem of having one DalMain, that I faced in my solution.
It means that the development bottleneck of having the team lining up to
edit DalProxy would still be there!
But the good thing is, I can have a number of specialist Proxy classes,
DalBalloonProxy and DalLiquidProxy which each implements the IDalBalloon and
IDalLiquid interfaces respectively, and each is responsible to their methods
specifically.
Thanks again.
Codex Twin <co***@gmail.com> wrote: Thanks! I really like the sound of the second idea you've explained.
From my reading of your solution and the Proxy design pattern (which I looked up), this is my understanding of your suggestion:
<snip most of it>
3) Have one proxy which implements all the interface and creates an instance of the individual classes:
public class DalProxy : IDalBalloon, IDalLiquid
{ //Members //some form of instantiation Balloon balloon = new Balloon(); //cast to IDalBalloon to check if it is an IDalBalloon IDalBalloon isBalloon = balloon as IDalBalloon;
There's no need to do this - just instantiate it as:
IDalBalloon balloon = new Balloon();
The compiler can verify (at compile time) that Balloon implements
IDalBalloon.
<snip>
However, using one single Proxy class (DalProxy) for invoking the methods would present the same problem of having one DalMain, that I faced in my solution. It means that the development bottleneck of having the team lining up to edit DalProxy would still be there!
They shouldn't - changes to DalProxy should only occur when the
interface changes, as it has no real implementation itself. In
addition, when the interface changes DalProxy only needs to be changed
for a matter of minutes, as the implementation of each method is so
simple.
But the good thing is, I can have a number of specialist Proxy classes, DalBalloonProxy and DalLiquidProxy which each implements the IDalBalloon and IDalLiquid interfaces respectively, and each is responsible to their methods specifically.
I don't think that particularly helps - if you're going to have
separate proxy classes, the caller would have to know which of those to
instantiate, at which point the benefit of having a proxy is almost
entirely gone.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote
<snip> They shouldn't - changes to DalProxy should only occur when the interface changes, as it has no real implementation itself. In addition, when the interface changes DalProxy only needs to be changed for a matter of minutes, as the implementation of each method is so simple.
Yes, sorry, you're right. The only thing that the DalProxy should have is an
implementation of IDalBalloon and IDalLiquid methods which would be
boilerplate code and wouldn't need time consuming check-outs which would
cause the team-time bottlenecks I want to avoid. But the good thing is, I can have a number of specialist Proxy classes, DalBalloonProxy and DalLiquidProxy which each implements the IDalBalloon and IDalLiquid interfaces respectively, and each is responsible to their methods specifically.
I don't think that particularly helps - if you're going to have separate proxy classes, the caller would have to know which of those to instantiate, at which point the benefit of having a proxy is almost entirely gone.
What I tried to get across in my post, but failed completely, was the
question of how I would create a way of switching between libraries. If you
remember in my solution, I had a DataAccessBaseClass, which has a static
method called GetDalLayer() which checks that the type of DalMain "is a"
DalBase, and if it
is, returns the an instace of DalMain. The checking is done by GetDalLayer()
which reads a config file which simply contains the string "DalMain", and if
it inherits from DalBase (which it should), creates an instance of it using
Activator and returns the instance.
Now, if I wanted to use an Oracle implementation, I would have to create a
DalMainForOracle class which would extend DalBase with overridden wrapper
methods specific for Oracle invocations. And then I'd edit the config file
so that DataAccessBaseClass.GetDalLayer() would return an instance of
DalMainForOracle.
Then the code to call Dal methods for either case would always be:
DalBase dal = DataAccessBaseClass.GetDalLayer();
//dal is an instance of DalMain or DalMainForOracle, depending on whats
specified in the config.
dal.Flow();
Using the Proxy method you've suggested, how would I be able to specify, if
possible, whether IDalBalloon is code SQL or Oracle implementation, so to
speak?
Thanks.
Codex Twin <co***@gmail.com> wrote: <snip>
They shouldn't - changes to DalProxy should only occur when the interface changes, as it has no real implementation itself. In addition, when the interface changes DalProxy only needs to be changed for a matter of minutes, as the implementation of each method is so simple.
Yes, sorry, you're right. The only thing that the DalProxy should have is an implementation of IDalBalloon and IDalLiquid methods which would be boilerplate code and wouldn't need time consuming check-outs which would cause the team-time bottlenecks I want to avoid.
Exactly. But the good thing is, I can have a number of specialist Proxy classes, DalBalloonProxy and DalLiquidProxy which each implements the IDalBalloon and IDalLiquid interfaces respectively, and each is responsible to their methods specifically.
I don't think that particularly helps - if you're going to have separate proxy classes, the caller would have to know which of those to instantiate, at which point the benefit of having a proxy is almost entirely gone.
What I tried to get across in my post, but failed completely, was the question of how I would create a way of switching between libraries. If you remember in my solution, I had a DataAccessBaseClass, which has a static method called GetDalLayer() which checks that the type of DalMain "is a" DalBase, and if it is, returns the an instace of DalMain. The checking is done by GetDalLayer() which reads a config file which simply contains the string "DalMain", and if it inherits from DalBase (which it should), creates an instance of it using Activator and returns the instance.
Right. You might want to consider using the Spring framework for this
kind of thing. I'm using it in Java at the moment, and it's wonderful.
I haven't used the .NET version, but I've looked at some of the docs
and it looks basically the same (as I'd expect). See http://www.springframework.org for more information.
<snip - I think the above covers it>
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote Right. You might want to consider using the Spring framework for this kind of thing. I'm using it in Java at the moment, and it's wonderful. I haven't used the .NET version, but I've looked at some of the docs and it looks basically the same (as I'd expect). See http://www.springframework.org for more information.
<snip - I think the above covers it>
I THINK have found a solution which is a happy medium which solves the
problems:
1) Allows a plug-able library by specifying the Library class from a config
file
2) Separates the classes into seprate files which avoid the development
bottleneck.
It uses interfaces rather than base classes and uses the Factory pattern.
The smaller concrete classes must all implement interfaces:
public interface IDalBalloon
{
void Float();
}
By doing so, I can have many files for each class in my DAL - which solves
the second problem, ie a seperate file for Balloon and Liquid
public class Balloon : IDalBalloon
{
public void Float()
{...}
}
public class Liquid: IDalLiquid
{
public void Flow()
{...}
}
I then have a base interface, (if we can call it that) simply defines
methods which return instances of objects of type IDalBalloon
public interface IDataFactory
{
IDalBalloon GetBalloon();
IDalLiquid GetLiquid();
}
This interface is implenmented by the specific implementation of
IDataFactory - these are the Sql and Oracle class libraries which are the
domain specific impementation of either for the Balloon class. An example
would look like this:
public class SqlDataFactory : IDataFactory
{
public IDalBalloon GetBalloon()
{
return new Balloon();
}
public IDalLiquid GetLiquid()
{
return new Liquid();
}
}
Now it is the type SqlDataFactory that I can plug in via the config file. I
could just as specify OracleDataFactory if I need to have an Oracle
implementation.
And then I use this code to return the instance of SqlDataFactory (Factory)
public class DalHelper
{
public static IDataFactory GetDalLayer()
{
string typeName = get the string "SqlDataFactory" from the config
Type type = Type.GetType(typeName);
return (SqlDataFactory)Avtivator.GetInstance(type, true);
}
}
So, from here I can call any implementation of Balloon with these 3 lines of
code:
IDataFactory df = DalHelper.GetDalLayer();
IDalBalloon balloon = df.GetBalloon();
balloon.Float();
I can think its fair to say there are two Factories going on in here. One by
the above code, which returns the SqlDataFactory object. And then the
sub-factory methods in SqlDataFactory itself. But then, I may be wrong! But
it seems to solve my two problems.
I'm off to reclaim my life!
Codex Twin <co***@gmail.com> wrote: "Jon Skeet [C# MVP]" <sk***@pobox.com> wrote Right. You might want to consider using the Spring framework for this kind of thing. I'm using it in Java at the moment, and it's wonderful. I haven't used the .NET version, but I've looked at some of the docs and it looks basically the same (as I'd expect). See http://www.springframework.org for more information.
<snip - I think the above covers it> I THINK have found a solution which is a happy medium which solves the problems:
<snip>
Goodo.
And then I use this code to return the instance of SqlDataFactory (Factory)
public class DalHelper { public static IDataFactory GetDalLayer() {
string typeName = get the string "SqlDataFactory" from the config
Type type = Type.GetType(typeName); return (SqlDataFactory)Avtivator.GetInstance(type, true); } }
I assume this is meant to be a cast to IDataFactory rather than
SqlDataFactory :)
So, from here I can call any implementation of Balloon with these 3 lines of code:
IDataFactory df = DalHelper.GetDalLayer(); IDalBalloon balloon = df.GetBalloon(); balloon.Float();
I can think its fair to say there are two Factories going on in here. One by the above code, which returns the SqlDataFactory object. And then the sub-factory methods in SqlDataFactory itself. But then, I may be wrong! But it seems to solve my two problems.
I think you may find it easier to just have one factory in the end,
which can handle everything. (Again, I'd suggest Spring as an excellent
way of doing this - you can use Spring and still have all the same
interfaces etc.) Then again, depending on your needs it may be better
to split it up as you have done...
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet
If replying to the group, please do not mail me too This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Sandman |
last post by:
I am splitting a text block into paragraphs, to be able to add images and stuff
like that to a specific paragraph in a content management system.
Well, right now I'm splittin on two or more...
|
by: Rakesh |
last post by:
Hi,
I was 'googling' to look out for some ways of optimizing the code
and came across this term - 'hot / cold splitting'.
In short, the discussion is about splitting heavily accessed ( hot )...
|
by: Dan |
last post by:
I have a need to make a set of classes that all share the same public
methods, some implementation and some data. So, I made an abstract
base (BaseClass) with an interface (IBaseClass) and a...
|
by: Frnak McKenney |
last post by:
I'm running into problems with VisualStudio.NET2003 and Windows
Forms inheritance. It _feels_ like a bug, but it could just as well
be a misunderstanding on my part regarding how the VS Designer...
|
by: Charles Law |
last post by:
I have just been asked how to share functions and properties between two
running applications. For example, I have App1 and App2 both running on the
same machine. App1 uses a DLL (perhaps) that...
|
by: lovecreatesbeauty |
last post by:
I'm disturbed on this question on a long time. I think if I finally get
understand it with your kind help, I will get close to a excellent C++
programmer. And I only can rely on your expertise and...
|
by: David Belohrad |
last post by:
Dear All,
could someone give a hint? I'd like to share the resources as follows:
A shared class which works as counter of number of shared resources:
class Shared
{
public:
Q_PCBShared()...
|
by: Mike |
last post by:
Class A
public objX
I want to create 2 or more instances of Class A and have the same value for
objX in all instances.
Instance1 of Class A
Instance2 of Class A
Instance3 of Class A
|
by: LL-JK |
last post by:
Hi Guys,
Hopefully you will understand my problem.
I have a spreadsheet that i import into a table which contains job
data. Using a number of queries i can filter the data as requested.
What...
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
|
by: ryjfgjl |
last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
| |