My struggles in understanding and learning about Object Oriented design, and the tools and knowledge I've taken from them.

Tuesday, December 29, 2009

Factory Design Pattern

I try not to get too wrapped up in design patterns, because one can really overuse them, or use them in inappropriate places, if one is not careful; that's not to say that design patterns don't have their place, because I think design patterns are common ways programmers have found to "best practice" object oriented programming.

But even though I try not to over-emphasize design patterns, there are several design patterns that I find myself using over-and-over again. One such pattern is the factory pattern.

Factory patterns are often used with inheritance or interfaces, because one of the best uses of a factory design pattern is for figuring out what the best version of object is to instantiate, based on some input.

A factory pattern is basically an object that has some method that is a big if-statement (or switch statement, if one prefers). For instance, suppose your configuration file had a configuration for what type of data access you want to use (MSSQL, XML, Oracle, mySQL, etc).

Here's a simple example. The classes (along with accompanying interface) would look something like this:

interface IAccessLayer
{
    string GetQueryResultsAsString(string query);
   DataTable GetQueryResultsAsDataTable(string query);
   void ExecuteModificationQuery(string query);
}

Implementing classes might look something like this:

class MSSQLAccessLayer : IAccessLayer
{
   ///Implement public contract from IAccessLayer
}

class mySQLAccessLayer : IAccessLayer
{
   ///Implement public contract from IAccessLayer
}

class XMLAccessLayer : IAccessLayer
{
   ///Implement public contract from IAccessLayer
}

class OracleAccessLayer : IAccessLayer
{
   ///Implement public contract from IAccessLayer
}

If the configuration file had a finite set of allowable strings for the access layer that were as follows:

MSSQL
ORACLE
XML
MYSQL

Then, the factory method would look something like this:


public IAccessLayer GetAccessLayer(string dataAccessMedium)
{
   dataAccessMedium = dataAccessMedium.ToUpper();
   if(dataAccessMedium == "MSSQL")
   {
      return new MSSQLAccessLayer();
   }

   else if(dataAccessMedium == "ORACLE")
   {
      return new OracleAccessLayer();
   }

   else if(dataAccessMedium == "MYSQL")
   {
      return new mySQLAccessLayer();
   }
   else if(dataAccessMedium == "XML")
   {
      return new XMLAccessLayer();
   }
   else
   {
      throw new Exception("Error. " + dataAccessMedium + " is not a valid data access method");
   }
}


The above is one application of the factory pattern. There are lots of variants, and lots of applications, which is why I felt so inclined to write about them.

By the way, check out my new project at SourceForge: TestAutomation. It helps to automate software testing in Windows environments. https://sourceforge.net/projects/testautomation/ . I'm always looking for people to join the project.

Monday, December 21, 2009

When to use Inheritance versus Interfaces

I tend to lean towards using interfaces, as opposed to inheritance. The reason for this is multi-fold:

1. I can implement multiple interfaces on a single class in C#. The only way I can implement multiple classes in C# is to have a big inheritance chain, which tends to get confusing, when going back to review code weeks or months later.
2. With interfaces, there's no ambiguity in who implements what behavior. There may be methods one overrides in C#, and that can get confusing when implementing a child class (ie Does the behavior this class uses match the parent class, or does it have different behavior?). With interfaces, I must define the behavior in each implementation.
3. In my world, and the types of applications I build, I don't see behavior being so expandable as to support a lot of inheritance; obviously, there are times when it makes complete sense to use inheritance, but for the most part, objects aren't that related.

That being said, there are times when I choose to use an interface, and find that it was an inappropriate choice for the solution I was trying to build. The reason it becomes inappropriate is because, when I first chose to use an interface, I didn't consider some of the granularity of the classes, and I start realizing that I'm re-doing a lot of work that I wouldn't have to do if I had chosen inheritance.

There are canned solutions that make solving these problems easier, such as abstract classes; however, in this example, I'll refrain from considering the abstract class as a possible solution.

