Where to find in-depth information about OOP? [closed] - oop

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I've found a lot of information on object oriented programming, but none of it seems to go into much detail. They always give you the shape example where cirlce, square, and retangle implement the interface. That's easy. I'm looking for something more real life and deeper into the process.
Does anybody have any good resources that are pretty in-depth? Or even code samples would be helpful.

That's a very broad question... Here's just a few links for you:
http://en.wikibooks.org/wiki/Object_Oriented_Programming
http://www.amazon.com/Object-Oriented-Programming-Peter-Coad/dp/013032616X
#Frankie - I've edited this for you having seen your comment. You're question is still very broad, but I'll try to provide a quick (very loosely thought) example of modeling some objects. The language I'll use is C#, though you can do it any OOP language you like.
We use Interfaces and Base Classes to represent very basic models. One of the defining differences between and Interface and a Base Class is that an Interface cannot be instantiated (think of it as a blueprint that cannot physically exist, just a design on paper)... a Base Class however can be instantiated (it can exist, and might be considered a prototype). Let's go from there...
Say we want to model vehicles... airplanes, cars, motorcycles, bicycles, etc. In our modeling brain we recognize that a Vehicle is the root of everything. Let's start then by defining a blueprint that works for all types of vehicles. For that we'll use an Interface
interface IVehicle
{
string Make;
string Model;
int Year;
}
Our interface now says, any object we build that implements this interface must have a Make, Model, and Year property. Now cars, bikes, motorcycles, etc. pop into our head, and we want to make classes for them... but we realize, lots of these vehicles have things in common. Let's make a prototype for all LandVehicles, and for that we'll use a Base Class that implements our blueprint interface IVehicle
public class LandVehicle : IVehicle
{
// We must physically implement the required members of the interface.
public string Make { get; set; }
public string Model { get; set; }
public int Year { get; set; }
// Then we can add things specific to land vehicles.
public int NumberOfWheels { get; set; }
public int TopSpeed { get; set; }
}
Now we have a prototype to build from. Let's design a Car and a Cycle
public class Car : LandVehicle
{
// because LandVehicle is a real object, we do not have to re-implement its memebers,
// we can just add to them:
public int MaxPassengers { get; set; }
public bool IsLuxury { get; set; }
public string FuelType { get; set; }
}
public class Bicycle : LandVehicle
{
public string Type { get; set; } // mountain, race, cruiser, etc.
public int NumberOfGears { get; set; }
}
With that, we can instantiate Cars and Bicycle objects... but by using Base Classes, we could create many other types of LandVehicles without having to add our basic properties to each one. This is one of the things than makes OOP so extensible.
Furthermore with our Interface, we left it open enough to make other base classes, perhaps WaterVehicles, AirVehicles, etc... and thus classes that derive from them.
This is just the very tip of the iceberg, and a rather off-the-top-of-my-head example, but it should get you started. If you have more specific questions or a specific scenario you'd like to use as context, let me know and I'll help out more.

Related

Why does an object's type refer to its interface? (Design Patterns: Elements of Reusable Object-Oriented Software book)

