The principle states: software should be open for extension, but closed for modification.
- They are "Open For Extension". This means that the behavior of the module can be extended. That we can make the module behave in new and different ways as the requirements of the application change, or to meet the needs of new applications.
- They are "Closed for Modification". The source code of such a module is inviolate. No one is allowed to make source code changes to it.
Class: WeatherDisplay
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | namespace OCP.a.problem { public class WeatherDisplay { private readonly DisplayTemperature _DisplayTemperature; private readonly DisplayWindSpeed _DisplayWindSpeed; public WeatherDisplay(int temperature, int windSpeed) { _DisplayTemperature = new DisplayTemperature(temperature); _DisplayWindSpeed = new DisplayWindSpeed(windSpeed); } public void DisplayWeather() { Console.WriteLine(_DisplayTemperature.Temperature()); Console.WriteLine(_DisplayWindSpeed.WindSpeed()); } } } |
Class: DisplayTemperature
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace OCP.a.problem { public class DisplayTemperature { private readonly int _Temperature; public DisplayTemperature(int temperature) { _Temperature = temperature; } public string Temperature() { return("The current temperature is: " + _Temperature + " degrees celcius."); } } } |
Class: DisplayWindSpeed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace OCP.a.problem { public class DisplayWindSpeed { private readonly int _WindSpeed; public DisplayWindSpeed(int windSpeed) { _WindSpeed = windSpeed; } public string WindSpeed() { return("The current wind speed is: " + _WindSpeed + " meters per second."); } } } |
Below you can see a solution that would obey the Open Closed Principle using the Strategy Pattern:
Interface: IDisplayTemperature
1 2 3 4 5 6 7 | namespace OCP.b.solution { public interface IDisplayTemperature { string Temperature(); } } |
Interface: IDisplayWindSpeed
1 2 3 4 5 6 7 | namespace OCP.b.solution { public interface IDisplayWindSpeed { string WindSpeed(); } } |
Class: WeatherDisplay
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | namespace OCP.b.solution { public class WeatherDisplay { private readonly IDisplayTemperature _DisplayTemperature; private readonly IDisplayWindSpeed _DisplayWindSpeed; public WeatherDisplay(int temperature, int windSpeed) { _DisplayTemperature = new DisplayTemperature(temperature); _DisplayWindSpeed = new DisplayWindSpeed(windSpeed); } public void DisplayWeather() { Console.WriteLine(_DisplayTemperature.Temperature()); Console.WriteLine(_DisplayWindSpeed.WindSpeed()); } } } |
Class: DisplayTemperature : IDisplayTemperature
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace OCP.b.solution { public class DisplayTemperature : IDisplayTemperature { private readonly int _Temperature; public DisplayTemperature(int temperature) { _Temperature = temperature; } public string Temperature() { return("The current temperature is: " + _Temperature + " degrees celcius."); } } } |
Class: DisplayWindSpeed : IDisplayWindSpeed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace OCP.b.solution { public class DisplayWindSpeed : IDisplayWindSpeed { private readonly int _WindSpeed; public DisplayWindSpeed(int windSpeed) { _WindSpeed = windSpeed; } public string WindSpeed() { return("The current wind speed is: " + _WindSpeed + " meters per second."); } } } |
Class: DisplayTemperatureInCelcius : IDisplayTemperature
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace OCP.b.solution { public class DisplayTemperatureInCelcius : IDisplayTemperature { private readonly int _Temperature; public DisplayTemperatureInCelcius(int temperature) { _Temperature = temperature; } public string Temperature() { return("The current temperature is: " + _Temperature + " degrees celcius."); } } } |
Class: DisplayTemperatureInFahrenheit : IDisplayTemperature
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | namespace OCP.b.solution { public class DisplayTemperatureInFahrenheit : IDisplayTemperature { private readonly int _Temperature; public DisplayTemperatureInFahrenheit(int temperature) { _Temperature = temperature; } public string Temperature() { double fahrenheit = (212 - 32) / 100 * _Temperature + 32; return ("The current temperature is: " + fahrenheit + " degrees fahrenheit."); } } } |
Interface: ITextDisplay
1 2 3 4 5 6 7 | namespace OCP.c.final.solution { public interface ITextDisplay { void Show(TextWriter writer); } } |
Class: WeatherDisplay
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | namespace OCP.c.final.solution { public class WeatherDisplay { private readonly IEnumerable<ITextDisplay> _Displays; public WeatherDisplay(IEnumerable<ITextDisplay> displays) { _Displays = displays; } public void DisplayWeather() { foreach (ITextDisplay display in _Displays) { display.Show(Console.Out); } } } } |
Class: DisplayTemperatureInCelcius : ITextDisplay
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace OCP.c.final.solution { public class DisplayTemperatureInCelcius : ITextDisplay { private readonly int _Temperature; public DisplayTemperatureInCelcius(int temperature) { _Temperature = temperature; } public void Show(TextWriter writer) { writer.WriteLine("The current temperature is: " + _Temperature + " degrees celcius."); } } } |
Class: DisplayHumidity : ITextDisplay
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace OCP.c.final.solution { public class DisplayHumidity : ITextDisplay { private readonly int _Humidity; public DisplayHumidity(int humidity) { _Humidity = humidity; } public void Show(TextWriter writer) { writer.WriteLine("The current humidity is: " + _Humidity + " percent."); } } } |
I hope you found these examples helpful. Also take a look at the following links:
http://www.objectmentor.com/resources/articles/ocp.pdf
http://www.lostechies.com/blogs/joe_ocampo/archive/2008/03/21/ptom-the-open-closed-principle.aspx
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
http://en.wikipedia.org/wiki/Strategy_pattern
Code download: http://downloads.fohjin.com/OCP.zip
No comments:
Post a Comment