Sie sind auf Seite 1von 7

8/1/2017 Windows OOPS Principles (SOLID Principles) sample in C# for Visual Studio 2010

Technologies Documentation Resources


Windows Dev Center Search Dev Center

Windows desktop
Back to search results | Dev Center - Desktop > Samples > OOPS Principles (SOLID Principles)

Get started

Get SDK and tools


Design
OOPS Principles (SOLID Principles)
Explains about each OOPS Principles (SOLID Principles) in detail. It has sample demos for each principle in detail i.e. Single Responsibility
Quick
Develop access Principle, Open Closed Principle, Liskov Substitution Principle, Interface Segregation Principle, Dependency Inversion Principle.

My samples
Test & deploy Download C# (85.5 KB)
Upload a sample

Browse sample
Resources requests
Ratings (43) Updated 4/30/2013

Dashboard Downloaded 17,050 times License MS-LPL

29,743 Favorites Add to favorites Share

Points Requires Visual Studio 2010


Top 0.5%
Technologies Silverlight, ASP.NET, Windows Forms, WPF, ASP.NET MVC, ASP.NET Web Forms, MVVM, Design Patterns

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

Description Browse code Q and A (6)

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#

//1. Single Responsibility Principle

// 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"
}
}

Open Closed Principle:



Classes, modules, func ons, etc. should be open for extension, but closed for modica on.

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#

//2. Open Close Principle


// Here DataProvder is open for extension (extends to Sql, Oracle, Oledb Providers and so on..) and closed for manipulation
abstract class DataProvider
{
public abstract int OpenConnection();
public abstract int CloseConnection();
public abstract int ExecuteCommand();
}
class SqlDataProvider : DataProvider
{
public override int OpenConnection()
{
Console.WriteLine("\nSql Connection opened successfully");
return 1;
}
public override int CloseConnection()
{
Console.WriteLine("Sql Connection closed successfully");
return 1;
}
public override int ExecuteCommand()
{
Console.WriteLine("Sql Command Executed successfully");
return 1;
}
}
class OracleDataProvider : DataProvider
{
public override int OpenConnection()
{
Console.WriteLine("Oracle Connection opened successfully");
return 1;
}
public override int CloseConnection()
{
Console.WriteLine("Oracle Connection closed successfully");
return 1;
}
public override int ExecuteCommand()
{
Console.WriteLine("Oracle Command Executed successfully");
return 1;
}
}

class OledbDataProvider : DataProvider


{
public override int OpenConnection()
{
Console.WriteLine("OLEDB Connection opened successfully");
return 1;
}
public override int CloseConnection()
{
Console.WriteLine("OLEDB Connection closed successfully");
return 1;
}
public override int ExecuteCommand()
{
Console.WriteLine("OEDB Command Executed successfully");
return 1;
}
}
class OpenClosePrincipleDemo
{
public static void OSPDemo()
{
Console.WriteLine("\n\nOpen Close Principle Demo ");

DataProvider DataProviderObject = new SqlDataProvider();


DataProviderObject.OpenConnection();
DataProviderObject.ExecuteCommand();
DataProviderObject.CloseConnection();

DataProviderObject = new OracleDataProvider();


DataProviderObject.OpenConnection();
DataProviderObject.ExecuteCommand();
DataProviderObject.CloseConnection();

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
}
}

Liskov Subs tu on Principle:



This principle is just an extension of the Open Close Principle.
It means that we must make sure that new derived classes are extending the base classes without changing their behavior.

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;

public virtual void SetWidth(int width)


{
mWidth = width;
}

public virtual void SetHeight(int height)


{
mHeight = height;
}

public virtual int GetArea()


{
return mWidth * mHeight;
}
}

// 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

// Now below methods implementation will impact base class functionality.


public override void SetWidth(int width)
{
mWidth = width;
mHeight = width;
}

public override void SetHeight(int height)


{
mWidth = height;
mHeight = height;
}
}

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 ");

Rectangle RectangleObject = CreateInstance();

// 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.
}
}

Interface Segrega on Principle:



Clients should not be forced to depend upon interfaces that they do not use.

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

Base Interface: IDataProvider


Derived Interfaces: ISqlDataProvider, IOracleDataProvider
Derived Classes: SqlDataClient, OracleDataClient

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#

// Only common generic methods exists for all derived classes.


interface IDataProvider
{
int OpenConnection();
int CloseConnection();
}
// Implement methods specific to the respective derived classes
interface ISqlDataProvider : IDataProvider
{
int ExecuteSqlCommand();
}
// Implement methods specific to the respective derived classes
interface IOracleDataProvider : IDataProvider
{
int ExecuteOracleCommand();
}
// Client 1
// Should not force SqlDataProvider client to implement ExecuteOracleCommand, as it wont required that method to be implemented.

// So that we will derive ISqlDataProvider not IOracleDataProvider


class SqlDataClient : ISqlDataProvider
{
public int OpenConnection()
{
Console.WriteLine("\nSql Connection opened successfully");
return 1;
}
public int CloseConnection()
{
Console.WriteLine("Sql Connection closed successfully");
return 1;
}

// Implemeting ISqlDataProvider, we are not forcing the client to implement IOracleDataProvider


public int ExecuteSqlCommand()
{
Console.WriteLine("Sql Server specific Command Executed successfully");
return 1;
}
}
// Client 2
// Should not force OracleDataProvider client to implement ExecuteSqlCommand, as it wont required that method to be implemented.

// So that we will derive IOracleDataProvider not ISqlDataProvider


class OracleDataClient : IOracleDataProvider
{
public int OpenConnection()
{
Console.WriteLine("\nOracle Connection opened successfully");
return 1;
}
public int CloseConnection()
{
Console.WriteLine("Oracle Connection closed successfully");
return 1;
}
https://code.msdn.microsoft.com/windowsdesktop/OOPS-Principles-SOLID-7a4e69bf 4/7
8/1/2017 Windows OOPS Principles (SOLID Principles) sample in C# for Visual Studio 2010
}
// Implemeting IOracleDataProvider, we are not forcing the client to implement ISqlDataProvider
public int ExecuteOracleCommand()
{
Console.WriteLine("Oracle specific Command Executed successfully");
return 1;
}
}
class InterfaceSegregationPrincipleDemo
{
public static void ISPDemo()
{
Console.WriteLine("\n\nInterface Inversion Principle Demo ");

// 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.

ISqlDataProvider SqlDataProviderObject = new SqlDataClient();


SqlDataProviderObject.OpenConnection();
SqlDataProviderObject.ExecuteSqlCommand();
SqlDataProviderObject.CloseConnection();

IOracleDataProvider OracleDataProviderObject = new OracleDataClient();


OracleDataProviderObject.OpenConnection();
OracleDataProviderObject.ExecuteOracleCommand();
OracleDataProviderObject.CloseConnection();
}
}

Dependency Inversion Principle:



A: High level modules should not depend upon low level modules. Both should depend upon abstrac ons.
B: Abstrac ons should not depend upon details. Details should depend upon abstrac ons.

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?

The dependencies have been inverted.

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; }

public void AddFunds(decimal value)


{
Balance += value;
}
public void RemoveFunds(decimal value)
{
Balance -= value;
}
}

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; }

public void Transfer()


{
Source.RemoveFunds(Value);
Destination.AddFunds(Value);
}
}
/*
Problem with above design:

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).

4. Any extension functionality changes be required to low level modules.


4.A. Change in the BankAccount class may break the TransferAmount.
4.B. In complex scenarios, changes to low level classes can cause problems that cascade upwards through the hierarchy of module
s.
5. As the software grows, this structural problem can be compounded and the software can become fragile or rigid.
6. Without the DIP, only the lowest level classes may be easily reusable.
7. Unit testing should be redone when there is a change in high level or low level classes.
8. Time taken process to change the existing functionality and extending the functionality
*/

//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; }

public void AddFunds(decimal value)


{
Balance += value;
}
public void RemoveFunds(decimal value)
{
Balance -= value;
}
}
public class TransferAmounts
{
public decimal Amount { get; set; }
public void Transfer(ITransferSource TransferSource, ITransferDestination TransferDestination)
{
TransferSource.RemoveFunds(Amount);
TransferDestination.AddFunds(Amount);
}
}
/*
Advantage in above example after applying DIP:

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.

This principle cannot be applied for every class or every module.


If we have a class functionality that is more likely to remain unchanged in the future there is not need to apply this principle
.
*/
class DependencyInversionPrincipleDemo
https://code.msdn.microsoft.com/windowsdesktop/OOPS-Principles-SOLID-7a4e69bf 6/7
8/1/2017 Windows OOPS Principles (SOLID Principles) sample in C# for Visual Studio 2010
class DependencyInversionPrincipleDemo
{
public static void DIPDemo()
{
Console.WriteLine("\n\nDependency Inversion Principle Demo ");

//Created abstract class/interfaces objects for low level classes.


ITransferSource TransferSource = new BOABankAccount();
TransferSource.AccountNumber = 123456789;
TransferSource.Balance = 1000;
Console.WriteLine("Balance in Source Account : " + TransferSource.AccountNumber + " Amount " + TransferSource.Balance);

ITransferDestination TransferDestination = new BOABankAccount();


TransferDestination.AccountNumber = 987654321;
TransferDestination.Balance = 0;
Console.WriteLine("Balance in Destination Account : " + TransferDestination.AccountNumber + " Amount " + TransferDestina
tion.Balance);

TransferAmounts TransferAmountsObject = new TransferAmounts();


TransferAmountsObject.Amount = 100;

// High level class using abstract class/interface objects


TransferAmountsObject.Transfer(TransferSource, TransferDestination);
Console.WriteLine("Transaction successful");

Console.WriteLine("Balance in Source Account : " + TransferSource.AccountNumber + " Amount " + TransferSource.Balance);


Console.WriteLine("Balance in Destination Account : " + TransferDestination.AccountNumber + " Amount " + TransferDestina
tion.Balance);
}
}

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).

Visit my all other ar cles here h p://code.msdn.microso .com/site/search?f%5B0%5D.Type=User&f%5B0%5D.Value=Srigopal%20Chitrapu

Popular Learning Resources Programs For IT Pros Values Company


Windows Dev Center Channel 9 Microsoft developer program Microsoft Power BI Diversity and inclusion Careers

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

ASP.NET Microsoft Imagine Corporate social responsibility Research

IIS.NET Privacy at Microsoft Site map

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

Das könnte Ihnen auch gefallen