Why does object's type refer to its interface? Why the term type is used here? In terms of C++ I am not able to understand it.
Gamma, Erich. Design Patterns: Elements of Reusable Object-Oriented
Software (Addison-Wesley Professional Computing Series) (Kindle
Locations 593-596). Pearson Education. Kindle Edition.
An object’s class defines how the object is implemented. The class
defines the object’s internal state and the implementation of its
operations. In contrast, an object’s type only refers to its
interface—the set of requests to which it can respond. An object can
have many types, and objects of different classes can have the same
type.
An oversimplification...
Interface - a list of things that a class have and the things that it can do... a list of things that answer the "Whats"
Implementation - answers the question on "How" the "Whats" are accomplished.
Example:
An interface IPackageMover that does 2 things and 2 classes (types) that actually implements the interface (and also do other things aside from the interface requires)
// the interface
public interface IPackageMover
{
string GetName();
void public void MoveTo(Package package, string newAddress);
}
// the "type" that has the implementation
public class JoeThePackageMover : IPackageMover
{
public string GetName()
{
return "Joe";
}
public void MoveTo(Package package, string newAddress)
{
PickUp(package);
Drive(newAddress);
DropOff(package);
}
public void PickUp(Package package)
{
// do stuff
}
public void Drive(string newAddress)
{
// do stuff
}
public void DropOff(Package package)
{
// do stuff
}
}
// another "type" with the same interface
public class PassTheBuckPackageMover : IPackageMover
{
public string GetName()
{
return "What do you want it to be?";
}
public void MoveTo(Package package, string newAddress)
{
var joe = new JoeThePackageMover();
joe.MoveTo(package, newAddress);
}
public void Chill()
{
//do stuff
}
}
Why does object's type refer to its interface? Why the term type is used here? In terms of C++ I am not able to understand it.
Objects in OOP are not very different from the real world. For example :
A Car IS-A Vehicle. By this definition, a Car has the ability to transport people/cargo from one place to another.
A Car is also a Car. By this definition, it has the ability to be driven using a steering wheel.
In the above example, a Car IS-A Car and a Car is also a Vehicle because it can be driven using a steering wheel to move cargo/people from one place to another. In other words, the type of an object in the real world is defined by the things you can do with it (vis-à-vis it's interface.)
If we use the above analogy in programming, Car is a subclass of Vehicle and code that has a Car object can use all functions from Vehicle as well as Car. This would mean that a Car IS-A Vehicle and a Car. In conclusion, the type of object is defined by its interface, i.e the set of operations it supports.

Object-Oriented Programming: How to properly design, implement, and name a method which involve object interactions?

Language doesn't matter, it is generic object-oriented question(take java/C# etc). Take a simple concept.
A Person has a Car. The Person can drive the Car. Car doesn't usually drive or wander around, right? ``
But, usually in codes, we see methods like myCarObject.Drive().
Now when a Person is introduced, and the Person drives the car:
======================= First Way =================================
class Car{
int odometer;void drive(){ odometer++; }
}
class Person{
void driveCar(Car c) { c.drive(); }
}
========================================================================
================================ Alternative Way =======================
public Car{
int odometer; // car doesn't do the driving, it's the person, so no drive()
}
public Person{
void driveCar(Car c) { c.odometer++; }
}
========================== and other ways....============================
===========================================================================
So, my question is clear: what is the best way to design/implement/name methods in similar cases?
It's a bit difficult to make simplified examples like that make any sense, but here is an attemt:
A Car class would generally contain methods for the things that the object can do by itself with the information that it has, for example:
public class Car {
private bool engineOn;
public int Speed { get; private set; }
public void Start() { engineOn = true; Speed = 0; }
public void Accelerate() { Speed++; }
public void Break() { if (Speed > 0) Speed--; }
public void Stop() { Speed = 0; engineOn = false; };
}
A Person class would would manage a car by controlling the things that the car itself is not aware of in its environment. Example:
public class Person {
public void Drive(Car car, int speedLimit) {
car.Start();
while (car.Speed < speedLimit) {
car.Accelerate();
}
while (car.Speed > 0) {
car.Break();
}
car.Stop();
}
}
There are of course many different variations of how you can use OO in each situation.
If you wish to express your logic in a way that closely resembles human language semantics, you'll want to invoke an action or function on an entity which is logically capable of carrying it out.
When behavior cannot be placed on an object (in the sense that it has state), you put it in a Service or Utility class, or some similar construct. Authenticate is a classic example of something that doesn't make much sense to invoke on a user, or on any other object. For this purpose, we create an AuthenticationProvider (or service, whichever you prefer).
In your scenario of a Person and a Car, it's one object invoking behavior on another. person.Drive(car) would therefore make the most sense.
If a Person owns a Car (and a Car is always owned by a Person), then person.Drive() might be the only thing you need to do. The Drive() method will have access to the properties of person, one of which is its car.
An important thing to note here is the concept of loose coupling. In more complex scenario's, you don't want to all sorts of cross-references within your model. But by using interfaces and abstractions you'll often find yourself putting methods on objects where they don't really belong from a real-world perspective. The trick is to be aware of, and utilize a language's features for achieving loose coupling and realistic semantics simultaneously.
Keeping in mind that in a real application you'll have the bootstrapping code tucked away elsewhere, here is an example of how that might look like in C#:
We start off by defining interfaces for the things that can transport (ITransporter), and the things that can be transported (ITransportable):
public interface ITransportable
{
void Transport(Transportation offset);
}
public interface ITransporter
{
void StartTransportation(ITransportable transportable);
void StopTransportation(ITransportable transportable);
}
Note the Transportation helper class which contains the information necessary to re-calculate the current location of an ITransportable after it has been transported for a certain period of time with a certain velocity and whatnot. A simple example:
public class Transportation
{
public double Velocity { get; set; }
public TimeSpan Duration { get; set; }
}
We then proceed to create our implementations for these. As you might have guessed, Person will derive from ITransportable and Car derives from ITransporter:
public class Person : ITransportable
{
public Tuple<double, double> Location { get; set; }
private ITransporter _transporter;
void ITransportable.Transport(Transportation offset)
{
// Set new location based on the offset passed in by the car
}
public void Drive<TCar>(TCar car) where TCar : ITransporter
{
car.StartTransportation(this);
_transporter = car;
}
public void StopDriving()
{
if (_transporter != null)
{
_transporter.StopTransportation(this);
}
}
}
Pay close attention to what I did there. I provided an explicit interface implementation on the Person class. What this means is that Transport can only be invoked when the person is actually referenced as an ITransportable - if you reference it as a Person, only the Drive and StopDriving methods are visible.
Now the Car:
public class Car : ITransporter
{
public double MaxVelocity { get; set; }
public double Acceleration { get; set; }
public string FuelType { get; set; }
private Dictionary<ITransportable, DateTime> _transportations = new Dictionary<ITransportable, DateTime>();
void ITransporter.StartTransportation(ITransportable transportable)
{
_transportations.Add(transportable, DateTime.UtcNow);
}
void ITransporter.StopTransportation(ITransportable transportable)
{
if (_transportations.ContainsKey(transportable))
{
DateTime startTime = _transportations[transportable];
TimeSpan duration = DateTime.UtcNow - startTime;
var offset = new Transportation
{
Duration = duration,
Velocity = Math.Max((Acceleration*duration.Seconds), MaxVelocity)/2
};
transportable.Transport(offset);
_transportations.Remove(transportable);
}
}
}
Following the guidelines we set earlier, a Car will not have any (visible) methods on it, either. Unless you explicitly reference it as an ITransporter, which is exactly what happens inside of the Person's Drive and StopDriving methods.
So a Car here is just a Car. It has some properties, just like a real car, based on which you can determine a location offset after a person drove it for a certain amount of time. A Car cannot "Drive", "Start", or anything like that. A Person does that to a Car - a Car does not do that to itself.
To make it more realistic you would have to add all sorts of additional metadata that affect a Car's average velocity over a certain period of time on a certain route. Truth is, you probably won't end up modeling something like this anyway. I stuck with your model just to illustrate how you could retain natural language semantics if you were working with objects that make it challenging to do so.
An example of how these classes may be used by a client:
Person person = new Person();
Car car = new Car();
// car.Transport(); will not compile unless we explicitly
// cast it to an ITransporter first.
// The only thing we can do to set things in motion (no pun intended)
// is invoke person.Drive(car);
person.Drive(car);
// some time passes..
person.StopDriving();
// currentLocation should now be updated because the Car
// passed a Transportation object to the Person with information
// about how quickly it moved and for how long.
var currentLocation = person.Location;
As I already eluded before, this is by no means a good implementation of this particular scenario. It should, however, illustrate the concept of how to solve your problem: to keep the logic of "transportation" inside of the "transporter", without the need to expose that logic through public methods. This gives you natural language semantics in your client code while retaining proper separation of concerns.
Sometimes you just need to be creative with the tools you have.
In second case, it's like you're saying that the task of driving a car consist in incrementing the odometer. It's clearly not the driver's business, and a violation of encapsulation. The odometer should probably be an implementation detail.
In first case, the car maybe does not drive itself, but it advances, so you could use another verb. But car.advance() is maybe not how a Person drives cars... Even if it was thru vocal commands, the decoding of the command would probably result in a sequence of more basic commands.
I very much like the answer of Guffa which tries to address what driving a car could mean. But of course, you may have another context...

Object oriented design principle Abstraction

While reading about abstraction, I came across the following statement
"Abstraction captures only those details about an object that are relevant to the current perspective"
For eg.
From the driver's perspective, Car class would be
public class Car
{
void start();
void applybrakes();
void changegear();
void stop();
}
From the mechanic's perspective, Car class would be
public class Car
{
void changeOil();
void adjustBrakes();
}
My question,
While designing a system, do we design for one user perspective(either driver or mechanic) or can
we design for multiple user perspective and further abstract out based on user type?
Hope my question is clear.
Thanks
Depending on your use case you might need to deign for multiple users. In your example, if your car will be used by both the mechanic and the driver, then you cannot just ignore one set of users. In that case, you can still abstract details by using Interfaces.
You could design your object like this:
interface IDrivable {
void start();
void applyBrakes();
void changeGear();
void stop();
}
interface IFixable {
void changeOil();
void adjustBrakes();
}
public class Car : IDrivable, IFixable {
// implement all the methods here
}
Now, when a mechanic wants the car, you don't give him a Car object, instead give him an IFixable object. Similarly, the driver gets an IDrivable object. This keeps the relevant abstraction for both sets of users simultaneously.
class Driver {
private IDrivable car;
public Driver(IDrivable car) {
this.car = car;
}
public driveCar() {
this.car.start();
this.car.accelerate();
//this is invalid because a driver should not be able to do this
this.car.changeOil();
}
}
Similary, a mechanic won't have access to the methods in the interface IDrivable.
You can read more about interfaces here. Even though this is the MSDN link and uses C#, all major languages support interfaces.
I think you may be inferring too much from "perspective." I wouldn't take perspective here to mean a person or user so much as a vantage point. The idea of a view here is maybe not even a good metaphor. What we're really talking about here is division of responsibility between the smaller objects that we use to compose the larger objects.
The whole point of this idea is decoupling and modularity. You want objects that you can pull out and replace without changing everything around them. So you want your objects to be coherent, for their methods and variables to be closely related.
You might be able to get some mileage from the user metaphor in terms of the interface-client relationship between objects.

Object Oriented Design for a Chess game [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am trying to get a feel of how to design and think in an Object Oriented manner and want to get some feedback from the community on this topic. The following is an example of a chess game that I wish to design in an OO manner. This is a very broad design and my focus at this stage is just to identify who is responsible for what messages and how the objects interact each other to simulate the game. Please point out if there are elements of bad design (high coupling, bad cohesion etc.) and how to improve on them.
The Chess game has the following classes
Board
Player
Piece
Square
ChessGame
The Board is made up of squares and so Board can be made responsible for creating and managing Square objects. Each piece also is on a square so each piece also has a reference to the square it is on. (Does this make sense?). Each piece then is responsible to move itself from one square to another.
Player class holds references to all pieces he owns and is also responsible for their creation (Should player create Pieces?) . Player has a method takeTurn which in turn calls a method movePiece which belongs to the piece Class which changes the location of the piece from its current location to another location. Now I am confused on what exactly the Board class must be responsible for. I assumed it was needed to determine the current state of the game and know when the game is over. But when a piece changes it's location how should the board get updated? should it maintain a seperate array of squares on which pieces exist and that gets updates as pieces move?
Also, ChessGame intially creates the Board and player objects who in turn create squares and pieces respectively and start the simulation. Briefly, this might be what the code in ChessGame may look like
Player p1 =new Player();
Player p2 = new Player();
Board b = new Board();
while(b.isGameOver())
{
p1.takeTurn(); // calls movePiece on the Piece object
p2.takeTurn();
}
I am unclear on how the state of the board will get updated. Should piece have a reference to board? Where should be the responsibility lie? Who holds what references? Please help me with your inputs and point out problems in this design. I am deliberately not focusing on any algorithms or further details of game play as I am only interested in the design aspect. I hope this community can provide valuable insights.
I actually just wrote a full C# implementation of a chess board, pieces, rules, etc. Here's roughly how I modeled it (actual implementation removed since I don't want to take all the fun out of your coding):
public enum PieceType {
None, Pawn, Knight, Bishop, Rook, Queen, King
}
public enum PieceColor {
White, Black
}
public struct Piece {
public PieceType Type { get; set; }
public PieceColor Color { get; set; }
}
public struct Square {
public int X { get; set; }
public int Y { get; set; }
public static implicit operator Square(string str) {
// Parses strings like "a1" so you can write "a1" in code instead
// of new Square(0, 0)
}
}
public class Board {
private Piece[,] board;
public Piece this[Square square] { get; set; }
public Board Clone() { ... }
}
public class Move {
public Square From { get; }
public Square To { get; }
public Piece PieceMoved { get; }
public Piece PieceCaptured { get; }
public PieceType Promotion { get; }
public string AlgebraicNotation { get; }
}
public class Game {
public Board Board { get; }
public IList<Move> Movelist { get; }
public PieceType Turn { get; set; }
public Square? DoublePawnPush { get; set; } // Used for tracking valid en passant captures
public int Halfmoves { get; set; }
public bool CanWhiteCastleA { get; set; }
public bool CanWhiteCastleH { get; set; }
public bool CanBlackCastleA { get; set; }
public bool CanBlackCastleH { get; set; }
}
public interface IGameRules {
// ....
}
The basic idea is that Game/Board/etc simply store the state of the game. You can manipulate them to e.g. set up a position, if that's what you want. I have a class that implements my IGameRules interface that is responsible for:
Determining what moves are valid, including castling and en passant.
Determining if a specific move is valid.
Determining when players are in check/checkmate/stalemate.
Executing moves.
Separating the rules from the game/board classes also means you can implement variants relatively easily. All methods of the rules interface take a Game object which they can inspect to determine which moves are valid.
Note that I do not store player information on Game. I have a separate class Table that is responsible for storing game metadata such as who was playing, when the game took place, etc.
EDIT: Note that the purpose of this answer isn't really to give you template code you can fill out -- my code actually has a bit more information stored on each item, more methods, etc. The purpose is to guide you towards the goal you're trying to achieve.
Here is my idea, for a fairly basic chess game :
class GameBoard {
IPiece config[8][8];
init {
createAndPlacePieces("Black");
createAndPlacePieces("White");
setTurn("Black");
}
createAndPlacePieces(color) {
//generate pieces using a factory method
//for e.g. config[1][0] = PieceFactory("Pawn",color);
}
setTurn(color) {
turn = color;
}
move(fromPt,toPt) {
if(getPcAt(fromPt).color == turn) {
toPtHasOppositeColorPiece = getPcAt(toPt) != null && getPcAt(toPt).color != turn;
possiblePath = getPcAt(fromPt).generatePossiblePath(fromPt,toPt,toPtHasOppositeColorPiece);
if(possiblePath != NULL) {
traversePath();
changeTurn();
}
}
}
}
Interface IPiece {
function generatePossiblePath(fromPt,toPt,toPtHasEnemy);
}
class PawnPiece implements IPiece{
function generatePossiblePath(fromPt,toPt,toPtHasEnemy) {
return an array of points if such a path is possible
else return null;
}
}
class ElephantPiece implements IPiece {....}
I recently created a chess program in PHP (website click here, source click here) and I made it object oriented. Here are the classes I used.
ChessRulebook (static) - I put all my generate_legal_moves() code in here. That method is given a board, whose turn it is, and some variables to set the level of detail of the output, and it generates all the legal moves for that position. It returns a list of ChessMoves.
ChessMove - Stores everything needed to create algebraic notation, including starting square, ending square, color, piece type, capture, check, checkmate, promotion piece type, and en passant. Optional additional variables include disambiguation (for moves like Rae4), castling, and board.
ChessBoard - Stores the same information as a Chess FEN, including an 8x8 array representing the squares and storing the ChessPieces, whose turn it is, en passant target square, castling rights, halfmove clock, and fullmove clock.
ChessPiece - Stores piece type, color, square, and piece value (for example, pawn = 1, knight = 3, rook = 5, etc.)
ChessSquare - Stores the rank and file, as ints.
I am currently trying to turn this code into a chess A.I., so it needs to be FAST. I've optimized the generate_legal_moves() function from 1500ms to 8ms, and am still working on it. Lessons I learned from that are...
Do not store an entire ChessBoard in every ChessMove by default. Only store the board in the move when needed.
Use primitive types such as int when possible. That is why ChessSquare stores rank and file as int, rather than also storing an alphanumeric string with human readable chess square notation such as "a4".
The program creates tens of thousands of ChessSquares when searching the move tree. I will probably refactor the program to not use ChessSquares, which should give a speed boost.
Do not calculate any unnecessary variables in your classes. Originally, calculating the FEN in each of my ChessBoards was really killing the program's speed. I had to find this out with a profiler.
I know this is old, but hopefully it helps somebody. Good luck!

Advise on object-oriented design

I would like some help with a OOD query.
Say I have the following Customer class:
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
It's a simple placeholder for customer related data. Next comes the CustomerFactory, which is used to fetch customers:
public static class CustomerFactory
{
public static Customer GetCustomer(int id)
{
return null; // Pretend this goes off to get a customer.
}
}
Now, if I wanted to write a routine named UpdateCustomer(Customer customer) can someone suggest where I could place this method?
Obviously I don't want to use the Customer class since that would be against SRP (Single Responsibility Principle), also I don't see it as a good idea to attach the method to the CustomerFactory class, since it's only role is to get customers from the database.
So it looks like I'm going to need another class, but I don't know what to name it.
Cheers.
Jas.
What you have called a Factory isn't a Factory at all. It's a Repository.
A Factory handles the instansiation of various classes sharing a common Interface or Class Hierarchy based on some set of parameters.
A Repository handles the retrieval and management of data.
The Repository would definitely have the UpdateCustomer(Customer customer) method in it as well as the GetCustomer(int id) method.
You are more on less on your way to creating a Repository. Do something like this:
public interface ICustomerRepository
{
Customer SelectCustomer(int id);
void UpdateCustomer(Customer customer);
void DeleteCustomer(int id);
void CreateCustomer(Customer customer);
}
Then create concrete implementations of this interface (the interface is really just because it's good practice to program against interfaces - you could skip it, though, although I would recommend that you keep it).
Wouldn't your UpdateCustomer routine be placed in your DAL (Data Access Layer). You should define a class to handle inserts or updates to the database and then pass a customer object to it.
You could write the DAL class to handle all of this but I don't see any issue in storing it in your CustomerFactory class, although as mentioned it is not really a factory.