I am trying to use OOP to model the relationship between classes where either can be OF the other.
For example: In a hierarchical business, you might have the Corporation -> Has -> Businesses -> Has -> Departments
Simple enough. But, what if the a different business acquires this corporation. Then the corporation will be part of the business rather then the reverse.
You can always use an interface or the most common properties for the base class. For example:
public abstract class BusinessUnit {
protected ArrayList<BusinessUnit> businessUnits;
}
And in the classes:
public class Corporation extends BusinessUnit { }
public class Business extends BusinessUnit { }
Of course you'll have to handle it differently inside the classes according to the BusinessUnit type.
Related
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.
After searching different forums related to tight coupling (when a group of classes are highly dependent on one another)
Example1
class CustomerRepository
{
private readonly Database database;
public CustomerRepository(Database database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
class Database
{
public void AddRow(string Table, string Value)
{
}
}
Above class CustomerRepository is dependent on Database class so they are tightly coupled .and i think this class is also an example of Compostion ,then i searched for loose coupling so changing the above class so that tight coupling dependency is removed.
Example2
class CustomerRepository
{
private readonly IDatabase database;
public CustomerRepository(IDatabase database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
interface IDatabase
{
void AddRow(string Table, string Value);
}
class Database : IDatabase
{
public void AddRow(string Table, string Value)
{
}
}
I have searched that composition support loose coupling now my question is how example1 is tightly coupled as it were based on composition? secondly what is the relation between loose coupling and composition?
Any help will be greatly appreciated.
What you have there is not really tight coupling. Tight coupling would be this:
class CustomerRepository {
private readonly Database database;
public CustomerRepository() {
this.database = new Database;
}
}
The class has a hardcoded dependency on a specific Database class which cannot be substituted. That's really tight coupling.
The composition example you're showing is already loosely coupled, since it's entirely possible to substitute the dependency being injected into the constructor by any other Database inheriting class.
Your second example is even more loosely coupled, since it uses an interface instead of a concrete class; but that's something of a minor detail.
#deceze's explains most of your questions. I am just adding my 2 cents to his answer.
Both examples are loosely coupled but to different degrees.
Example -1 You are allowed to inject object of concrete type via its constructor.
Example -2 You are allowed to inject an objecto of abstract type via its constructor.
What makes the example 2 more loosly coupled is the due to Dependency Inversion Principle. It's main idea is - one should “Depend upon Abstractions. Do not depend upon concretions.”
Second example depends on interface and not on a Concrete class like the first one. Now comes the confusion -why interface is special why not a class both of them do the same thing?
Lets assume tomorrow if you want to delete Database Class and replace it with new class FlatFile, you need to change CustomerRepository class in the first example but not the second. In the second example the person who will create an instance of CustomerRepository only should worry replacing Database class with FlatFile Class. This is the meaning of loose copling changing Database class should not force you to change CustomerRepository class.
To answer your last question
what is the relation between loose coupling and composition?
There is no direct relation, you can still use composition and mess up the coupling between class by not implementing the Dependency inversion principle. So the right question you should ask is -
How to make a tightly coupled code to loosely coupled?
Follow Dependency inversion principle.
This is an OOD based interview question:
There is a Furniture class and has derived classes like WoodChair, WoodTable, SteelChair, SteelTable. Interviewer wanted to add more number of classes like ironchair,irontable etc; How should we do that. The design is not yet published and we are free to modify the entire sutff given.
I thought that since we're basically building types of furniture we should use a builder pattern here with Furniture class with properties like type (chair/table) and make(iron/wood) etc. Then we'd have an interface Builder with functions like: buildLegs(..), buildSurface(..) and sub-classes like ChairBuilder, TableBuilder and a Director class to instantiate all of them. We could add as many new types of Furniture of any make and construct a builder class for them without affecting existing design.
After reading Builder Vs Decorator pattern I was sure that I'm not supposed to use Decorator pattern here. But is Builder also ok? Is it an overkill?
Also, I'm not sure how to deal with the make of the furniture. Would adding a feature of type enum for the make be enough? [steel, iron, wood] The make doesn't really add any new behavior to the furniture items.
It looks like something needs to be refactored in the existing classes, which may also help avoiding creating a new class for every one of the need that arise in the future. This depends entirely on the context though: an inventory application needs a radically different model of a chair than a software that needs to display a chair in 3d. How do you know? Ask the interviewer, then you will know where they want you to go.
Boring case: a Chair has some common behavior/data that can be refactored out in a different class, same thing for Table. Now how do you choose to represent the material? Again, it depends on the domain, ask the interviewer. It is also a matter of the language you are using: does your language of choice support multiple inheritance? Do you need (or want) to use multiple inheritance at all? It may make sense to favor composition over inheritance. Why would you go one way or the other? Do you even need a class to represent this piece of information?
How should we do that.
Ask the interviewer, they will guide you to the solution. There is no single correct answer to a problem so broadly formulated, they want you to ask questions and see how you think. That said, as broad as the question is, the way it is formulated may be a hint that you should refactor something in order to avoid having to create a class for every new combination of furniture and material.
Possible solutions:
No need for Table/Chair/Bed to inherit from Furniture: a class Furniture with a property for the piece of furniture and a property for the material.
Classes for Table, Chair, Bed, whatever with a property for the material. The complexity of how the material is represented depends on how this information have to be modeled: it could be a string, or a Class (Wood, Iron, Steel) implementing an IMaterial interface.
Probably, i was use Abstract Factory: WoodFurntiture, SteelFurniture, IronFurniture.
Each Factory know How to make chair, table.
Inside you can use (if you need) other DP, but for a now, i do not see any needs for it
Code:
namespace Furniture
{
class Program
{
static void Main(string[] args)
{
IFurnitureFactory factory = new WoodFurnitureFactory();
IFurniture chair = factory.GetChair();
}
}
public interface IFurniture { }
public class WoodChair : IFurniture { }
public class WoodTable : IFurniture { }
public class SteelChair : IFurniture { }
public class SteelTable : IFurniture { }
public class IronChair : IFurniture { }
public class IronTable : IFurniture { }
public interface IFurnitureFactory
{
IFurniture GetChair();
IFurniture GetTable();
}
public class WoodFurnitureFactory : IFurnitureFactory
{
public IFurniture GetChair()
{
return new WoodChair();
}
public IFurniture GetTable()
{
return new WoodTable();
}
}
public class IronFurnitureFactory : IFurnitureFactory
{
public IFurniture GetChair()
{
return new IronChair();
}
public IFurniture GetTable()
{
return new IronTable();
}
}
public class SteeFurniturelFactory : IFurnitureFactory
{
public IFurniture GetChair()
{
return new SteelChair();
}
public IFurniture GetTable()
{
return new SteelTable();
}
}
}
Let's say you need to build an application that manages cheques. Each cheque contains data about the amount of money, the date, the payee and an additional payment date which may or may not be present. Additionally, each cheque must be related to a current account which belongs to a certain bank.
Now, our application should allow cheques printing under these conditions:
Each bank managed by the app has a different cheque layout (i.e. each field has a different x,y position).
The cheque layout changes slightly if the payment date is present, even with the same related bank object. But, from bank to bank these changes may not be the same (e.g. bank A may vary position for the date field, while bank B changes position for the payee field)
With these restrictions in place, it's difficult to come up with a simple inheritance schema as there is no consistent behavior to factor out accross the different types of cheques there are. One possible solution would be to avoid inheritance and create a class for every cheque - bank combination:
class ChequeNoPaymentDateForBankA
class ChequeWithPaymentDateForBankA
class ChequeNoPaymentDateForBankB
class ChequeWithPaymentDateForBankB, etc.
Each of these classes implement the print() method which takes the fields positions from a Bank object and builds up the cheque layout. So far so good, but this approach leaves me with a strange feeling as there is no room for code reuse. I wonder if I'm misinterpreting the problem and perhaps there is a better way. As this is not a new problem domain at all, I'm sure this is a reinvent-the-wheel effort. Any insights will be kindly appreciated.
Usually in these situations I move from inheritance to delegation. That is, instead of putting the common code in a superclass (which, as you say, is problematic becuase there are two dimensions), I put the common in a field (one field per dimension) and delegate to that field.
Assuming you're speaking about Java:
public interface Bank {
public void print();
}
public class BankA implements Bank {
public void print() { ... }
}
public class BankB implements Bank {
public void print() { ... }
}
public interface PaymentSchedule {
public void print();
}
public class WithPaymentDate implements PaymentSchedule {
public void print() { ... }
}
public class NoPaymentDate implements PaymentSchedule {
public void print() { ... }
}
public class Cheque {
private final Bank bank;
private final PaymentSchedule schedule;
public Cheque(Bank b, PaymentSchedule s) {
bank = b;
schedule = s;
}
public void print() {
bank.print();
schedule.print();
}
}
That's the general structure of the solution.
Depending on the exact details of your print() algorithm you may need to pass some more data into the print methods and/or to pass this data into the constructors of the classes (of the Bank or PaymentSchedule subclasses) and store it in fields.
I would start by separating the domain model (cheques, banks, etc) from the view (the way the cheques are printed). This is the basic idea behind the MVC pattern and one of its aims is to allow the same domain model to be displayed in different ways (which seems to be your case). So, I would first create the domain classes, something like:
class Cheque
{
protected $bank;
protected $money;
...
}
class Bank {...}
Note that these classes are the "M" of the MVC triad and implement the logic of your domain model, not the behavior related to the rendering process. The next step would be to implement the View classes used to render a cheque. Which approach to take heavily depends on how complex your rendering is, but I would start by having a ChequeView class that renders the common parts and that delegates to other sub-view the specific parts that can change (in this case the date):
abstract class ChequeView
{
protected $cheque;
protected $dateView;
public function __construct($cheque)
{
$this->cheque = $cheque;
$this->dateView = //Whatever process you use to decide if the payment date is shown or not
}
public function render()
{
$this->coreRender();
$this->dateView->render();
}
abstract protected function coreRender();
}
class BankACheckView extends ChequeView
{
protected function coreRender() {...}
}
class BankBCheckView extends ChequeView
{
protected function coreRender() {...}
}
abstract class DateView
{
abstract function render()
}
class ShowDateView extends DateView
{
function render() {...}
}
class NullDateView extends DateView
{
function render() {...}
}
And, if there is code to reuse across subclasses, you can of course factor them in ChequeView and make coreRender() call them.
In case your rendering turns to be too complex, this design may not scale. In that case I would go for splitting your view in meaningful subparts (e.g. HeaderView, AmountView, etc) so that rendering a cheque becomes basically rendering its different sub-parts. In this case the ChequeView may end basically working as a Composite. Finally, if you reach this case and setting up the ChequeView turns out to be a complex task you may want to use a Builder.
Edit based on the OP comments
The Builder is mostly used when the instantiation of the final object is a complex process (e.g. there are many things to sync between the sub-parts in order to get a consistent whole). There is generally one builder class and different clients, that send messages (potentially in different orders and with different arguments) to create a variety of final objects. So, while not prohibited, it is not usual to have one builder per type of object that you want to build.
If you are looking for a class that represents the creation of a particular instance you may want to check the Factory family of patterns (maybe the Abstract Factory resembles closely to what you had in mind).
HTH
I'm reading some books about Design Patterns and while some describe the relation between the abstraction and the implementation as a composition, some describe it as an aggregation. Now I wonder: is this dependant on the implementation? On the language? Or context?
The terms "composition" and "aggregation" mean more or less the same thing and may be used interchangeably. Aggregation may be used more frequently when describing container classes such as lists, dynamic arrays, maps, and queues where the elements are all of the same type; however, both terms may be found to describe classes defined in terms of other classes, regardless of whether those types are homogenous (all of the same type) or heterogenous (objects of different types).
To make this clearer:
class Car {
// ...
private:
Engine engine;
Hood hood;
};
// The car is *composed* of an engine and a hood. Hence, composition. You are
// also bringing together (i.e. *aggregating*) an engine and hood into a car.
The relationship between abstraction and implementation typically implies inheritance, rather than composition/aggregation; typically the abstraction is an interface or virtual base class, and the implementation is a fully concrete class that implements the given interface. But, to make things confusing, composition/aggregation can be a part of the interface (because, for example, you may need to set/get the objects that are used as building blocks), and they are also an approach to implementation (because you might use delegation to provide the definition for methods in your implementation).
To make this clearer:
interface Car {
public Engine getEngine();
public Hood getHood();
public void drive();
}
// In the above, the fact that a car has these building blocks
// is a part of its interface (the abstraction).
class HondaCivic2010 implements Car {
public void drive(){ getEngine().drive(); }
// ...
}
// In the above, composition/delegation is an implementation
// strategy for providing the drive functionality.
Since you have tagged your question "bridge", I should point out that the definition of the bridge pattern is a pattern where you use composition rather than inheritance to allow for variation at multiple different levels. An example that I learned at college... using inheritance you might have something like:
class GoodCharacter;
class BadCharacter;
class Mage;
class Rogue;
class GoodMage : public GoodCharacter, Mage;
class BadMage : public BadCharacter, Mage;
class GoodRogue : public GoodCharacter, Rogue;
class BadRogue : public BadCharacter, Rogue;
As you can see, this kind of thing goes pretty crazy, and you get a ridiculous number of classes. The same thing, with the bridge pattern, would look like:
class Personality;
class GoodPersonality : public Personality;
class BadPersonality : public Personality;
class CharacterClass;
class Mage : public CharacterClass;
class Rogue : public CharacterClass;
class Character {
public:
// ...
private:
CharacterClass character_class;
Personality personality;
};
// A character has both a character class and a personality.
// This is a perfect example of the bridge pattern, and we've
// reduced MxN classes into a mere M+N classes, and we've
// arguably made the system even more flexible than before.
the bridge pattern must use delegation (aggregation/composition and not inheritance). from the gang-of-four book:
Use the Bridge pattern when
* you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time.
* both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently.
* changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled.
* (C++) you want to hide the implementation of an abstraction completely from clients. In C++ the representation of a class is visible in the class interface.
* you have a proliferation of classes as shown earlier in the first Motivation diagram. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" [RBP+91] to refer to such class hierarchies.
* you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class [Cop92], in which multiple objects can share the same string representation (StringRep).
Standard UML of Bridge pattern clears out all air around the confusion. Below is an explanation with a brief example to clear the air around this.
Apologies for this lengthy code, best way is to copy this code to Visual Studio to easily understand it.
Read through the explanation written at the end of code
interface ISpeak
{
void Speak();
}
class DogSpeak : ISpeak
{
public void Speak()
{
Console.WriteLine("Dog Barks");
}
}
class CatSpeak : ISpeak
{
public void Speak()
{
Console.WriteLine("Cat Meows");
}
}
abstract class AnimalBridge
{
protected ISpeak Speech;
protected AnimalBridge(ISpeak speech)
{
this.Speech = speech;
}
public abstract void Speak();
}
class Dog : AnimalBridge
{
public Dog(ISpeak dogSpeak)
: base(dogSpeak)
{
}
public override void Speak()
{
Speech.Speak();
}
}
class Cat : AnimalBridge
{
public Cat(ISpeak catSpeak)
: base(catSpeak)
{
}
public override void Speak()
{
Speech.Speak();
}
}
-- ISpeak is the abstraction that bot Dog and Cat has to implement
-- Decoupled Dog and Cat classes by introducing a bridge "Animal" that is composed of ISpeak
-- Dog and Cat classes extend Animal class and thus are decoupled from ISpeak.
Hope this clarifies