How to skip a step in the parent class?

C

Curious

I have two projects, "CORE" and "Console". The "Console" project uses
objects and their associated methods defined in the "CORE" project.
Therefore, the "Console" project is depedent on the "CORE" project.

In "CORE" project, I have two classes, "Report" and "CoreConnection".
There is a "Files" method in the "Report" class that calls methods in
the "CoreConnection" class, specifically, "GetListFromStoredProcedure"
which in turn calls "RunSafeSql", which in turn calls
"InternalExecuteGenericSqlCall" which in turn, calls
"WriteSqlCallEndEvent".

In "Console" project, I have a class "JoinConsoleCoreConnection" which
is a child class of "CoreConnection". Now I call the "Files" method in
the "Report" class from a method in "JoinConsoleCoreConnection". So it
calls chains of methods in the "CoreConnection" class, including
"GetListFromStoredProcedure" which in turn calls "RunSafeSql", which
in turn calls "InternalExecuteGenericSqlCall", which in turn calls
"WriteSqlCallEndEvent".

Now I need to make a change: When I call the "Files" method in the
"Report" class ***from "JoinConsoleCoreConnection"***, I want to skip
the call to "WriteSqlCallEndEvent". What changes are necessary in
order to skip this step?

I understand that I probably will need to redefine the
"InternalExecuteGenericSqlCall" method to not call
"WriteSqlCallEndEvent" in the calling class,
"JoinConsoleCoreConnection". However, that will not work since
"RunSafeSql" in "CoreConnection" will only call the
"InternalExecuteGenericSqlCall" in "CoreConnection" (instead of the
one in "JoinConsoleCoreConnection").

Any advice?
 
A

Anthony Jones

Curious said:
I have two projects, "CORE" and "Console". The "Console" project uses
objects and their associated methods defined in the "CORE" project.
Therefore, the "Console" project is depedent on the "CORE" project.

In "CORE" project, I have two classes, "Report" and "CoreConnection".
There is a "Files" method in the "Report" class that calls methods in
the "CoreConnection" class, specifically, "GetListFromStoredProcedure"
which in turn calls "RunSafeSql", which in turn calls
"InternalExecuteGenericSqlCall" which in turn, calls
"WriteSqlCallEndEvent".

In "Console" project, I have a class "JoinConsoleCoreConnection" which
is a child class of "CoreConnection". Now I call the "Files" method in
the "Report" class from a method in "JoinConsoleCoreConnection". So it
calls chains of methods in the "CoreConnection" class, including
"GetListFromStoredProcedure" which in turn calls "RunSafeSql", which
in turn calls "InternalExecuteGenericSqlCall", which in turn calls
"WriteSqlCallEndEvent".

Now I need to make a change: When I call the "Files" method in the
"Report" class ***from "JoinConsoleCoreConnection"***, I want to skip
the call to "WriteSqlCallEndEvent". What changes are necessary in
order to skip this step?

I understand that I probably will need to redefine the
"InternalExecuteGenericSqlCall" method to not call
"WriteSqlCallEndEvent" in the calling class,
"JoinConsoleCoreConnection". However, that will not work since
"RunSafeSql" in "CoreConnection" will only call the
"InternalExecuteGenericSqlCall" in "CoreConnection" (instead of the
one in "JoinConsoleCoreConnection").
Any advice?


Sounds like you need to read up on virtual methods and the override keyword.
I'm using C# parlance since you haven't specified the language but the
concept is the same in other languages.

Add :-

protected virtual bool CanWriteSqlCallEndEvent { get {return true; } }

to the CoreConnection class.

In InternalExecuteGenericSqlCall use:-

if (CanWriteSqlCallEndEvent)
{
// your code to call WriteSqlCallEndEvent
}
else
{
// what you might need to do otherwise
}

Now in JoinConsoleCoreConnection:-

protected override bool CanWriteSqlCallEndEvent {get {return false;} }


However this sort of thing is what those in the refactoring world would call
a bad smell. It just doesn't feel right which means that perhaps you need
to reconsider the architecture.
 
C

Curious

Anthony,

A question for you: Will the property, "CanWriteSqlCallEndEvent", can
be set in the parent class "CoreConnection" if the original caller,
"JoinConsoleCoreConnection", sets it in the child
("JoinConsoleCoreConnection") class?
 
C

Curious

Anthony,

In your opinion, how to re-engineer the architecture for this purpose?

FYI, it turns out to be even more complicated than what I described, I
missed something in the middle. It calls a method, "GetFiles", in the
"PrivateConnection" class which is a child class of "CoreConnection".
Details are descibed in pseudo code below:

-------------------------------------------------------------------------------
class Report
{

Files()
{
GetInitialFiles();
}

GetInitialFiles()
{
PrivateConnection InternalConnection;
InternalConnection.GetFiles();
}
}

class CoreConnection
{

GetListFromStoredProcedure()
{
RunSafeSql();
}

RunSafeSql()
{
InternalExecuteGenericSqlCall();
}

InternalExecuteGenericSqlCall()
{

WriteSqlCallEndEvent(); // This should be skipped if the original
caller is from JoinConsoleCoreConnection

}
}

class PrivateConnection : CoreConnection
{

GetFiles()
{

CoreConnection cc = new CoreConnection ();

cc.GetListFromStoredProcedure();
}
}


class JoinConsoleCoreConnection : CoreConnection
{

FilterReportFiles()
{
Report aReport = new Report();
aReport.Files();

}
}

-------------------------------------------------------------------------------

