How to skip a step in the parent class?

  • Thread starter Thread starter Curious
  • Start date Start date
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?
 
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.
 
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?
 
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!
 
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!
 
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.
 
Thanks for the answer! I've added a "set" method for this property in
the parent class, CoreConnection. This way, it's not readonly.
 
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.
 
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!
 
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.
 
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.
 
Back
Top