4

I am wondering if I am approaching my project the right way in terms of OOP. My project consists of a windows console application in c#. The point of the application is to take user input, convert it to an sql query and query the connecting database and then spit out the information in a reader-friendly format that the user requested. I have the following 3 classes right now:

Class: commandLineInterpreter extends sqlQueries

this class prints out the commands that the user can utilize. it also takes the user input.

Class: sqlQueries extends dbConnect

this class holds the sql queries that will query the database depending on what the user is inputing.

Class: dbConnect this class initlizes the database connection and prints out a message saying if it suceeded or not.

as you can see i have the commandlineInterpreter class that extends the sql query class that then extends the db connect class.

When I initlize the commandline class in the main() function, it automatically intitlizes the other extend classes as well. I did this because without connecting to the DB then the commandLine interpreter is useless as it cant provide any answers.

My question is, even though these classes aren't related in an inheritance sense of OOP, does it still make sense to do class inheritance this way? or is there a better way to organize my code?

john
  • 1,057
  • 1
  • 17
  • 28

4 Answers4

7

I slightly disagree with this design as it seems your objects have no relational hierarchy.

The command line interpreter should not know anything about the SQL Queries class. It's kind of a separation of concern and it's only job is to read user input, with the collected input you can then simply pass it to the next service layer, i.e. the SQL Queries class.

Darren
  • 68,902
  • 24
  • 138
  • 144
2

Inheritance is a very powerful tool that is available in OOP-languages compared to others such as C. However, think very carefully when and where you apply inheritance because, basically, it must be used only when your design really calls for it. That is, when you're really sure that a 'B is-an A' kind of relationship exists. If you can get away with it, always prefer composition over inheritance, because it leaves much more flexibility in your design.

For example, what if you want to add some extra functionality to DbConnect? You would now have to consider how this change would not break any assumptions that were made by any sub-classes in your design. With composition, classes are left and designed in much more isolation. Moreover, inheritance also ties together implicitly the lifetimes and states of different classes, which means they really have to be aligned for inheritance to work.

The fact that your CommandLineInterpreter class required a connection to the database somehow does not imply that is has to inherit from that class. Just use composition and create a connection inside the interpreter whenever you need one.

Wim.van.Gool
  • 1,290
  • 1
  • 10
  • 19
1

Inheritance usually expresses a relation of the kind "A is a B". Example: An apple is a fruit. But here you have completely unrelated classes. Keep them distinct and create separate objects for the distinct tasks.

The dbConnect class mixes two very distinct aspects: Connecting to the DB and displaying a message. The commandLineInterpreter class should be the only one interacting with the user and displaying messages. The dbConnect class seems superfluous. The connection functionality should go to the sqlQueries class. Possibly create a method bool Connect() there that you can call from the command line interpreter. The Boolean result can be used to display an appropriate message.

class SqlQueries
{
    private SqlConnection connection;

    public bool Connect()
    {
        Try {
            connection = ...
            connection.Open();
            return true;
        } catch {
            return false;
        }
    }

    ....
}

class CommandLineInterpreter 
{
    public void Run()
    {
        var sqlQueries = new SqlQueries();
        if (sqlQueries.Connect()) {
            Console.WriteLine("connected");

            // run your interpreter here
            ...
        } else {
            Console.WriteLine("Connection error! Not connected.");
        }
    }
}

In C# types (like classes), properties, methods and events have PascalCase. Fields, method parameters and local variables have camelCase.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
1

There is no need for inheritance between your commandLineInterpreter, sqlQueries, dbConnect classes as the inheritance is needed when some class (including its own features) also contains the features of some other class.

But here there is an association (an OOP concept when one class is associated (when class do some work and next class do remaining) to the other class) can used between sqlQueries and dbConnect class.

For an association kind of relationship use dbConnect object in sqlQueries.

  • What would an association type of relationship look like? – john Oct 12 '14 at 18:55
  • It depends. If a class A really 'owns' an instance of type B and manages it's lifetime, A typically creates an instance of B in it's constructor and assigns it to a private readonly attribute. However, there are no specific rules to how a 'design time relationship' between classes should be programmed. This is all very dependent on requirements such as instance lifetimes, performance/disposal of instances, ownership of instances, availability of information at different points in time, etc etc – Wim.van.Gool Oct 12 '14 at 19:10