How to skip the step of "WriteSqlCallEndEvent" in
"InternalExecuteGenericSqlCall" if the caller is from
"JoinConsoleCoreConnection" in this case (since it's actually using
PrivateConnection instead of CoreConnection)? Thanks!
 
C

Curious

Anthony,

In your opinion, how to re-engineer the architecture for this
purpose?

FYI, it turns out to be even more complicated than what I described, I
missed something in the middle. It calls a method, "GetFiles", in the
"PrivateConnection" class which is a child class of "CoreConnection".
Details are descibed in pseudo code below:

---------------------------------------------------------------------------­----
class Report
{

Files()
{
GetInitialFiles();
}

GetInitialFiles()
{
PrivateConnection InternalConnection;
InternalConnection.GetFiles();
}
}


class CoreConnection
{

GetListFromStoredProcedure()
{
RunSafeSql();
}


RunSafeSql()
{
InternalExecuteGenericSqlCall();
}

InternalExecuteGenericSqlCall()
{


WriteSqlCallEndEvent(); // This should be skipped if the
original
caller is from JoinConsoleCoreConnection


}
}


class PrivateConnection : CoreConnection
{

GetFiles()
{

CoreConnection cc = new CoreConnection ();

this.GetListFromStoredProcedure(); // This goes straight to
"GetListFromStoredProcedure" in parent class, "CoreConnection"
}
}


class JoinConsoleCoreConnection : CoreConnection
{

FilterReportFiles()
{
Report aReport = new Report();
aReport.Files();

}
}

---------------------------------------------------------------------------­----

How to skip the step of "WriteSqlCallEndEvent" in
"InternalExecuteGenericSqlCall" if the caller is from
"JoinConsoleCoreConnection" in this case (since it's actually using
PrivateConnection instead of CoreConnection)? Thanks!
 
A

Anthony Jones

Curious said:
Anthony,

A question for you: Will the property, "CanWriteSqlCallEndEvent", can
be set in the parent class "CoreConnection" if the original caller,
"JoinConsoleCoreConnection", sets it in the child
("JoinConsoleCoreConnection") class?

The question is a little difficult to decipher. The CanWriteSqlCallEndEvent
cannot be set by either class because it doesn't have set defined. Its
readonly with a fixed value.

Generally for instances of CoreConnection the property will have a value of
true. However in more specific JoinConsoleCoreConnection instances the
property will have a value of false.
 
C

Curious

Thanks for the answer! I've added a "set" method for this property in
the parent class, CoreConnection. This way, it's not readonly.
 
A

Anthony Jones

Curious said:
Thanks for the answer! I've added a "set" method for this property in
the parent class, CoreConnection. This way, it's not readonly.


I'm not sure I understand why you would want to set it. Its value is fixed.
 
S

Sujith S Varier

Hello,
Can't you add the code to check the "current instance type" and decide
whether to execute a particular code

like..
modify your InternalExecute.... method as follows....

InternalExecuteGenericSqlCall()
{

if(this.GetType()==typeof(JoinConsoleCoreConnection)){
//do nothing
}
else
{
WriteSqlCallEndEvent();
}

}


regards
Sujith


Anthony,

In your opinion, how to re-engineer the architecture for this
purpose?

FYI, it turns out to be even more complicated than what I described, I
missed something in the middle. It calls a method, "GetFiles", in the
"PrivateConnection" class which is a child class of "CoreConnection".
Details are descibed in pseudo code below:

---------------------------------------------------------------------------­----
class Report
{

Files()
{
GetInitialFiles();
}

GetInitialFiles()
{
PrivateConnection InternalConnection;
InternalConnection.GetFiles();
}
}


class CoreConnection
{

GetListFromStoredProcedure()
{
RunSafeSql();
}


RunSafeSql()
{
InternalExecuteGenericSqlCall();
}

InternalExecuteGenericSqlCall()
{


WriteSqlCallEndEvent(); // This should be skipped if the
original
caller is from JoinConsoleCoreConnection


}
}


class PrivateConnection : CoreConnection
{

GetFiles()
{

CoreConnection cc = new CoreConnection ();

this.GetListFromStoredProcedure(); // This goes straight to
"GetListFromStoredProcedure" in parent class, "CoreConnection"
}
}


class JoinConsoleCoreConnection : CoreConnection
{

FilterReportFiles()
{
Report aReport = new Report();
aReport.Files();

}
}

---------------------------------------------------------------------------­----

How to skip the step of "WriteSqlCallEndEvent" in
"InternalExecuteGenericSqlCall" if the caller is from
"JoinConsoleCoreConnection" in this case (since it's actually using
PrivateConnection instead of CoreConnection)? Thanks!
 
A

Anthony Jones

Sujith S Varier said:
Hello,
Can't you add the code to check the "current instance type" and decide
whether to execute a particular code

like..
modify your InternalExecute.... method as follows....

InternalExecuteGenericSqlCall()
{

if(this.GetType()==typeof(JoinConsoleCoreConnection)){
//do nothing
}
else
{
WriteSqlCallEndEvent();
}

}


That requires the CoreConnection class to be aware that a
JoinConsoleCoreConnection class exists. This is not good design. A general
class should not have knowledge of any specific specialization of itself.
 
S

Sujith S Varier

Yes!!!
You are right...

Anthony Jones said:
That requires the CoreConnection class to be aware that a
JoinConsoleCoreConnection class exists. This is not good design. A
general
class should not have knowledge of any specific specialization of itself.
 

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