Instead, I'll try to iterate some reasons to choose an interface, as opposed to inheritance, and vice-versa:

Reasons to choose an interface
1. Uncommon behavior, but a common "fingerprint": If you envision a set of classes having similar public methods, but uncommon private members, constructors, and behaviors, then an interface is probably the right choice
2. Defining multiple ways to arrive at a solution: The data access layer is a good example of this. An interface is a great way to have multiple options for database storage, and having that be a configurable piece of the software
3. Multiple developers working on common tasks: Interfaces were designed to solve problems that arise when multiple people are working independently of one another. Defining an interface (often referred to as a public contract) is a way to keep people on the same page.

Reasons to choose inheritance
1. Similar-looking classes: If classes begin to look very similar, especially at the private-member level, refactoring to make those private members protected, and implementing inheritance is probably a good decision
2. Common Behavior: Let's face it: interfaces exist because common behavior does occur between classes. "Inventing" common behavior, and forcing inheritance onto multiple classes that do not have a real relationship is not a good thing, though.

A lot of the decision to choose inheritance or interfaces comes down to style and preference; however, these are a couple "fun facts" I've gleamed in the process of writing code.

By the way, check out my new project at SourceForge: TestAutomation. It helps to automate software testing in Windows environments. https://sourceforge.net/projects/testautomation/

Tuesday, September 1, 2009

Decoupling in Relational Databases

Before I understood relational databases, the tables I put in my databases, and the resulting architectural output was bad. And sloppy. I would put columns into tables that had 1-to-1 relationships with their foreign key counterpart, and I would duplicate those columns, to generate the effect of a bridge table.

For instance, if I had a database where I had a table called USER, and another table called GROUP, and the relationship between USER and GROUP was such that a USER could belong to 1 or more groups, I may have created the USER table like the one below

USER
-----
id - int (auto increment)
firstname - varchar(50)
lastname - varchar(50)
fk_group1 - int (relates to GROUP table)
fk_group2 - int (relates to GROUP table)
fk_group3 - int (relates to GROUP table)

As you can see in the above table, I may have made a bunch of columns that have a foreign key relationship with the GROUP table.

That's all fine and dandy, except in the event that a USER belongs to 1000 GROUPS. Every time a USER exceeded the number of groups available in the USER table, I would have to go back and add more columns.

The other implication of not understanding some basic tenets of relational databases is that the application code to represent the relationship between USER and GROUP was just as sloppy (or even worse!) than the database design.

It was not until I started exploring concepts in decoupling that I realized the error of my ways. One of the best ways to implement decoupling in relational databases is with bridge tables. A bridge table is a table whose relationship with other tables creates a Many-to-Many relationship. In a many-to-many relationship paradigm, the two tables are decoupled, because they don't have a direct relationship with one another.

For instance, to implement a bridge table that acts as a go-between for USER and GROUP, I would modify the USER table to look as follows:

USER
-----
id - int (auto increment)
firstname - varchar(50)
lastname - varchar(50)

And, just for completeness sake, I'll show what the GROUP table looks like

GROUP
-----
id - int (auto increment)
groupname - varchar(50)

The bridge table to allow for as many user memberships as I wanted, I would create a table called USER_GROUP (you can name bridge tables whatever you want, I just like to have the name format be something like TABLEa_TABLEb).

The USER_GROUP table would look as follows:

USER_GROUP
-----------
id - int (auto increment)
fk_user - int (relationship with USER)
fk_group - int (relationship with GROUP)

Then, if I wanted to build a SQL query to show all groups, and their associated users, it would look something like this:

SELECT GROUP.groupname, USER.firstname, USER.lastname
FROM GROUP
INNER JOIN USER_GROUP ON GROUP.id=USER_GROUP.fk_group
INNER JOIN USER ON USER_GROUP.fk_user=USER.id
ORDER BY GROUP.groupname, USER.lastname, USER.firstname

