Skip to content

Repository files navigation

OSBCodingDojo

Monthly Coding Dojo for skill development and/or improvement

OCP (Open Closed Principle)

  • OPEN for Extension
  • CLOSED for Modification

Patterns

Fluent Interfaces

With methods returning this you can combine one method after another like:

bmwService.withMechanicalMaintenance().withSafetyTest().getCost()

Decorator Pattern

Base object is extended by decorator objects.

All classes (base and decorators) implement the same interface. Decorator class constructors take the common interface as an input argument. After the base object is constructed it can be decorated by constructing decorator objects with the before created base object.

Example:

Imagine an interface called IPizza with a method getCost().

interfaceIPizza{doublegetCost();}

This interface is implemented by a base class called PizzaBase.

classPizzaBase:IPizza{privatedoublecost;publicPizzaBase(){this.cost=4.5;//price for pizza without extra toppings}publicdoublegetcost(){returncost;}}

The decorator classes also implement the interface.

classPizzaToppingCheese:IPizza{privateIPizzapizza;privatedoublecost;publicPizzaToppingCheese(IPizzaaPizza){this.pizza=aPizza;this.cost=0.8;}publicdoublegetCost(){returnthis.pizza.getCost()+this.cost;}}classPizzaToppingMushrooms:IPizza{privateIPizzapizza;privatedoublecost;publicPizzaToppingMushrooms(IPizzaaPizza){this.pizza=aPizza;this.cost=1.0;}publicdoublegetCost(){returnthis.pizza.getCost()+this.cost;}}

To use the decorator pattern, the base object (or its cosntructor) is passed to the constructor of a decorator object which itself can be passed to another decorator object constructor. See the code snippet below:

staticvoidMain(string[]args){Console.WriteLine(newPizzaToppingMushrooms(newPizzaToppingCheese(newPizzaBase())).getCost());}

This outputs the cost for a Pizza + Cheese + Mushrooms.

6.3

Adapter Pattern

Imagine a class Caller that contains an object of class ClassA with the interface IClassA. Now you've got an object of class ClassB that generally serves the same purpose as ClassA but implements different methods to achieve that functionality. To use ClassB within Caller you need to create an adapter class AdapterA2B that implements the interface IClassA and adaptsClassB's methods to them of ClassA.

The mentioned classes could look like follows:

publicinterfaceIClassA{voiddoAFoo();}
publicclassClassA:IClassA{publicvoiddoAFoo(){Console.WriteLine("doing Foo the A way...");}}
publicclassClassB{publicvoiddoBFoo(){Console.WriteLine("doing Foo the B way...");}}
publicclassCaller{privateIClassAfooClass
public Caller(IClassAfooClass){this.fooClass=fooClass;}publicvoiddoFoo(){fooClass.doFoo();}}
publicclassAdapterA2B:IClassA{privateClassBclass2Adapt
public AdapterA2B(ClassBclass2Adapt){this.class2Adapt=class2Adapt;}publicvoiddoAFoo(){class2Adapt.doBFoo();}}

Using Caller with both classes ClassA and ClassB could look like that:

staticvoidMain(string[]args){Callercaller1=newCaller(newClassA());Callercaller2=newCaller(newAdapterA2B(newClassB()));caller1.doFoo();caller2.doFoo();}

... and produce the following output:

doing Foo the A way...
doing Foo the B way...

Facade Pattern

About

Monthly Coding Dojo for skill development and/or improvement

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages