Академический Документы
Профессиональный Документы
Культура Документы
Windows desktop
Back to search results | Dev Center - Desktop > Samples > OOPS Principles (SOLID Principles)
Get started
My samples
Test & deploy Download C# (85.5 KB)
Upload a sample
Browse sample
Resources requests
Ratings (43) Updated 4/30/2013
Topics ioc, Dependency Injection, Inversion of Control, OOPS Principles, SOLID Principles, Single Responsibility Principle
Srigopal Chitrapu Closed Principle, Liskov Substitution Principle, Interface Segregation Principle, Dependency Inversion Principle,
MSFT, Partner Joined Apr 2007 Dependency Injection Pattern, Inversion of Control principle, OOPS, SOLID
View samples
Report abuse to Microsoft
4 5 13 Show activity
Targeted Audience:
More from Srigopal Chitrapu
1. .NET Architects
Design Patterns - Command Pattern
2. .NET Applica on Designers
(22)
3. .NET Applica on Developers
Design Patterns - MVVM Pattern-
Part 2 Prerequisites:
(12) 1. OOPS
Design Patterns - Dependency 2. Any OOPS Programming language
Injection Pattern Part-2 (Unity
Application Blocks)
Introduc on:
(12) As we all know that using Object Oriented Programming System (OOPS) concepts and using classes, objects will not show that we are wri ng
ecient code in our applica ons. Without knowing OOPS principles we will be using OOPS and facing problems in maintaing and enhancing the co
Design Patterns - Builder Pattern
in our applica ons. So we should know how to implement OOPS and use them in right manner, that is where 5 Object Oriented Principles (also
(14)
called as SOLID Principles) comes into picture. Let us go through each principle and understand how to implement classes and objects in our real
See all me applica ons.
Single Responsibility Principle:
One Class should be responsible for one task.
E.g.
Want to Insert data into database and want to log the details.
If we create a class to represent DataAccess, it should not be used to save to the database (task 1), as well as log the details (task 2).
Problem:
If we want to change database type or we want to change the logger type/loca on, If both tasks present in single class, one task changes aects
to another.
Solu on:
Create one class for saving into database and another class for logging the details.
Exmple:
C#
// Data access class is only responsible for data base related operations
class DataAccess
{
public static void InsertData()
{
Console.WriteLine("Data inserted into database successfully");
}
}
// Logger class is only responsible for logging related operations
class Logger
{
public static void WriteLog()
https://code.msdn.microsoft.com/windowsdesktop/OOPS-Principles-SOLID-7a4e69bf 1/7
8/1/2017 Windows OOPS Principles (SOLID Principles) sample in C# for Visual Studio 2010
public static void WriteLog()
{
Console.WriteLine( "Logged Time:" + DateTime.Now.ToLongTimeString() + " Log Data insertion completed successfully"
}
}
Create a Base class with Required func onality, and ensure we will not modify that class. (Closed for modica on)
Create a Derived class by inheri ng the Base class for extension (Open for modica on)
Example:
C#
https://code.msdn.microsoft.com/windowsdesktop/OOPS-Principles-SOLID-7a4e69bf 2/7
8/1/2017 Windows OOPS Principles (SOLID Principles) sample in C# for Visual Studio 2010
}
}
Func ons that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
Or
If any module is using a Base class then the reference to that Base class can be replaced with a Derived class without aec ng the func onality of
the module.
Or
While implemen ng derived classes, need to ensure that the derived classes just extend the func onality of base classes without replacing the
func onality of base classes.
E.g.
If we are calling a method dened at a base class upon an abstracted class, the func on must be implemented properly on the subtype class.
Example:
C#
// If any module is using a Base class then the reference to that Base class can be replaced with a Derived class without affect
ing the functionality of the module.
// Or
// While implementing derived classes, one needs to ensure that, derived classes just extend the functionality of base classes w
ithout replacing the functionality of base classes.
class Rectangle
{
protected int mWidth = 0 ;
protected int mHeight = 0;
// While implementing derived class if one replaces the functionality of base class then,
// it might results into undesired side effects when such derived classes are used in existing program modules.
class Square : Rectangle
{
// This class modifies the base class functionality instead of extending the base class functionality
class LiskovSubstitutionPrincipleDemo
{
private static Rectangle CreateInstance()
{
// As per Liskov Substitution Principle "Derived types must be completely substitutable for their base types".
bool SomeCondition = false;
if (SomeCondition == true)
{
return new Rectangle();
}
else
{
return new Square();
}
}
https://code.msdn.microsoft.com/windowsdesktop/OOPS-Principles-SOLID-7a4e69bf 3/7
8/1/2017 Windows OOPS Principles (SOLID Principles) sample in C# for Visual Studio 2010
public static void LSPDemo()
{
Console.WriteLine("\n\nLiskov Substitution Principle Demo ");
// User assumes that RectangleObject is a rectangle and (s)he is able to set the width and height as for the base class
RectangleObject.SetWidth(5);
RectangleObject.SetHeight(10);
// Now this results into the area 100 (10 * 10 ) instead of 50 (10 * 5).
Console.WriteLine("Liskov Substitution Principle has been violated and returned wrong result : " + RectangleObject.GetAr
ea());
// So once again I repaet that sub classes should extend the functionality, sub classes functionality should not impact
base class functionality.
}
}
E.g.
When a client depends upon a class that contains interfaces that the client does not use, but that other clients do use, then that client will be
aected by the changes that those other clients force upon the class
Each Derived class should implement func ons from their respec ve interfaces.
No derived interface force other derived classes to implement the func onali es which they won't use.
Example:
C#
// Each client will implement their respective methods no base class forces the other client to implement the methods wh
ich dont required.
// From the above implementation, we are not forcing Sql client to implemnt orcale logic or Oracle client to implement s
ql logic.
By passing dependencies to classes as abstrac ons, you remove the need to program dependency specic.
Also referred as IoC Inversion of Control principle and implements as DI Dependency Injec on Pa ern in programming world.
E.g:
An Employee class that needs to be able to save to XML and a database.
Problem 1:
If we placed ToXML() and ToDB() func ons in the class, we'd be viola ng the single responsibility principle.
Problem 2:
If we created a func on that took a value that represented whether to print to XML or to DB, we'd be hard-coding a set of devices and thus be
viola ng the open closed principle.
Solu on:
1. Create an abstract class named 'DataWriter' that can be inherited from 'XMLDataWriter' and 'DbDataWriter'.
2. Then Create a class named 'EmployeeWriter' that would expose an Output 'DataWriter saveMethod' that accepts a dependency as an argument
See how the Output method is dependent upon the abstrac ons just as the output types are?
Now we can create new types of ways for Employee data to be wri en, perhaps via HTTP/HTTPS by crea ng abstrac ons, and without modifying a
of our previous code!
Read more about Inversion of Control (IoC) with Dependency Injection (DI) Pattern here http://code.msdn.microsoft.com/Dependency-Injection-with-
5702acaf
Example:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SOLIDPrinciplesDemo
{
//DIP Violation
// Low level Class
public class BankAccount
{
public string AccountNumber { get; set; }
public decimal Balance { get; set; }
https://code.msdn.microsoft.com/windowsdesktop/OOPS-Principles-SOLID-7a4e69bf 5/7
8/1/2017 Windows OOPS Principles (SOLID Principles) sample in C# for Visual Studio 2010
// High level Class
public class TransferAmount
{
public BankAccount Source { get; set; }
public BankAccount Destination { get; set; }
public decimal Value { get; set; }
1. The high level TransferAmount class is directly dependent upon the lower level BankAccount class i.e. Tight coupling.
2. The Source and Destination properties reference the BankAccount type.So impossible to substitute other account types unless t
hey are subclasses of BankAccount.
3. Later we want to add the ability to transfer money from a bank account to pay bills, the BillAccount class would have to inhe
rit from BankAccount.
As bills would not support the removal of funds,
3.A. This is likely to break the rules of the Liskov Substitution Principle (LSP) or
3.B. Require changes to the TransferAmount class that do not comply with the Open/Closed Principle (OCP).
//Applying DIP resolves these problems by removing direct dependencies between classes.
public interface ITransferSource
{
long AccountNumber { get; set; }
decimal Balance { get; set; }
void RemoveFunds(decimal value);
}
public interface ITransferDestination
{
long AccountNumber { get; set; }
decimal Balance { get; set; }
void AddFunds(decimal value);
}
public class BOABankAccount : ITransferSource, ITransferDestination
{
public long AccountNumber { get; set; }
public decimal Balance { get; set; }
1. Higher level classes refer to their dependencies using abstractions, such as interfaces or abstract classes i.e. loose coupli
ng.
2. Lower level classes implement the interfaces, or inherit from the abstract classes.
3. This allows new dependencies can be substituted without any impact.
4. Lower levels classes will not cascade upwards as long as they do not involve changing the abstraction.
5. Increases the robustness of the software and improves flexibility.
6. Separation of high level classes from their dependencies raises the possibility of reuse of these larger areas of functionali
ty.
7. Minimized risk to affect old funtionallity present in Higher level classes.
8. Testing applies only for newly added low level classes.
9. Though using this principle implies an increased effort and a more complex code, but it is more flexible.
Note:
In that case the creation of new low level objects inside the high level classes(if necessary) can not be done using the operato
r new.
Instead, some of the Creational design patterns can be used, such as Factory Method, Abstract Factory, Prototype.
The Template Design Pattern is an example where the DIP principle is applied.
I have explained each principle in detail with example in the sample. Download the sample and go through the code with comments.
Thank you for reading my ar cle. Drop all your ques ons/comments in QA tab give me your feedback with star ra ng (1 Star - Very Poor, 5 Star - Very
Good).
Microsoft Azure Windows development videos Windows Insider program Microsoft SQL Server Accessibility About Microsoft
Microsoft Visual Studio Microsoft Virtual Academy Microsoft Affiliate program Internet of Things Microsoft in education Company news
Office Dev Center BizSpark (for startups) Operations Management Suite Microsoft philanthropies Investors
English Sitemap Contact us Privacy & cookies Terms of use Trademarks About our ads Microsoft 2017
https://code.msdn.microsoft.com/windowsdesktop/OOPS-Principles-SOLID-7a4e69bf 7/7