This decoupling also makes it easier to write code for, as well, because each of the concepts (USER and GROUP) can exist independently of one another, yet the logical relationship still exists (GROUP "has a" user). In the composition relationship between GROUP and USER, I can demonstrate that with either a LIST variable, or by implementing an IEnumerable interface.

Saturday, August 29, 2009

Many-To-One Composition Relationships

Many-to-one relationships are very common, especially in applications involving databases. The reason for this is that the many-to-one paradigm is a common scenario in the real world, and programming languages, databases, and other technical constructs attempt to represent the real world.

Consider the relationship between a car and its tires. Composition solves the problem of how a car "has" tires. It would go something like this:


///Here is a generic implementation of a Car class
public class Car
{
   private List _allFourTires;

   public Car()
   {
      _allFourTires = new List();
   }
}

///And here is the class "Tire", which composes Car
public class Tire
{
   private string _model;

   private string _type;

   private int _width;

   private double _aspectRatio;

   ///You get the idea
}


The List<> type is a great way to solve the problem of many-to-one composition, but there is another way in C#, and it is called "Collections."

Collections are implemented in a lot of the base .Net objects, including DataSets and DataTables.

For instance, consider the below code:


///Assume I have a DataSet called myDataSet, and it has
///a bunch of datatables in it
foreach(DataTable table in myDataSet.Tables)
{
   foreach(DataRow row in table.Rows)
   {
      ///Do some stuff with the table
   }
}


The reason DataSet has a .Tables and a DataTable has .Rows is because they implement the IEnumerable .Net interface.

As mentioned above, an alternative to implementing the IEnumerable is to have a DataSet have a List<> variable with DataTables, and to have a DataTable have a List<> variable of DataRows, but over time, the IEnumerable is easier to manage.

Interfaces are a public contract between classes. They're basically a grocery list, and if you plan on using them, you must have everything on the grocery list. Luckily, IEnumerable has only one "item" on the list. That item is a public method called GetEnumerator().

When implementing a paradigm such as this, the effect you're really having is to create a bridge between the container class (Car), and the containee class (Tire). So, in between Car and Tire goes the IEnumerable class. In the below example, we'll call it TireCollection


/// The container class
public class Car
{
   ///A global variable of the bridge (IEnumerable) class
   private TireCollection _tireCollection;

   /// Constructor - makes a tire collection based
   /// on the model
   public Car(string model)
   {
       makeTireCollection(model);
   }

   /// This is just sort of a factory method - I could
   /// get more abstract, and create a TireCreatorFactory
   /// class, but I think this is sufficient for this example
   private void makeTireCollection(string model)
   {
       if (model == "Ford")
          makeFordTireCollection();
   }

   /// Makes the tire collection for Ford cars
   private void makeFordTireCollection()
   {
       List tireList = new List();
       tireList.Add(new Tire("Bridgestone", "P", 215, 75));
       tireList.Add(new Tire("Bridgestone", "P", 215, 75));
       tireList.Add(new Tire("Bridgestone", "P", 215, 75));
       tireList.Add(new Tire("Bridgestone", "P", 215, 75));
       _tireCollection = new TireCollection(tireList);
   }

   /// This is an unnecessary attribute, but if I didn't have this
   /// I would have to do:
   /// foreach(Tire in car)...
   /// With this attribute, I can do
   /// foreach(Tire in car.Tires)
   /// I like that better
   public TireCollection Tires
   {
       get { return _tireCollection; }
   }
}


Notice in the above, I have an attribute called Tires. As mentioned in the comments, this is an unnecessary attribute, but I think it looks cleaner when we go to implement the Car class.

Below is the IEnumerable class TireCollection. Note that it has a method called GetEnumerator():


/// This essentially acts as a bridge between
/// the Car class and the tire class
public class TireCollection : IEnumerable
{
   ///We do have a List<> variable in the TireCollection.
   ///So, in effect, we don't get away from having a List<>
   ///variable...the collection simply buys us a "decoupling"
   ///effect
   List _tireList;

   public TireCollection(List tireList)
   {
       _tireList = tireList;
   }

   public IEnumerator GetEnumerator()
   {
       return (_tireList as IEnumerable).GetEnumerator();
   }
}


Then, the Tire class looks pretty typical


/// This is the Tire class - there are many tires on a car
/// Well...four, anyway
public class Tire
{
   private string _model;

   private string _type;

   private int _width;

   private double _aspectRatio;

   /// Constructor
   public Tire(string model, string type, int width, double aspectRatio)
   {
       _model = model;
       _type = type;
       _width = width;
       _aspectRatio = aspectRatio;
   }

   /// This is simply a public method
   public string GetTireProperties()
   {
       return "Tire is of model " + _model + " with type " + _type;
   }
}


Now comes the question of how to implement this code. This part is the simple part:


Car car = new Car("Ford");
foreach (Tire tire in car.Tires)
{
   ///Output tire.GetTireProperties()
}


It is a few more steps to implement an IEnumerable interface, but it's worth it for those solutions that wish to have looser coupling between the composition relationship.

In the comments in the makeFordTireCollection() method in Car, I mention that I could have just as easily implemented a TireCreatorFactory class that assembles a Tire collection for me. The effect of doing so would have provided a higher degree of decoupling between Car and Tire, which is probably a more optimal situation, since loosely coupled class interactions are highly valued in object oriented design.

Friday, August 21, 2009

Is-A Versus Has-A

Is-A versus Has-A

Believe it or not, the concept of whether a class "Is a [something]" or "Has a [something]" comes up quite a bit in object oriented design. For instance, consider the questions "Is a transmission a car?" and "Does a car have a transmission?"

Clearly, the second question is the only of the two that one would answer in the affirmative. A transmission is not a car, but a car does have a transmission. This is a classic "Is-A/Has-A" example. And sometimes the answer to the questions are not so clear cut, particularly if the relationship is more obscure, like the relationship between a wall and sheetrock. For example, sheetrock, if hanged, could perform the duties of a wall, and a wall can contain sheetrock. The implementation of the solution to that question could probably be solved with either implementing a "Is-A" paradigm, or a "Has-A" paradigm.

So, I haven't described how "Is-A" and "Has-A" are implemented in object oriented design. Well the answer to that is really quite simple:

"Is-A" is implemented via INHERITANCE
"Has-A" is implemented via COMPOSITION

INHERITANCE

Inheritance is a good solution when some component would be logically defined, more abstractly, as another object.

For instance, think of fruit. Fruit is really more of an abstract concept than it is an implementation. Fruit can either have seeds (raspberries), or not have seeds (bananas). It can also have rind (bananas), or not have rind (raspberries). These attributes (seeds, rinds) are values that the more abstract "fruit" has.

The implementation of this code could be as follows:

///Below is the "Fruit" class

public class Fruit
{
   private bool _hasSeeds;
   private bool _hasRind;

   ///Public attribute for whether or not the fruit has seeds
   public bool HasSeeds
   {
      get { return _hasSeeds; }
      set { _hasSeeds = value; }
   }

   ///Public attribute for whether the fruit has a rind
   public bool HasRind
   {
      get { return _hasRind; }
      set { _hasRind = value; }
   }   
}

///Public implementation of Banana
///Inherits from Fruit
public class Banana : Fruit
{
   ///Because the nature of a banana lends itself
   ///to knowing whether or not it has seeds and rind
   ///I will set those attributes in the constructor
   ///There is no reason that the class who calls
   ///Banana should have to know that a banana does not
   ///have seeds and does have a rind.
   public Banana()
   {
      this.HasSeeds = false;
      this.HasRind = true;
   }

   public void Peel()
   {
      ///Do some kind of action to peel the banana
      ///Since Peel() is not common among all fruits
      ///Peel() does not have to be in the Fruit class
      ///However, there may be reasons to put it in there
      ///anyway. It depends on how similar the behavior
      ///is for all fruits' Peel() behavior
   }
}

