Professional Documents
Culture Documents
Cap 7 - DesignPatterns - PrincipiiDeBaza
Cap 7 - DesignPatterns - PrincipiiDeBaza
Benefits:
A consumer/client can use the interface without even knowing about the concrete
implementations.
class Program
{
static void Main()
{
//This is your client code.
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}
}
1.1 Program to an interface not an implementation
Exemplul 2
Let suppose we need to add a feature to all Speakers to "Say Hello“. All speakers speak
"Hello World“, except SpanishSpeaker which cannot Say Hello.
An abstract Speaker base class has been added. The Speaker abstract class implements
ISpeaker interface and marks the Speak() as abstract which means that each Speaker
implementation is responsible for implementing the Speak method since it varies from
Speaker to Speaker. But all speakers say "Hello" unanimously. So in the abstract
Speaker class we define a method that says "Hello World" and each Speaker
implementation will derive the SayHello method. The SayHello method for Spanish
Speaker is overriden.
Please note that, we have not made any changes to Interface ISpeaker. And the
client code and SpeakerFactory also remain unchanged. And this is what we achieve
by Programming to an Interface not an implementation.
1.1 Program to an interface not an implementation
Exemplul 2
public enum Language
{ class Program
English, German, Spanish {
} static void Main()
{ //This is your client code.
public class SpeakerFactory ISpeaker speaker = SpeakerFactory.
{ CreateSpeaker(Language.English);
public static Ispeaker CreateSpeaker ( speaker.Speak();
Language language) Console.ReadLine();
{ }
switch (language) }
{
case Language.English: public interface ISpeaker
return new EnglishSpeaker(); {
case Language.German: void Speak();
return new GermanSpeaker(); }
case Language.Spanish:
return new SpanishSpeaker();
default:
throw new
ApplicationException("No speaker can
speak such language");
}
}}
1.1 Program to an interface, not an implementation
Exemplul 2
public abstract class Speaker : Ispeaker public class GermanSpeaker : Speaker
{ {
public abstract void Speak(); public GermanSpeaker() { }
public virtual void SayHello() public override void Speak()
{ {
Console.WriteLine("Hello world."); Console.WriteLine("I speak German.");
} this.SayHello();
} }
}
Note!
An implementation of composition over inheritance typically begins with the creation of
various interfaces representing the behaviors that the system must exhibit. The use of
interfaces allows this technique to support the polymorphic behavior that is so valuable
in object-oriented programming.
1.3 Favor composition over inheritance.
Comparasion
Benefits of composition
Loosely coupled- any change to Fruit class does not affect to Apple class. Similarly
also adding any method with same signature as Fruit class does not make any affect,
and the code will compile perfectly.
Stronger Encapsulation- in composition if we change the return type of peel() in
Fruit class, there is no need to change anything in Apple class. Without changing
anything also the code will compile perfectly and run as well.
A challenging issue: what if one DataSet class wants to use one sorting algorithm (say,
MergeSort) and another data set class wants to use a different sorting algorithm (say,
QuickSort)? Will you inherit from two classes implementing two different sorting
algorithms? NO!
1.3 Favor composition over inheritance.
Examplu
In this case it is best to use composition - in other words, use a HAS-A relationship
instead of an IS-A relationship.
//Sorting.java class DynamicDataSet {
import java.awt.List; Sorting sorting;
interface Sorting { public DynamicDataSet() {
List sort(List list); sorting = new MergeSort();
} }
class MergeSort implements Sorting { // DynamicDataSet implementation
public List sort(List list) { }
// sort implementation class SnapshotDataSet {
return list; Sorting sorting;
} public SnapshotDataSet() {
} sorting = new QuickSort();
class QuickSort implements Sorting { }
public List sort(List list) { // SnapshotDataSet implementation
// sort implementation }
return list;
}
}
Each pattern describes a problem that occurs over and over again in our
environment, and then describes the core of the solution to that problem,
in such a way that you can use the solution a million times over, without
ever doing it the same way twice.- GoF (Gang of Four) - Design Patterns: Elements of
Reusable Object-Oriented Software by Gamma, Helm, Johnson, and Vlissides, 1994)
Avantajele aplicării:
comune
Numele şablonului
aplicare
instantierii/crearii de obiecte
dintre clase