///Public implementation of Banana
///Inherits from Fruit
public class Raspberry : Fruit
{

   ///Like in Banana, raspberries HasSeeds and HasRind
   ///attributes are set
   public Raspberry()
   {
      this.HasSeeds = true;
      this.HasRind = false;
   }
}


As you can see, this example lends itself very well to the "Is-A" paradigm, because clearly, Bananas and Raspberries are "Fruit." Also note that in the above, I did not put the Peel() method in the Fruit class, because it didn't seem to belong there. If I have an issue where many fruits need to have the Peel() behavior defined in them, I could do one of the following:

1. Create an interface, and have any peelable fruit invoke it:

public interface IPeelableFruit
{
   ///Notice how there is no implementation in the interface's Peel()
   ///This is because an interface has no implementation
   ///It is simply a public contract between anyone implementing it
   void Peel();
}


Making an interface like the above would make a lot of sense if each fruit's implementation of Peel() were significantly different from one another.

With an interface, when I declare Banana, or any other peelable fruit, it would look like:

public class Banana : Fruit, IPeelableFruit
{
   public void Peel()...
}


2. I could create a PeelableFruit class, and a NonPeelableFruit class, and have subsequent classes inherit:

public class PeelableFruit : Fruit
{
   public PeelableFruit()
   {
      this.HasRind = true;
   }
}


Then declare Banana as follows:

public class Banana : PeelableFruit
{
...
}


What would happen in the above example is: PeelableFruit would be a fruit. Banana would be ("is-a") a PeelableFruit, and also a Fruit, because it would inherit from both. The technical term is "inheritance chain".

COMPOSITION

"Has-A" lends itself to object relationships where something contains something else, like the above example of a Car and a Transmission. But, suppose we wanted to really define, in a fruit, what a "Rind" is. This would give us a pretty good example of "Has-A", because a PeelableFruit "Has-A" Rind.

So, if I wanted to build a "Rind" class, I would do something like the following:


public class Rind
{
   private string _color;
   //Let's say this is how difficult the rind is
   //to peel
   //A banana would be something like 2, and an orange would
   //be 5
   private int _difficultyToPeel;

   private int _thicknessInMillimeters;

   ///Each of these private members would also have
   ///corresponding public members. I'll omit those

   public Rind(string color, int difficultyToPeel, int thicknessInMillimeters)
   {
      _color = color;
      _difficultyToPeel = difficultyToPeel;
      _thicknessInMillimeters = thicknessInMillimeters;
   }
}


So, now that the Rind class is defined, we can now put a Rind object into the PeelableFruit Class:


public class PeelableFruit : Fruit
{
   ///In the constructor, I instantiate the Rind object
   ///Otherwise, later on in the execution, I may forget
   ///and exceptions will get thrown
   ///Note the constructor had to be changed to facilitate
   ///the necessity to instantiate the
   ///Rind object (the color, difficulty, and thickness)
   ///parameters
   public PeelableFruit(string rindColor, int difficultyToPeel, int thicknessInMillimeters)
   {
      this.HasRind = true;
      this.PeelableFruitRind = new Rind(rindColor, difficultyToPeel, thicknessInMillimeters);
   }

   protected Rind PeelableFruitRind;
}


Then, when it comes time to instantiate a banana, doing so gives the banana much more robustness:

public class Banana : PeelableFruit
{
   ///I don't really know if this is "best practice" to make a class so knowing of how
   ///it implements a parent class, but I don't care. This is how I will continue
   ///to invoke this sort of inheritance
   public Banana() : base("YELLOW", 2, 7)
   {

   }
}


Note that, when Banana gets instantiated, it will inherit the PeelableFruit's protected variable PeelableFruitRind, and that fruit rind will have a color of "YELLOW", a peeling difficulty of 2, and a thickness of 7 millimeters. Now, Banana "Has-A" rind, and that means it's using COMPOSITION.

Monday, June 15, 2009

Polymorphism

I've talked a bit about polymorphism before, but it's a very cool thing, when you apply it with something called a FACTORY.

Basically, a Factory is a big IF-Statement, that directs an object to do something, depending on what it really is.   A factory is a subset of a programming concept called a "Design Pattern."   More, hopefully, on that later.

Polymorphism is the unique ability of an object oriented language to have objects be more than one type of "thing."   It really is a real-world application of INHERITANCE.

So, consider the example of a Human Being.   A human being is a mammal.   So is a dog.   So is a cat.   There are common attributes that mammals share, which means that if we were to represent humans, dogs, cats, etc in a computer program, we could use inheritance to do it.

So, let's just throw out some code to do just that:


class Mammal
{
   ///Create Some Private Variables here
   private bool _hasHair, _givesBirthToLiveYoung;

   ///Expose some attributes here
   ///I make them protected
   protected bool HasHair
   {
      get { return _hasHair; }
      set { _hasHair = value; }
   }

   protected bool GivesBirthToLiveYoung
   {
      get { return __givesBirthToLiveYoung; }
      set { __givesBirthToLiveYoung = value; }
   }
}

class Human : Mammal
{
    private bool _walksUpright;
    public bool WalksUpright
    {
         get { return _walksUpright; }
         set { _walksUpright = value; }
    }
}

class Dog : Mammal
{
////Let's assume I put some attributes and behaviors here
}

class Cat : Mammal
{
////Let's assume I put some attributes and behaviors here
}


Now, in the above classes, Human, Dog, and Cat all inherit from Mammal the Gives Birth To Live Young and Has hair attributes.   Obviously there's a lot more that a mammal could give to our child-classes, but it's not necessary to go into all that.

I may have a factory class that has a method in it that takes a parameter of type Mammal, and then does something with the object, depending on if it is a Human, Dog, or Cat...or better yet, that method could take a list variable that has a bunch of Mammal objects in it (really the only reason I'm doing that here is to better describe polymorphism).

So consider my factory below:


public void DoWork(List inputMammalList)
{
    foreach(Mammal animal in inputMammalList)
    {
          if(animal is Human)
          {
               ///Do Human stuff
          }
          else if(animal is Dog)
          {
               ///Do Dog stuff
          }
          else if(animal is Cat)
          {
               ///Do Cat stuff
          }

    }
}


Polymorphism is very useful because it really allows you to apply a lot of concepts of object oriented programming.

One final note:   Some people favor the use of interfaces over inheritance (myself included).   The same sort of thing could be applied if mammal were an interface, and were implemented by Human, Dog, and Cat; of course, the difference would be that the interface mammal would have no real implementation.   It would only contain the names of the usable properties and behaviors the Human, Dog, and Cat classes could implement.

Thursday, January 29, 2009

Shifting Responsibility in OOP

One of the things I've struggled with in my learning of OOP is who should own responsibility for things. Coming from mainly procedural PHP, I basically followed the model of: Page calls method, which may call another method, and eventually work gets done because the page initiated the work.

For instance, consider the following code:


$booleanVar = getBooleanResult($someInput);
if($booleanVar == true)
{
callMethodA($someOtherInput);
}
else
{
callMethodB($yetEvenDifferentInput);
}


The above code works just fine, but it doesn't take advantage of what object oriented programming provides: ENCAPSULATION. As mentioned earlier, encapsulation is basically the ability to hide behavior (ie methods/functions) within a class, and never having to expose that method to the outside world. The implication is that you can let your class do the work of assembling the "guts" of an object, and not have to manipulate it through each iteration of code.

Let me use an example. Below is code that I have to manage, because I'm not taking full advantage of what OOP provides:


public class Human
{
///Here I create some private variables,
///and expose them publicly below
private int _numberOfArms, _numberOfEyes;
private string _eyeColor;

///My Public Properties
public int NumberOfArms
{
get { return _numberOfArms; }
set { _numberOfArms = value; }
}

public int NumberOfEyes
{
get { return _numberOfEyes;}
set { _numberOfEyes = value; }
}

public string EyeColor
{
get { return _eyeColor;
set { _eyeColor = value; }
}

public string Talk(string wordsToSay)
{
return "I am going to say: " + wordsToSay;
}

}

///...Then in some other object
Human Tim = new Human();
Tim.NumberOfArms = 2;
Tim.NumberOfEyes = 2;
Tim.EyeColor = "Green";
Tim.Talk("Hey man. I have " + Tim.NumberOfArms + " arms" );
///Output: I am going to say: Hey man. I have 2 arms


The above example follows the same model as my first example. It's all nice and fine that the Human class has some attributes (NumberOfArms, NumberOfEyes, and EyeColor) along with a behavior (Talk()), but the class in general is pretty dumb. One of the things I've come to realize in the time I've been programming is that if you can transfer responsibility from the caller of the object to the object itself, that is really much better.

That doesn't always work (for instance consider .Net controls, such as textboxes, labels, etc). Sometimes you need to manipulate those properties outside of the class; however, there are usually plenty of opportunities to transfer responsibility to the class.

Consider the revised example:


public class Human
{
///I'm adding a constructor here. The class knows how
///many arms, eyes, etc
///it has. It's asinine to assume otherwise in
///this case
public Human(string myFirstWords, string theirFirstWords)
{
///Notice I use keyword "this" here.
this.NumberOfArms = 2;
this.NumberOfEyes = 2;
this.Talk(myFirstWords);
this.Listen(theirFirstWords);
}

///Here I create some private variables,
///and expose them publicly below
private int _numberOfArms, _numberOfEyes;
private string _eyeColor;
private bool _endOfDiscussion = false;

///My Public Properties
public int NumberOfArms
{
get { return _numberOfArms; }
set { _numberOfArms = value; }
}

public int NumberOfEyes
{
get { return _numberOfEyes;}
set { _numberOfEyes = value; }
}

public string EyeColor
{
get { return _eyeColor;
set { _eyeColor = value; }
}

public string Talk(string wordsToSay)
{
return "I am going to say: " + wordsToSay;
}

///I listen here. And I continue to listen and talk
///until the end of discussion occurs.
public void Listen(string input)
{
while(!_endOfDiscussion)
{
if(this.needToRespond(input))
this.Talk(this.thinkUpResponse(input));

}
}

///Assume that input may be dead air. If the person
///I'm talking to
///actually says something, then I know I need
///to respond
private bool needToRespond(string input)
{
if(input != "")
{
return true;
}
return false;
}

///Here I use some encapsulation to do stuff that
///needn't be exposed to the real world.
///It sort of follows, if you think about it,
///because no one really sees a human think up a response
///A human's thoughts are conveyed when humans Talk()
private string thinkUpResponse(string input)
{
if(input.Contains("?"))
{
_endOfDiscussion = true;
return this.answerToQuestion(input);
}
else
{
return this.wittyBanter(input);
}
}

///This is a response to a question
private string answerToQuestion(string question)
{
///Do stuff here to figure out how
///to answer question
string answer = ///...
return answer;
}

///Figure out how to think up something funny
private string wittyBanter(string statement)
{
///Do stuff here to come up with
///a witty response
string wittyResponse = ///...
return wittyResponse;
}



}


In the above example, the constructor handles much of the initialization of the object; however, it doesn't need to be the constructor. It could just as easily be a method called Load(), or something like that. This is particularly useful if you can't populate an object until required information has been set, which would have to be done outside of the class. Just for fun, I added some extra behavior in the above class, which will help the Human class to have a conversation, and I use some private methods to demonstrate appropriate implementation of private vs. public methods (ie encapsulation). The above class probably won't get you very far in getting a class to actually have a decent conversation, because one would probably need to implement threads, or maybe some clever design pattern to make that work properly, but I think this is a decent example of shifting some of the responsibility away from the user of the class to the class itself.

Followers

Search This Blog

Powered by Blogger.