<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="https://publishpress.com/"
	>

<channel>
	<title>EngineerSpock</title>
	<atom:link href="https://engineerspock.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://engineerspock.com</link>
	<description>EngineerSpock</description>
	<lastBuildDate>Fri, 11 Jan 2019 08:12:53 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.3.12</generator>

<image>
	<url>https://engineerspock.com/wp-content/uploads/2016/04/cropped-Symbol-32x32.png</url>
	<title>EngineerSpock</title>
	<link>https://engineerspock.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>SOLID Principles: Interface Segregation Principle (ISP)</title>
		<link>https://engineerspock.com/2018/12/27/isp-solid/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=isp-solid</link>
					<comments>https://engineerspock.com/2018/12/27/isp-solid/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Thu, 27 Dec 2018 16:03:22 +0000</pubDate>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[SOLID]]></category>
		<category><![CDATA[ISP]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2656</guid>

					<description><![CDATA[In this part of the SOLID series, we're going to revisit the ISP or Interface Segregation Principle. Yep, this is a very long article. If you want an easier way of learning SOLID principles in depth, then I would recommend you taking my SOLID tutorial just for 10.99$. Interface Segregation [...]]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-1 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ></div><div class="fusion-builder-row fusion-row"></div><div class="fusion-layout-column fusion_builder_column fusion-builder-column-0 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="width:100%;margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-clearfix"></div></div></div><div class="fusion-text fusion-text-1"></div><br />
In this part of the SOLID series, we&#8217;re going to revisit the ISP or Interface Segregation Principle. Yep, this is a very long article. If you want an easier way of learning SOLID principles in depth, then I would recommend you <a href="https://www.udemy.com/solid-principles/?couponCode=BLOG-SOLID-2" rel="noopener" target="_blank">taking my SOLID tutorial</a> just for 10.99$.</p>
<h2>Interface Segregation Principle Definition</h2>
<p>Before giving a definition, I want to say a couple of words about what we mean here by the word “interface”. Of course, “interface” is a reserved keyword in C# which allows to declare a non-implementable type consisting of member signatures. Such a construction defines an API, a shape which has to be implemented by inheritors of that interface. </p>
<p>At the same time, it’s not necessary to implement an interface to expose an interface. What I mean is that classes which don’t implement any interfaces have their own interfaces comprised of publicly visible members. The set of public members of a class represents the interface of that class. So, simply put, an interface is what clients see and use.</p>
<p>A great simple definition of the Interface Segregation Principle was given in the book you have already heard of, “Agile Principles, Patterns, and Practices in C#”. So, the definition is:</p>
<blockquote><p>
“The Interface Segregation Principle states that Clients should not be forced to depend on methods they do not use.”
</p></blockquote>
<p>A simple conclusion that we can draw from this definition is that you should prefer small, cohesive interfaces to “fat” interfaces. Just in case, I’ll remind you that “cohesive” means that all the API members are logically related to each other.</p>
<p>It’s always useful to look at a picture which illustrates the problem. And of course, this is also a chance to get some fun. Look at this illustration.</p>
<p><img decoding="async" fetchpriority="high" src="https://engineerspock.com/wp-content/uploads/2018/12/ISP-300x228.jpg" alt="" width="300" height="228" class="alignleft size-medium wp-image-2660" srcset="https://engineerspock.com/wp-content/uploads/2018/12/ISP-200x152.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-300x228.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-400x304.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-600x457.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/12/ISP.jpg 644w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p>This funny monster wants to eat and that’s why it says that if IRequireFood, then it means that I want to Eat some food, not light candelabra or layout cutlery. This obviously implies that if you have a public interface named IRequireFood, it would be silly to have methods like LaunchAircraft or KillCharacter exposed by that interface.</p>
<h2>A bit of History</h2>
<p>Here is an interesting historical note about the ISP. I’m pretty sure that ISP was first used long ago before Robert Martin, but the first public formulation belongs to Robert C. Martin. He applied the ISP first time while consulting for Xerox. Xerox had created a new printer system that could perform a variety of tasks such as stapling and faxing. The software for this system was created from the ground up. As the software grew, making modifications became more and more difficult so that even the smallest change would take a redeployment cycle of an hour, which made development nearly impossible. The redeployment cycle took so much time because at that time there were no C# or Java, these languages compile very fast. What we can’t say about C++ for example. Bad design of a C++ program can lead to significant compilation time. The consequences are dramatic.</p>
<p>Let’ get back to the story. The design problem was that a single Job class was used by almost all of the tasks. </p>
<p><img decoding="async" src="https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Problem.jpg" alt="" width="614" height="393" class="aligncenter size-full wp-image-2661" srcset="https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Problem-200x128.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Problem-300x192.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Problem-400x256.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Problem-460x295.jpg 460w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Problem-600x384.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Problem.jpg 614w" sizes="(max-width: 614px) 100vw, 614px" /></p>
<p>Whenever a print job or a stapling job needed to be performed, a call was made to the Job class. This resulted in a &#8216;fat&#8217; class with multitudes of methods specific to a variety of different clients. Because of this design, a staple job would know about all the methods of the print job, even though there was no use for them.</p>
<p>To solve the problem, Uncle Bob came up with an idea which is called &#8220;Interface Segregation Principle&#8221; today. Uncle Bob created an interface layer between the Job class and its clients using the Dependency Inversion Principle (that we&#8217;re going to cover later). </p>
<p><img decoding="async" src="https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Solution.jpg" alt="" width="710" height="544" class="aligncenter size-full wp-image-2662" srcset="https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Solution-200x153.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Solution-300x230.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Solution-400x306.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Solution-600x460.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/12/UncleBob-Story-Solution.jpg 710w" sizes="(max-width: 710px) 100vw, 710px" /></p>
<p>Instead of having one large Job class, a Staple Job interface or a Print Job interface was created that would be used by the Staple or Print classes, respectively, calling methods of the Job class. Therefore, one interface was created for each job type, which were all implemented by the Job class.</p>
<p>So, Interface Segregation Principle violation results in classes that depend on things they do not need, increasing coupling and reducing flexibility and maintainability.<br />
 </p>
<h2>Interface Segregation Principle Violation in C#</h2>
<p>I want to show you a real case from my practice which was related to the problem of interface segregation. I’ve been working with devices a lot and once I faced the following case.</p>
<p>Before continuing I want to say that I like to give examples to students which reflect the whole picture of a real-world case, so I’ll describe all the details related to the problem because I think that this helps to understand the material much better.</p>
<p>So, on the top level, we have a monolithic WPF application which works in POS terminals. Those terminals allow people to buy tickets on suburban trains. That application allows users to buy tickets via credit cards. Thus, the application has to work with bank terminals somehow. Due to some business reasons, there were several bank terminal models integrated to POS-terminals, so all of them had to be supported. The interoperation with bank terminals is not direct, bank terminal producers provide their own applications through which our application can work with their bank terminals. Their applications are implemented as COM-servers. If you don’t know what is a COM-server, just think of it as of a standalone executable service. The following diagram reflects the flow of operations:</p>
<p><img decoding="async" src="https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-1024x475.jpg" alt="" width="1024" height="475" class="aligncenter size-large wp-image-2663" srcset="https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-200x93.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-300x139.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-400x186.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-600x279.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-768x357.jpg 768w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-800x371.jpg 800w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-1024x475.jpg 1024w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram-1200x557.jpg 1200w, https://engineerspock.com/wp-content/uploads/2018/12/ISP-Problem-Diagram.jpg 1514w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<p>Let’s look at the code:</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public interface IBankTerminal<br />
{<br />
    void Start();<br />
    void Stop();<br />
    void Ping();<br />
    void BankHostTest();<br />
    void Purchase(decimal amount, string checkId);<br />
    void CancelPayment(string checkId, decimal amount);<br />
    void InterruptTransaction();</p>
<p>    event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; PaymentCompleted;<br />
    event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; CancellationCompleted;<br />
    event EventHandler&lt;TransactionCompletedEventArgs&gt; TransactionCompleted;<br />
}<br />
[/code]</p>
<p>There is a bare minimum of operations which are supported by any possible bank terminal. That’s why I defined the IBankTerminal interface which reflects the API provided by services which interoperate with bank terminals directly.</p>
<p>Now I have three implementations of the IBankTerminal interface: ZapTerminal, ZonTerminal and PdqTerminal. </p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class PdqTerminal : IBankTerminal<br />
{<br />
    private PdqTerminalServiceCommunicator _service = new PdqTerminalServiceCommunicator();</p>
<p>    public void Start() { }<br />
    public void Stop() { }<br />
    public void Ping() { }<br />
    public void BankHostTest() { }<br />
    public void Purchase(decimal amount, string checkId) { }<br />
    public void CancelPayment(string checkId, decimal amount) { }<br />
    public void InterruptTransaction() { }</p>
<p>    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; PaymentCompleted;<br />
    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; CancellationCompleted;<br />
    public event EventHandler&lt;TransactionCompletedEventArgs&gt; TransactionCompleted;<br />
}<br />
[/code]</p>
<p>I omitted the real implementation since it would complicate the example too much and there is no meaning to show you the guts and low-level details. I also omitted the code for Zap and Zon terminal which in their turn use corresponding communication objects as well.</p>
<p>And now I’ll describe the problem which arose. The thing is that bank terminals are different. The ZonTerminal is a black-box solution which physically is a box which on its own works with credit card readers. Credit card readers are those devices which accept your card, read the chip or a magnetic stripe and dispense back a card back to you. So, ZonTerminal doesn’t expose API for interoperating with card readers, because the service application automatically sets all the necessary things up. At the same time, the other two bank terminals, “PdqTerminal” and “ZapTerminal” don’t take responsibility for interoperating with card readers automatically. On the contrary, they delegate this responsibility to a client, exposing API for interoperating with card readers.</p>
<p>So, in the first case (ZonTerminal), our application doesn’t need to do anything at all, while in the other two cases, our application has to show a window to POS-terminal maintenance engineers to provide the ability to set up the bank terminal devices properly. </p>
<p>Let’s look at the ViewModel class which is a presenter for that window which allows maintenance engineers to set up the bank terminal devices. The window has four buttons which allow to test if contact or contactless readers are on a certain port and to find them by scanning through all the available ports in the system.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class CardReadersCommunicatorViewModel<br />
{<br />
    public CardReadersCommunicatorViewModel()<br />
    {<br />
    }</p>
<p>    public bool TestContactReaderOnPort(string port)<br />
    {<br />
        return false;<br />
    }</p>
<p>    public bool TestNonContactReaderOnPort(string port)<br />
    {<br />
        return false;<br />
    }</p>
<p>    public string FindContactReader()<br />
    {<br />
        return null;<br />
    }</p>
<p>    public string FindNonContactReader()<br />
    {<br />
        return null;<br />
    }<br />
}<br />
[/code]</p>
<p>We need to pass in the CardReadersCommunicatorViewModel’s constructor a dependency which is capable of testing and searching for card readers on ports. Now ask yourself what would you do to solve the problem?</p>
<p>The straightforward way is to add four method signatures right into the IBankTerminal. Let’s do this and look at what will happen.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public interface IBankTerminal<br />
{<br />
    &#8230;</p>
<p>    bool IsContactReaderOnPort(string comPort);<br />
    bool IsNonContactReaderOnPort(string comPort);<br />
    string FindContactReader();<br />
    string FindNonContactReader();</p>
<p>    &#8230;<br />
}<br />
[/code]</p>
<p>Ok, since we have three implementers we need to implement the just added API members. Everything will be fine with ZapTerminal and PdqTerminal. </p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class PdqTerminal : IBankTerminal<br />
{<br />
    private PdqTerminalServiceCommunicator _service = new PdqTerminalServiceCommunicator();</p>
<p>    public void Start() { }<br />
    public void Stop() { }<br />
    public void Ping() { }<br />
    public void BankHostTest() { }<br />
    public void Purchase(decimal amount, string checkId) { }<br />
    public void CancelPayment(string checkId, decimal amount) { }<br />
    public void InterruptTransaction() { }</p>
<p>    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; PaymentCompleted;<br />
    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; CancellationCompleted;<br />
    public event EventHandler&lt;TransactionCompletedEventArgs&gt; TransactionCompleted;</p>
<p>    public bool IsContactReaderOnPort(string comPort)<br />
    {<br />
        return _service.IsContactReaderOnPort(comPort);<br />
    }</p>
<p>    public bool IsNonContactReaderOnPort(string comPort)<br />
    {<br />
        return _service.IsNonContactReaderOnPort(comPort);<br />
    }</p>
<p>    public string FindContactReader()<br />
    {<br />
        return _service.FindContactReader();<br />
    }</p>
<p>    public string FindNonContactReader()<br />
    {<br />
        return _service.FindNonContactReader();<br />
    }<br />
}</p>
<p>public class ZapTerminal : IBankTerminal<br />
{<br />
    private ZapTerminalServiceCommunicator _service = new ZapTerminalServiceCommunicator();</p>
<p>    public void Start() { }<br />
    public void Stop() { }<br />
    public void Ping() { }<br />
    public void BankHostTest() { }<br />
    public void Purchase(decimal amount, string checkId) { }<br />
    public void CancelPayment(string checkId, decimal amount) { }<br />
    public void InterruptTransaction() { }</p>
<p>    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; PaymentCompleted;<br />
    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; CancellationCompleted;<br />
    public event EventHandler&lt;TransactionCompletedEventArgs&gt; TransactionCompleted;</p>
<p>    public bool IsContactReaderOnPort(string comPort)<br />
    {<br />
        return _service.IsContactReaderOnPort(comPort);<br />
    }</p>
<p>    public bool IsNonContactReaderOnPort(string comPort)<br />
    {<br />
        return _service.IsNonContactReaderOnPort(comPort);<br />
    }</p>
<p>    public string FindContactReader()<br />
    {<br />
        return _service.FindContactReader();<br />
    }</p>
<p>    public string FindNonContactReader()<br />
    {<br />
        return _service.FindNonContactReader();<br />
    }<br />
}<br />
[/code]</p>
<p>But what about ZonTerminal? ZonTerminal’s service doesn’t provide an API for communicating with card readers. Seemingly, we need to throw NotSupportedExceptions from the implemented members.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class ZonTerminal : IBankTerminal<br />
{<br />
    private ZonTerminalServiceCommunicator _service = new ZonTerminalServiceCommunicator();</p>
<p>    public void Start() { }<br />
    public void Stop() { }<br />
    public void Ping() { }<br />
    public void BankHostTest() { }<br />
    public void Purchase(decimal amount, string checkId) { }<br />
    public void CancelPayment(string checkId, decimal amount) { }<br />
    public void InterruptTransaction() { }</p>
<p>    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; PaymentCompleted;<br />
    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; CancellationCompleted;<br />
    public event EventHandler&lt;TransactionCompletedEventArgs&gt; TransactionCompleted;</p>
<p>    public bool IsContactReaderOnPort(string comPort)<br />
    {<br />
        throw new NotImplementedException();<br />
    }</p>
<p>    public bool IsNonContactReaderOnPort(string comPort)<br />
    {<br />
        throw new NotImplementedException();<br />
    }</p>
<p>    public string FindContactReader()<br />
    {<br />
        throw new NotImplementedException();<br />
    }</p>
<p>    public string FindNonContactReader()<br />
    {<br />
        throw new NotImplementedException();<br />
    }<br />
}<br />
[/code]</p>
<p>Doesn’t this case remind you something? Something we’ve seen previously. Of course, this is a violation of the Liskov Substitution Principle. But what, we’re talking about the Interface Segregation Principle, aren’t we? Yes, we are, the thing is that as I told you earlier, all the principles are related to each other. Sometimes they have hidden relationships. In this particular case, we end up with the LSP violation as a consequence of ISP violation. If we stick with the current solution and request IBankTerminal, we will end up with the following code:</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class CardReadersCommunicatorViewModel<br />
{<br />
    private readonly IBankTerminal _bankTerminal;</p>
<p>    public CardReadersCommunicatorViewModel(IBankTerminal bankTerminal)<br />
    {<br />
        _bankTerminal = bankTerminal;<br />
    }</p>
<p>    public bool TestContactReaderOnPort(string port)<br />
    {<br />
        return _bankTerminal.IsContactReaderOnPort(port);<br />
    }</p>
<p>    public bool TestNonContactReaderOnPort(string port)<br />
    {<br />
        return _bankTerminal.IsNonContactReaderOnPort(port);<br />
    }</p>
<p>    public string FindContactReader()<br />
    {<br />
        return _bankTerminal.FindContactReader();<br />
    }</p>
<p>    public string FindNonContactReader()<br />
    {<br />
        return _bankTerminal.FindNonContactReader();<br />
    }<br />
}<br />
[/code]</p>
<p>we require the IBankTerminal interface as a parameter of the CardReadersCommunicatorViewModel’c constructor, one day, someone will pass the ZonTerminal into the constructor and the end user will get an exception after clicking on the testing or search button in the window.</p>
<p>So, if we want to avoid such unfortunate consequences, we need to acknowledge the fact that the IBankTerminal interface is too fat. It contains excessive API members. </p>
<h2>Fixing the ISP Violation</h2>
<p> <br />
The major and obvious refactoring technique which we usually apply to adhere to the ISP is that we create small isolated interfaces which represent well-defined concrete responsibilities. In this particular case, we need to segregate the responsibility which concerns the interoperating with card readers.</p>
<p>So, I’ll do that.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public interface IBankTerminal<br />
{<br />
    void Start();<br />
    void Stop();<br />
    void Ping();<br />
    void BankHostTest();<br />
    void Purchase(decimal amount, string checkId);<br />
    void CancelPayment(string checkId, decimal amount);<br />
    void InterruptTransaction();</p>
<p>    event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; PaymentCompleted;<br />
    event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; CancellationCompleted;<br />
    event EventHandler&lt;TransactionCompletedEventArgs&gt; TransactionCompleted;<br />
}</p>
<p>public interface IReadersCommunicable<br />
{<br />
    bool IsContactReaderOnPort(string comPort);<br />
    bool IsNonContactReaderOnPort(string comPort);<br />
    string FindContactReader();<br />
    string FindNonContactReader();<br />
}<br />
[/code]</p>
<p>Now we should implement this new interface on our two models of bank terminal which actually can interoperate with card readers.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class PdqTerminal : IBankTerminal, IReadersCommunicable<br />
{<br />
    private PdqTerminalServiceCommunicator _service = new PdqTerminalServiceCommunicator();</p>
<p>    public void Start() { }<br />
    public void Stop() { }<br />
    public void Ping() { }<br />
    public void BankHostTest() { }<br />
    public void Purchase(decimal amount, string checkId) { }<br />
    public void CancelPayment(string checkId, decimal amount) { }<br />
    public void InterruptTransaction() { }</p>
<p>    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; PaymentCompleted;<br />
    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; CancellationCompleted;<br />
    public event EventHandler&lt;TransactionCompletedEventArgs&gt; TransactionCompleted;</p>
<p>    public bool IsContactReaderOnPort(string comPort)<br />
    {<br />
        return _service.IsContactReaderOnPort(comPort);<br />
    }</p>
<p>    public bool IsNonContactReaderOnPort(string comPort)<br />
    {<br />
        return _service.IsNonContactReaderOnPort(comPort);<br />
    }</p>
<p>    public string FindContactReader()<br />
    {<br />
        return _service.FindContactReader();<br />
    }</p>
<p>    public string FindNonContactReader()<br />
    {<br />
        return _service.FindNonContactReader();<br />
    }<br />
}</p>
<p>public class ZapTerminal : IBankTerminal, IReadersCommunicable<br />
{<br />
    private ZapTerminalServiceCommunicator _service = new ZapTerminalServiceCommunicator();</p>
<p>    public void Start() { }<br />
    public void Stop() { }<br />
    public void Ping() { }<br />
    public void BankHostTest() { }<br />
    public void Purchase(decimal amount, string checkId) { }<br />
    public void CancelPayment(string checkId, decimal amount) { }<br />
    public void InterruptTransaction() { }</p>
<p>    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; PaymentCompleted;<br />
    public event EventHandler&lt;PaymentOperationCompletedEventArgs&gt; CancellationCompleted;<br />
    public event EventHandler&lt;TransactionCompletedEventArgs&gt; TransactionCompleted;</p>
<p>    public bool IsContactReaderOnPort(string comPort)<br />
    {<br />
        return _service.IsContactReaderOnPort(comPort);<br />
    }</p>
<p>    public bool IsNonContactReaderOnPort(string comPort)<br />
    {<br />
        return _service.IsNonContactReaderOnPort(comPort);<br />
    }</p>
<p>    public string FindContactReader()<br />
    {<br />
        return _service.FindContactReader();<br />
    }</p>
<p>    public string FindNonContactReader()<br />
    {<br />
        return _service.FindNonContactReader();<br />
    }<br />
}<br />
[/code]</p>
<p>Great. Now we can require the ICardReadersCommunicable interface in the ViewModel’s constructor.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class CardReadersCommunicatorViewModel<br />
{<br />
    private readonly IReadersCommunicable _readersCommunicable;</p>
<p>    public CardReadersCommunicatorViewModel(IReadersCommunicable readersCommunicable)<br />
    {<br />
        _readersCommunicable = readersCommunicable;<br />
    }</p>
<p>    public bool TestContactReaderOnPort(string port)<br />
    {<br />
        return _readersCommunicable.IsContactReaderOnPort(port);<br />
    }</p>
<p>    public bool TestNonContactReaderOnPort(string port)<br />
    {<br />
        return _readersCommunicable.IsNonContactReaderOnPort(port);<br />
    }</p>
<p>    public string FindContactReader()<br />
    {<br />
        return _readersCommunicable.FindContactReader();<br />
    }</p>
<p>    public string FindNonContactReader()<br />
    {<br />
        return _readersCommunicable.FindNonContactReader();<br />
    }<br />
}<br />
[/code]</p>
<p>Great! There is no chance anymore that someone will pass an inappropriate instance which can’t work with card readers. And by the way, now it’s much more understandable what API members to use here, since we have a one-purpose interface here. Now a client of the interfaces should not be bothered by excessive API members thinking of their role. Now everything stands on its shelve.</p>
<p>By applying the ISP, we achieve the low coupling between methods which are different by their meaning and thus we achieve a high cohesion between them in segregated interfaces.<br />
 </p>
<h2>ISP Violation Example 2</h2>
<p>In the previous case, the implementer of an interface itself knew too much, it knew what it should not that’s why it could not implement some members appropriately. So, the existence of a problem has already been obvious at the level of interface implementer.<br />
Very often the problem goes deeper when the problem shows itself only at the implementer’s client level. Consider the following example.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
[DataContract(Namespace = &quot;&quot;)]<br />
public class AppConfig<br />
{<br />
    private AppConfig()<br />
    {<br />
    }</p>
<p>    [DataMember(IsRequired = true)]<br />
    public string ServerId { get; set; }</p>
<p>    [DataMember(IsRequired = true)]<br />
    public string ServerIP { get; set; }</p>
<p>    [DataMember(IsRequired = true)]<br />
    public string ServerPort { get; set; }</p>
<p>    [DataMember(IsRequired = true)]<br />
    public int LoggingSwitch { get; set; }</p>
<p>    [DataMember(IsRequired = true)]<br />
    public int AppSkinId { get; set; }</p>
<p>    [DataMember(IsRequired = true)]<br />
    public decimal Income { get; set; }</p>
<p>    [DataMember(IsRequired = true)]<br />
    public decimal Outcome { get; set; }</p>
<p>    [DataMember(IsRequired = true)]<br />
    public decimal TotalRevenue { get; set; }</p>
<p>    public static AppConfig Config { get; private set; }</p>
<p>    public static void Initialize()<br />
    {<br />
        using (Stream s = File.OpenRead(&quot;config.xml&quot;))<br />
        {<br />
            Config = (AppConfig) new DataContractSerializer(typeof(AppConfig)).ReadObject(s);<br />
        }<br />
    }<br />
}<br />
[/code] </p>
<p>We have a configuration class which is implemented as sort of a singleton. Its constructor is closed and it only can be created via the Initialize method which deserializes an XML configuration file.</p>
<p>Not surprisingly we have a class which utilized that configuration file. Here we have the Report class which implements some business logic of reports generation:</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class Report<br />
{<br />
    public string Generate()<br />
    {<br />
        return $&quot;Income:{AppConfig.Config.Income}&quot; + &quot;\n&quot; +<br />
               $&quot;Outcome:{AppConfig.Config.Outcome}&quot; + &quot;\n&quot; +<br />
               $&quot;Total Revenue:{AppConfig.Config.TotalRevenue}&quot;;<br />
    }<br />
}<br />
[/code]</p>
<p>Currently it directly depends on the AppConfig class. Because of that, we can’t easily write a unit test for the Report class. What we only can do is to write an integration test which deals with xml configuration file, setting it up properly.</p>
<p>To fix the problem, we can abstract away the configuration class by introducing an interface. Let’s extract an interface:</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public interface IAppConfig<br />
{<br />
    string ServerId { get; set; }<br />
    string ServerIP { get; set; }<br />
    string ServerPort { get; set; }<br />
    int LoggingSwitch { get; set; }<br />
    int AppSkinId { get; set; }<br />
    decimal Income { get; set; }<br />
    decimal Outcome { get; set; }<br />
    decimal TotalRevenue { get; set; }<br />
}<br />
[/code]</p>
<p>Now we can request this interface to be passed in the constructor of the Report class.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class Report<br />
{<br />
    private readonly IAppConfig _appConfig;</p>
<p>    public Report(IAppConfig reportsConfig)<br />
    {<br />
        _appConfig = appConfig;<br />
    }<br />
    public string Generate()<br />
    {<br />
        return $&quot;Income:{_appConfig.Income}&quot; + &quot;\n&quot; +<br />
               $&quot;Outcome:{_appConfig.Outcome}&quot; + &quot;\n&quot; +<br />
               $&quot;Total Revenue:{_appConfig.TotalRevenue}&quot;;<br />
    }<br />
}<br />
[/code]</p>
<p>Great! Now we can write a unit test.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
[TestFixture]<br />
public class ReportTests<br />
{<br />
    [Test]<br />
    public void Generate_ValidInput_GeneratesReport()<br />
    {<br />
        IAppConfig appConfig = new TestableAppConfig()<br />
        {<br />
            AppSkinId = 0,<br />
            Income = 10,<br />
            LoggingSwitch = 1,<br />
            Outcome = 100,<br />
            ServerIP = &quot;192.168.0.1&quot;,<br />
            ServerId = &quot;120888&quot;,<br />
            ServerPort = &quot;8080&quot;,<br />
            TotalRevenue = 1000<br />
        };</p>
<p>        Report sut = new Report(appConfig);<br />
        string report = sut.Generate();</p>
<p>        Assert.AreEqual(<br />
            $&quot;Income:10&quot; + &quot;\n&quot; +<br />
            $&quot;Outcome:100&quot; + &quot;\n&quot; +<br />
            $&quot;Total Revenue:1000&quot;,<br />
            report);<br />
    }<br />
}</p>
<p>public class TestableAppConfig : IAppConfig<br />
{<br />
    public string ServerId { get; set; }<br />
    public string ServerIP { get; set; }<br />
    public string ServerPort { get; set; }<br />
    public int LoggingSwitch { get; set; }<br />
    public int AppSkinId { get; set; }<br />
    public decimal Income { get; set; }<br />
    public decimal Outcome { get; set; }<br />
    public decimal TotalRevenue { get; set; }<br />
}<br />
[/code]</p>
<p>What’s wrong with this test? I set up all the properties, even those which are not required by the internal logic of the Report class. You could ask me why I indeed set all the properties, I could set only those which are required. Partly, you’re right, this would solve the problem of excessive code.</p>
<p>But imagine that there are tons of properties like in the real-world configuration file. Some of them even have similar names. Writing a unit test, would you be so sure that you have set all the properties required by the class under test? No, you wouldn’t. You’ll constantly see all that mess in the IntelliSense, asking yourself, whether that class requires that or another property to be set. The only way to get rid of that mess and make the code clearer and cleaner is to apply the Interface Segregation Principle.<br />
 </p>
<h2>Refactoring to Fix ISP Violation</h2>
<p>To cure the disease, we should segregate the configuration interface. The Reports class should know only the part of configuration related to generating reports. Let’s extract that part into a separate interface.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public interface IReportsConfig<br />
{<br />
    public decimal Income { get; set; }<br />
    public decimal Outcome { get; set; }<br />
    public decimal TotalRevenue { get; set; }<br />
}<br />
public interface IAppConfig<br />
{<br />
    public string ServerId { get; set; }<br />
    public string ServerIP { get; set; }<br />
    public string ServerPort { get; set; }<br />
    public int LoggingSwitch { get; set; }<br />
    public int AppSkinId { get; set; }<br />
}</p>
<p>public class TestableReportsAppConfig : IReportsConfig<br />
{<br />
    public decimal Income { get; set; }<br />
    public decimal Outcome { get; set; }<br />
    public decimal TotalRevenue { get; set; }<br />
}</p>
<p>public class TestableAppConfig : IAppConfig<br />
{<br />
    public string ServerId { get; set; }<br />
    public string ServerIP { get; set; }<br />
    public string ServerPort { get; set; }<br />
    public int LoggingSwitch { get; set; }<br />
    public int AppSkinId { get; set; }<br />
}<br />
[/code]</p>
<p>Now we can request the IReportsConfig interface to be passed in the Report’s class constructor.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class Report<br />
{<br />
    private readonly IReportsConfig _reportsConfig;</p>
<p>    public Report(IReportsConfig reportsConfig)<br />
    {<br />
        _reportsConfig = reportsConfig;<br />
    }<br />
    public string Generate()<br />
    {<br />
        return $&quot;Income:{_reportsConfig.Income}&quot; + &quot;\n&quot; +<br />
               $&quot;Outcome:{_reportsConfig.Outcome}&quot; + &quot;\n&quot; +<br />
               $&quot;Total Revenue:{_reportsConfig.TotalRevenue}&quot;;<br />
    }<br />
}<br />
[/code]</p>
<p>Now, the Report class is aware of only those things which are relevant to the Report’s business logic. Let’s implement the unit test now:</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
[TestFixture]<br />
public class ReportTests<br />
{<br />
    [Test]<br />
    public void Generate_ValidInput_GeneratesReport()<br />
    {<br />
        IReportsConfig appConfig = new TestableReportsAppConfig()<br />
        {<br />
            Income = 10,<br />
            Outcome = 100,<br />
            TotalRevenue = 1000<br />
        };</p>
<p>        Report sut = new Report(appConfig);<br />
        string report = sut.Generate();</p>
<p>        Assert.AreEqual(<br />
            $&quot;Income:10&quot; + &quot;\n&quot; +<br />
            $&quot;Outcome:100&quot; + &quot;\n&quot; +<br />
            $&quot;Total Revenue:1000&quot;,<br />
            report);<br />
    }<br />
}</p>
<p>public class TestableReportsAppConfig : IReportsConfig<br />
{<br />
    public decimal Income { get; set; }<br />
    public decimal Outcome { get; set; }<br />
    public decimal TotalRevenue { get; set; }<br />
}<br />
[/code]</p>
<p>Great! Now we don’t need to think of irrelevant stuff. The test is simple, clean and understandable.<br />
 </p>
<h2>Common Smells of Interface Segregation Principle Violation. Fixes and Related Patterns</h2>
<h3>ISP violation can be the root cause of LSP violation</h3>
<p>In the first example, you’ve seen a smell which was similar to the violation of the Liskov Substitution Principle (LSP). We can refer to this smell as to <strong>“degenerate implementation of interface methods”.</strong> If a method which either overrides a method of a base class or implements a method inherited from an interface throws an exception, most likely NotSupportedException or it just does nothing what is called “degenerative implementation” that indicates that ISP may be violated. This is logical since there is a very high chance that a client of such a class doesn’t want to know about that method and doesn’t want to use it. At the same time, this is an indication of LSP violation, since such a class can’t act as a substitution for a base class or an interface. Sometimes, in such cases, the LSP violation is the root cause of the problem, but often the root cause is the violation of the ISP. So, you should study your particular case and figure out what causes the problem.</p>
<h3>Too fat Interface</h3>
<p>Another smell, which you’ve seen in the second demo can be described as the case when a client’s code references a class but only uses a small portion of its API. It obviously indicates that there is a low cohesion between such classes. This should suggest you that something is wrong here and you need to start the investigation of the problem. Often, you’ll find that the problem hides behind the too fat interfaces. To fix the problem, you have to properly segregate such an interface. Another sub-case here is that when you see a fat interface, but you don’t own it, you can’t change the interface because you can’t modify its source code. In that case, it might be useful to apply a Façade pattern. You’ve seen the application of this pattern in the SRP section. In this case, we can use Façade to narrow down the &#8220;width&#8221; of a fat class API.</p>
<p>If you have a fat interface and its API is not compatible with an interface on the client’s side when you try to use it, then you may find that there is also a possibility to apply the Adapter pattern. Firstly, let’s look at the Adapter pattern generally. What is the Adapter pattern?</p>
<p><img decoding="async" src="https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-1024x495.jpg" alt="" width="1024" height="495" class="aligncenter size-large wp-image-2668" srcset="https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-200x97.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-300x145.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-400x193.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-600x290.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-768x371.jpg 768w, https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-800x387.jpg 800w, https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-1024x495.jpg 1024w, https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern-1200x580.jpg 1200w, https://engineerspock.com/wp-content/uploads/2018/12/AdapterPattern.jpg 1380w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>
<p>According to the Gang of Four book, adapter pattern is intended to “Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces”. The picture above demonstrates a case when an adapter can be applied. Imagine that at first, we have the Client which depends on the Fighter interface. On the other side, we have the Wizard class which exposes three members incompatible with the Fighter interface. If we want to use the Wizard through the Fighter interface, we need to introduce a WizardAdapter which implements the Fighter interface and internally uses the Wizard, it adapts it.</p>
<p>In our case, when we talk about the Interface Segregation Principle, we don’t have a classic problem when an adapter is usually applied, because we don’t deal with incompatible interfaces. In our case, interfaces are not incompatible, one is just too fat for another. Nevertheless, the adapter pattern can also be applied in our case as well.</p>
<p>Let’s look at the code which demonstrates the case of applying the Adapter pattern in order to adhere to the ISP. I didn’t come out with a real case, so I’ll just show you a completely synthetic example.</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public interface IWideInterface<br />
{<br />
    void A();<br />
    void B();<br />
    void C();<br />
    void D();<br />
}</p>
<p>public interface INarrowInterface<br />
{<br />
    void A();<br />
    void B();<br />
}<br />
[/code]</p>
<p>Here is the case. At first, you see that we have the IWideInterface which defines four methods, A, B, C, and D. The client’s code wants to use only methods A and B. To apply the Adapter pattern, we can define a separate INarrowInterface which defines only A and B methods. The adapter itself is going to implement that INarrowInterface while it accepts the IWideInterface instance in the constructor. </p>
<p>[code lang=&#8221;csharp&#8221;]<br />
class Adapter : INarrowInterface<br />
{<br />
    private readonly IWideInterface _wide;</p>
<p>    public Adapter(IWideInterface wide)<br />
    {<br />
        _wide = wide;<br />
    }</p>
<p>    public void A()<br />
    {<br />
        _wide.A();<br />
    }</p>
<p>    public void B()<br />
    {<br />
        _wide.B();<br />
    }<br />
}<br />
[/code]</p>
<p>As the implementation of A and B methods, adapter just delegates the responsibility to the IWideInterface instance. The client’s code now can rely on the INarrowInterface, taking the instance in the constructor. We can pass in the adapter instance and the client will get the access only to methods A and B. </p>
<p>[code lang=&#8221;csharp&#8221;]<br />
//needs to use only A and B<br />
class Client<br />
{<br />
    private readonly INarrowInterface _narrow;</p>
<p>    public Client(INarrowInterface narrow)<br />
    {<br />
        _narrow = narrow;<br />
    }<br />
}<br />
[/code]</p>
<p>This is how the Adapter pattern can be applied to adhere to the Interface Segregation Principle.</p>
<p>There is another tricky case related to the Adapter pattern. Let’s say we have a class Persister which is directly used by many clients:</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public class Persister<br />
{<br />
    public void SaveToFile(string file, string content)<br />
    {</p>
<p>    }</p>
<p>    public void SaveToDb(string connectionString, string content)<br />
    {</p>
<p>    }<br />
}<br />
[/code]</p>
<p>And now let’s say new clients require a new method in the Persister and they will depend only on that method. Then we can do the following:</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
public interface INewPersister<br />
{<br />
    void SaveToCloud(string connectionString, string content);<br />
}</p>
<p>public class Persister : INewPersister<br />
{<br />
    public void SaveToFile(string file, string content)<br />
    {</p>
<p>    }</p>
<p>    public void SaveToDb(string connectionString, string content)<br />
    {</p>
<p>    }</p>
<p>    void INewPersister.SaveToCloud(string connectionString, string content)<br />
    {<br />
    }<br />
}<br />
[/code]</p>
<p>Now old clients can use the Persister as they used before and they will not see the new method. While new clients will see only the new method. This implementation of the interface is called &#8211; &#8220;the explicit implementation&#8221;. You can call such a method only through the interface:</p>
<p>[code lang=&#8221;csharp&#8221;]<br />
class PersisterClient<br />
{<br />
    void Save()<br />
    {<br />
        Persister p = new Persister();<br />
        //doesn&#8217;t compile<br />
        //p.SaveToCloud(&quot;&quot;, &quot;&quot;)</p>
<p>        INewPersister np = new Persister();<br />
        np.SaveToCloud(&quot;&quot;, &quot;&quot;); // compiles<br />
    }<br />
}<br />
[/code]</p>
<p>That&#8217;s all about it.</p>
<p>Don&#8217;t forget that the general way of fixing a problem with a fat interface is to create a narrower interface with only absolutely required methods in it, then have the fat interface implement your new interface and then use that new interface in the client’s code which don’t need to know about irrelevant API members of a fat interface. This is exactly what we did in the second refactoring demo while fixing the problem with a configuration.</p>
<p>And the last point here I want to address is that you shouldn’t crush a whole class-level interface into multiple single-method interfaces just because this will make the ISP violation impossible. Apply the refactoring techniques only when you feel that there is a technical debt starts to appear here and there or if a technical debt hasn’t started to spread yet but you know for sure that it will if you don’t fix the ISP violation. </p>
<p>The last tip I want to say about, concerns the dependency management at a binary level. So, the tip is that it is better whenever possible to keep the interface within the client’s assembly. It makes easier to change the interface if something goes wrong. A client will be able to change the interface exactly how it wants instead of rolling out any adapters.</p>
<h2>Conclusion</h2>
<p>The principle we discussed throughout this post was the Interface Segregation Principle or ISP in short. The ISP has a simple definition: “Clients should not be forced to depend on methods they do not use.”  So, this definition implies that you have to strive to create small, cohesive and focused interfaces. </p>
<p>Of course, different clients can use only a subset of API members they depend upon, unless that API start to grow transforming into a very fat interface with unrelated members to each other or when similar but different methods appear to satisfy the requirements of different clients.</p>
<p>A typical way of violation you saw was when an interface was too broad what led to some smells like:</p>
<ul>
<li>implementers throw NotImplementedException</li>
<li>clients have to see all the mess in the IntelliSense thinking of what they actually need to use.<br />
As we discussed, there are several ways of dealing with ISP violations:</li>
<li>sometimes it is just enough to extract a separate interface from a fat one and use it where appropriate</li>
<li>sometimes you need to come out with a Façade which hides irrelevant API members</li>
<li>sometimes you need to apply an Adapter pattern especially if you don’t own the fat interface and thus you can’t modify its source code</li>
</ul>
<p>Intelligent adhering to the Interface Segregation Principle makes an application easier to maintain what is extremely valuable especially in the long term.</p>
<p>Abusing ISP, you can end up with tons of too small interfaces what makes them harder to use by all clients. This is a smell known as Anti-ISP.</p>
<p>That&#8217;s all for the ISP. That was an interesting investigation. But there is another principle waiting for us, the “Dependency Inversion Principle”.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/12/27/isp-solid/feed/</wfw:commentRss>
			<slash:comments>684</slash:comments>
		
		
		
		<series:name><![CDATA[SOLID]]></series:name>
	</item>
		<item>
		<title>SOLID Principles: Liskov Substitution Principle (LSP) In Practice</title>
		<link>https://engineerspock.com/2018/12/26/lsp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lsp</link>
					<comments>https://engineerspock.com/2018/12/26/lsp/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Wed, 26 Dec 2018 17:10:28 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[LSP]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[SOLID]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2625</guid>

					<description><![CDATA[LSP Definition The official definition from Barbara Liskov sounds like this: “If S is a subtype of T, then objects of type T may be replaced with objects of type S, without breaking the program” – B. Liskov. It’s not very hard to grasp what this definition means but I’ll quote the definition of [...]]]></description>
										<content:encoded><![CDATA[<p><div class="fusion-fullwidth fullwidth-box fusion-builder-row-2 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-1 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-2"><h2>LSP Definition</h2>
<p>The official definition from Barbara Liskov sounds like this:</p>
<blockquote>
<p>“If S is a subtype of T, then objects of type T may be replaced with objects of type S, without breaking the program” – B. Liskov.</p>
</blockquote>
<p>It’s not very hard to grasp what this definition means but I’ll quote the definition of LSP from the book of Uncle Bob “Agile Principles, Patterns, and Practices in C#” just in case. We find there the following definition of the Liskov Substitution Principle:</p>
<blockquote>
<p>“The Liskov Substitution Principle states that Subtypes must be substitutable for their base types.”</p>
</blockquote>
<p>By the way, Barbara Liskov is a scientist who described this principle in 1988. Let’s try to clarify what LSP means for developers in practice. What does it mean to be substitutable for a class? Let’s pretend that we have a client which uses the API of interface B.</p>
<p><img decoding="async" class="alignleft size-medium wp-image-2626" src="https://engineerspock.com/wp-content/uploads/2018/11/LSP-300x218.jpg" alt="Inheritance" width="300" height="218" srcset="https://engineerspock.com/wp-content/uploads/2018/11/LSP-200x145.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/11/LSP-300x218.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/11/LSP-400x290.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/11/LSP.jpg 514w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p>There are two implementors of that interface B. It is implemented by classes A and C. Class C can be considered substitutable for class A if the client doesn’t observe any difference using the class C instead of A. From the client’s perspective, a client shouldn’t experience different behavior using different inheritors of the same base class or an interface.</p>
<p>Actually, the LSP is strongly related to how object-oriented languages allow us to use inheritance.</p>
<p><img decoding="async" class="alignleft size-full wp-image-2627" src="https://engineerspock.com/wp-content/uploads/2018/11/Рисунок1.jpg" alt="A derives from B" width="250" height="211" srcset="https://engineerspock.com/wp-content/uploads/2018/11/Рисунок1-200x169.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/11/Рисунок1.jpg 250w" sizes="(max-width: 250px) 100vw, 250px" /></p>
<p>If class B inherits from A, then we can use B as A but we can’t use A as B. Thus, clients of A can use both A and B even if they know nothing about B. This is basics of polymorphism. Despite that this is basics, developers all the time violate the logic of such a relationship. By the way, as a remark, I want to remind you that it’s not necessary to have such a mechanism as the inheritance to model such relationships between objects. In dynamically typed languages, we use the so-called <strong>Duck Typing.</strong> <em>If a bird swims like a duck, it quacks like a duck then I call that bird a duck.</em> That’s why the term “Duck Typing” appeared. Dynamically typed languages don’t know if we’re allowed to call a certain method or not. The runtime checks if an object can respond to a message. By saying &#8220;message&#8221;, I mean a call to a method since in Dynamically Typed Languages it’s better to say “send a message” rather than “call a method.” Ok, let’s get back to the main topic.</p>
<h2>LSP Violation</h2>
<p>There are two ways of breaking the substitutability:</p>
<ul>
<li>Violating a Contract</li>
<li>Violating Covariance\Contravariance</li>
</ul>
<p>For a significant number of developers, it’s unclear what does it mean, so it requires further clarification. Without understanding these fundamental concepts, you’ll not be able to design types which don’t violate LSP, sooner or later you’ll bump into the horrible problems caused by an LSP violation. So, keep patience and let’s discuss a little bit the notion of contracts.</p>
<h2>Contracts</h2>
<p>Programming to Contracts was elaborated by Bertrand Meyer. In his classic book “Object-Oriented Software Construction”, he described the advantages of programming to contracts. He even came out with a whole new language called “Eiffel” which was built with programming to contracts in mind.</p>
<p><em>So, what is a contract?</em> <strong>Many developers mix the notions of an interface and a contract.</strong> This statement becomes more convincing with the fact that in WCF we treat interfaces and contracts equally. In WCF, a service contract can only be represented by an interface. In the real world, including real world outside of programming, contracts have some semantic payload. Usually, they determine some kind of relationships between people, rights, objects and so on. <strong>Interfaces have no semantic payload. </strong>They determine nothing except signatures. But signatures don’t bear any significant semantic payload. An interface represents just a shape. Thus, <strong>interfaces are not contracts.</strong></p>
<p>Here is an example of a contract provided by Krzysztof Cwalina:</p>
<p>[code lang=&#8221;csharp&#8221;]
public abstract class CollectionContract&lt;T&gt; : IList&lt;T&gt; {<br />
    public void Add(T item) {<br />
        AddCore(item);<br />
        count++;<br />
    }</p>
<p>    public int Count {<br />
        get { return count; }<br />
    }</p>
<p>    protected abstract void AddCore(T item);</p>
<p>    private int count;<br />
    &#8230;<br />
}[/code]</p>
<p>This contract says that when an item is added to the collection, the Count property is incremented by one. In addition, this contract is locked for all subtypes.</p>
<p><strong>A contract of a method constitutes of the following parts:</strong></p>
<ul>
<li>Acceptable and unacceptable input values or types, and their meanings</li>
<li>Return values or types, and their meanings</li>
<li>Error and exception condition values or types that can occur, and their meanings</li>
<li>Side effects</li>
<li>Preconditions</li>
<li>Postconditions</li>
<li>Invariants</li>
</ul>
<p>From the learning perspective, we are mostly interested in Preconditions, Postconditions, and Invariants. Preconditions of a function are the set of requirements a function applies to the input parameters and sometimes the state of the object to which that function belongs.</p>
<p>I have a simple example from my own practice. It is, of course, simplified and presented in a form of a skeleton for the sake of simplicity.</p>
<p>[code lang=&#8221;csharp&#8221;]
public interface IBankTerminal1PaymentGateway<br />
{<br />
    uint ProcessPayment(decimal amount);<br />
}<br />
public interface IBankTerminal2PaymentGateway<br />
{<br />
    uint ProcessPayment(decimal amount, string uniqueId);<br />
}<br />
public interface IBankTerminal<br />
{<br />
    int ProcessPayment(decimal amount, string uniqueId);<br />
}<br />
public class BankTerminal1 : IBankTerminal<br />
{<br />
    private IBankTerminal1PaymentGateway _gateway;</p>
<p>    ///&lt;returns&gt;Response Code. Always &gt;= 0&lt;/returns&gt;<br />
    public int ProcessPayment(decimal amount, string uniqueId)<br />
    {<br />
        //doesn&#8217;t require uniqueId at all<br />
        return (int)_gateway.ProcessPayment(amount);<br />
    }<br />
}</p>
<p>public class BankTerminal2 : IBankTerminal<br />
{<br />
    private IBankTerminal2PaymentGateway _gateway;<br />
    public int ProcessPayment(decimal amount, string uniqueId)<br />
    {<br />
        if (string.IsNullOrWhiteSpace(uniqueId))<br />
        {<br />
            throw new ArgumentException(&quot;A client must provide a unique ID for BankTerminal2&quot;);<br />
        }<br />
        return _gateway.ProcessPayment(amount, uniqueId);<br />
    }<br />
}[/code]</p>
<p>Here we have two different bank terminal models. Both models derive from the IBankTerminal interface which defines the ProcessPayment operation.</p>
<p>These terminals share a significant amount of business logic and they have very similar interfaces, so developers decided to join them by introducing that IBankTerminal interface. Unfortunately, both terminals have their own payment gateways with different interfaces. One requires a uniqueId to be generated by a client, while another doesn’t. To make the API universal, developers just rolled out a single method with two parameters.<br />
The implementation of the first terminal just ignores the second parameter, while the second checks the uniqueId and if it’s null or white space, it throws the ArgumentException.<br />
A client doesn’t expect such a behavior working with the base class. This happens because <strong>the second inheritor strengthens the preconditions.</strong> The first terminal accepts the uniqueId which can be equal to any value, no restrictions were applied.<br />
The corollary is that a <strong>client has to be aware of different behavior of these bank terminals.</strong> Those clients who worked with the first terminal would not expect any exceptions working with the second one passing null as a unique id.</p>
<p>The overall idea is that <strong>by weakening postconditions, inheritors extend the possible outcome from a function. As a result, clients face unexpected situations or they, in the end, have to understand different cases and treat them in a specific way.</strong></p>
<p>You can write contracts on the .NET platform in C# with a special library called “Code Contracts”, not surprisingly. Using code contracts, you can harness the power of static code verification on correctness. Due to some practical problems and problems related to the poor implementation of the “Code Contracts” library, it’s not a very popular approach nowadays. For example, Code Contracts work very slow on big solutions. And this is only one of the reasons. This library is out of the scope of the course, so if you’re interested in “Code Contracts” you can just google for it.</p>
<p>Another problem I want to demonstrate is related to the <strong>violation of invariants</strong> on a classic example in the next lecture.</p>
<h2>Violation of Invariants</h2>
<p>Let’s consider a classic example of LSP violation. I love this example because of two reasons. The first one is that it actually demonstrates the LSP violation and this reason is obvious and the second reason is that it shows that Object-Oriented Programming often can’t directly map the relationships between objects in the real world into the same model of relationships between them in code.</p>
<p><strong>A great number of developers think that writing code in OOP language, they’re modeling real-world domain problems.</strong> And partly this is true. But the real-world relationships between objects sometimes can’t be modeled directly in OOP language. Here is one of the naïve OOP statements: <em>“child classes implement IS-A relationship with base classes”.</em> For example, Dog is an Animal. Cat is an Animal. So, we can create three classes. Animal is the base class and the other two (Cat and Dog) are inheritors. Unfortunately, sometimes this kind of design doesn’t work as expected and you’ll see this in a minute.</p>
<p>So, let’s reflect the relationships between two real-world notions in code. We want to implement a Rectangle and Square, being able to calculate their areas. I’m sure you’ll agree with me that in the real world, Square is a special case of Rectangle. It’s obvious because Square is Rectangle with equal sides.</p>
<p>So, we can write the following:[code lang=&#8221;csharp&#8221;]
public class Rectangle<br />
{<br />
    public int Width { get; set; }<br />
    public int Height { get; set; }<br />
}</p>
<p>public class Square : Rectangle<br />
{<br />
}[/code]</p>
<p>I created the Rectangle class which has two properties: Width and Height and the Square which inherits from the Rectangle class. Separately I will create the class which is responsible for calculating areas of that shapes.</p>
<p>[code lang=&#8221;csharp&#8221;]
public class AreaCalculator<br />
{<br />
    // or maybe it&#8217;d be better to multiply Widths?<br />
    public static int CalcSquare(Square square) =&gt; square.Height * square.Height;<br />
    public static int CalcRectangle(Rectangle square) =&gt; square.Height * square.Width;<br />
}[/code]</p>
<p>Looks fine from the first sight. I’ll pretend that I’m a client and I want to create two shapes and calculate their areas. For that, I’ll implement the Main method where all the things will happen.</p>
<p>[code lang=&#8221;csharp&#8221;]
class Program<br />
{<br />
    static void Main()<br />
    {<br />
        Rectangle rect = new Rectangle() { Width = 2, Height = 5 };<br />
        int rectArea = AreaCalculator.CalcRectangle(rect);<br />
        Console.WriteLine($&quot;Rectangle Area = {rectArea}&quot;);</p>
<p>        //</p>
<p>        Rectangle square = new Square() { Height = 2, Width = 10 };<br />
        int squareArea = AreaCalculator.CalcRectangle(square);<br />
        Console.WriteLine($&quot;Square Area = {squareArea}&quot;);<br />
    }<br />
}[/code]</p>
<p>Pay attention to this:</p>
<p>[code lang=&#8221;csharp&#8221;]
Rectangle square = new Square() {Height = 2, Width = 10 };[/code]</p>
<p>Wait a minute. What the hell is this? How a Square can contain sides of different length?<br />
I hope that it’s obvious that something is wrong here with the API of Square. Square allows to set different length to Width and Height.</p>
<p>This design clearly violates the Liskov Substitution Principle. Square is not substitutable for Rectangle. Rectangle implements the invariant which states that width and height could be of different length. Square has to implement another invariant which states that Width and Height have to be equal. I intentionally omit that actually they also have to be greater or equal to zero.<br />
There is another problem is hiding here. Most likely you would need to create methods which take rectangle as a parameter and implement some business logic. In case of calculating the area, such a method could look like this.</p>
<p>[code lang=&#8221;csharp&#8221;]
public static int CalcArea(Rectangle rect)<br />
{<br />
    if (rect is Square)<br />
    {<br />
        return rect.Height * rect.Height;<br />
    }<br />
    else<br />
    {<br />
        return rect.Height * rect.Width;<br />
    }<br />
}[/code]</p>
<p>This method checks the type inside the method and run the appropriate calculation algorithm.<br />
What do you think? Is it a good way to solve the problem of LSP violation? Doesn’t this fix resemble you something we’ve seen previously? Yes, indeed, this is a violation of the Open/Closed principle. This method is open for modification. What will happen if we introduce a new shape? Correct, we will have to modify that switch-statement. This example of <strong>LSP violation is a hidden violation of OCP.</strong></p>
<p>Remember that <em>inheritors can require less and guarantee more but not vice-versa.</em> The smell which we observe here is also called <strong>“Refused Bequest”.</strong> Why at all the problem arise in the way it actually arises here? Were we wrong saying that a square is a special case of a rectangle? No, we were right, this is ridiculous to think what we were wrong. Any child knows that a Square is a subtype of a Rectangle. So why we face this problem directly modeling such a relationship between square and rectangle abstractions?</p>
<p>The answer is quite irritating; the thing is that the programming code just represents the concepts of square and rectangle. The class Rectangle is not a rectangle, and the class Square is not a Square, they are just representatives. Everything is fine actually, the thing is that representatives in the real world also don’t share the relationships between things they represent. So, how can we fix such a poor design? </p>
<h2>Refactoring to Remove LSP Violation</h2>
<p>Obviously, we need to make impossible to set different length of sides for a square to fix the problem. For now, the expectations of the square’s clients are broken. The AreaCalculator class now demonstrates that there is a problem of separated data and behavior. The calculation algorithms are separated from the Rectangle and Square classes which own the data required for calculations. The AreaCalculator can’t exist without Rectangle and Square, so why the behavior was moved away from Rectangle and Square? Rectangle and Square for now obviously lack cohesion. To cure the decease, we as always should construct proper abstractions. What we want to abstract away is the business logic of calculating the area. Each shape has its own algorithm of calculation the area. It is much better to make behavior shared rather than data.</p>
<p>Let’s abstract away the CalculateArea method by introducing the IShape interface.[code lang=&#8221;csharp&#8221;]
public interface IShape<br />
{<br />
    int CalculateArea();<br />
}[/code]</p>
<p>I want the Rectangle and Square to inherit from the IShape implementing their own algorithms.[code lang=&#8221;csharp&#8221;]
public class Rectangle : IShape<br />
{<br />
    public int Width { get; set; }<br />
    public int Height { get; set; }</p>
<p>    public int CalculateArea() =&gt; Width * Height;<br />
}</p>
<p>public class Square : IShape<br />
{<br />
    public int SideLength { get; set; }</p>
<p>    public int CalculateArea() =&gt; SideLength * SideLength;<br />
}[/code]</p>
<p>Square now defines its own property named SideLength. Now a client can’t misuse their API. In case of Rectangle, calling to CalculateArea, a client will get the area of a Rectangle, while in case of Square, a client will get the area of a Square. The client can’t set different length of width and height to a square.</p>
<h2>More Examples of LSP Violation</h2>
<h3>Variance</h3>
<p>We omitted the discussion of a very important topic – variance. Variance is a very complicated concept, so we’re going to only touch this topic despite that it is related to the LSP.</p>
<ul>
<li> Variance is the notion that describes the types compliance. It branches out to two notions: covariance and contravariance. </li>
<li> Assuming the type A can be cast to type B, type X is covariant in case X&lt;A&gt; can be cast to X&lt;B&gt;. </li>
</ul>
<p>For example, IBar is covariant to T, if the following is true:</p>
<p>[code lang=&#8221;csharp&#8221;]
IBar s = …;<br />
IBar&lt;object&gt; o = s;[/code]</p>
<p>This code snippet shows that “s” is covariant to “o”. Here a simple example which demonstrates the problem of casting: assuming we have the following class hierarchy:</p>
<p>[code lang=&#8221;csharp&#8221;]
class Animal { }<br />
class Dog : Animal { }<br />
class Cat : Animal { }[/code]</p>
<p>and a naïve generic implementation of Stack:</p>
<p>[code lang=&#8221;csharp&#8221;]
public class Stack&lt;T&gt;<br />
{<br />
    private int position;<br />
    readonly T[] data = new T[100];<br />
    public void Push(T obj)<br />
    {<br />
        data[position++] = obj;<br />
    }</p>
<p>    public T Pop()<br />
    {<br />
        return data[&#8211;position];<br />
    }<br />
}[/code]</p>
<p>The following code will not compile in C#:</p>
<p>[code lang=&#8221;csharp&#8221;]
Stack&lt;dog&gt; dogs = new Stack&lt;dog&gt;();<br />
Stack&lt;animal&gt; animals = dogs; // compilation error[/code]</p>
<p>C# deprecates this to prevent the possibility of writing the following code: </p>
<p>[code lang=&#8221;csharp&#8221;]
animals.Push(new Cat()); //adding a cat to dogs[/code]</p>
<p>We’re trying here to add cats to dogs. Arrays in C# are covariant because of historical reasons.<br />
So, the following code will compile:[code lang=&#8221;csharp&#8221;]
Dog[] dogs = new Dog[10];<br />
Animal[] animals = dogs;[/code]</p>
<p>And the violation of the LSP will be detected only in the runtime:</p>
<p>[code lang=&#8221;csharp&#8221;]
animals[0] = new Cat(); //runtime exception will occur[/code]</p>
<p>Starting from C# 4, generic interfaces allow variance though special keywords “in” and “out”. Generic classes at the same time don’t allow variance. The “out” keyword guarantees that inside the implementation of that interface, a generic parameter can only be used in the return statements. It solves the problem we’ve seen with adding a cat to a stack of dogs. This can be expressed as in the following snippet: </p>
<p>[code lang=&#8221;csharp&#8221;]
public interface IPoppable&lt;out T&gt;<br />
{<br />
    T Pop();<br />
}[/code]</p>
<p>If the Stack class from the previous example implements this interface, then the following code will compile and be absolutely correct: </p>
<p>[code lang=&#8221;csharp&#8221;]
var dogs = new Stack&lt;dog&gt;();<br />
dogs.Push(new Dog());<br />
IPoppable&lt;animal&gt; animals = dogs; //allowed[/code]</p>
<p>On the contrary, we can use the “in” keyword to ensure that the generic parameter is only used as the input. Here is the code snippet, which demonstrates the idea:</p>
<p>[code lang=&#8221;csharp&#8221;]
public interface IPushable&lt;in T&gt;<br />
{<br />
    void Push(T val);<br />
}[/code]</p>
<p>If the Stack class implements this interface, then the following code will compile and be absolutely correct:</p>
<p>[code lang=&#8221;csharp&#8221;]
IPushable&lt;animal&gt; animals = new Stack&lt;animal&gt;();<br />
IPushable&lt;cat&gt; cats = animals; //allowed<br />
cats.Push(new Cat());[/code]</p>
<h3>NotSupportedException Smell</h3>
<p>Another example I want to show you comes from the BCL of the .NET framework. It is also a well-known example of the LSP violation. There is a generic interface named ICollection&lt;T&gt; defined in the BCL. This type derives from the IEnumerable&lt;T&gt; and it defines the following methods: </p>
<ul>
<li>Add</li>
<li>Clear</li>
<li>Contains</li>
<li>CopyTo</li>
<li>Remove</li>
</ul>
<p>There is also a generic class named ReadOnlyCollection&lt;T&gt; which derives from the ICollection&lt;T&gt; defined in the BCL. As you can guess from the name of the ReadOnlyCollection, it implements a collection which cannot be changed after initialization. At the same time, ReadOnlyCollection&lt;T&gt; derives from the ICollection&lt;T&gt; what means that it should support all the operations defined in that parent generic interface. As a consequence, the ReadOnlyCollection has to implement Add, Clear and Remove methods somehow. But how it is supposed to implement them, taking into account that these operations are deprecated to perform on a read-only collection? Of course, there is no a meaningful way to solve this problem. So, the ReadOnlyCollection just throws the NotSupportedExpcetion from that modification methods. It clearly violates the Liskov Substitution Principle, since clients that work with ICollection&lt;T&gt; don’t expect such a behavior. And this is logical because other implementations of ICollection&lt;T&gt; such as List&lt;T&gt; don’t throw NotSupportedException, they just work as expected from a class which exposes modification methods. <strong>Throwing NotSupportedException is a strong smell of LSP violation.</strong></p>
<h3>Downcasts as a smell of LSP Violation</h3>
<p>Another smell which indicates the LSP violation demonstrates itself by appearing of too many downcasts in the code base. If a client is constantly checking the actual types of base classes or interfaces, it automatically means, that a client is concerned about different implementers for some reason. It means that a client knows some internal details about the object’s hierarchy construction.This smell is a consequence of the LSP violation. An example of such a smell you’ve seen in the lecture where we discussed the relationships between square and rectangle.</p>
<p>Downcasts are not always the indication of LSP violations. It is allowed to downcast a type if you’re absolutely sure about the type you need to downcast to. Consider the following example:</p>
<p>[code lang=&#8221;csharp&#8221;]
public void PayCashback(int customerId, decimal amount)<br />
{<br />
    Customer c = repository.GetCustomer(customerId);<br />
    var pc = c as PrivelegedCustomer;<br />
    if (pc != null)<br />
    {<br />
        pc.AddMoneyToAccount(amount);<br />
    }<br />
    else<br />
    {<br />
        throw new ArgumentException(&quot;PayCashback on a regular customer!&quot;);<br />
    }<br />
}[/code]</p>
<p>For example, the client only calls this function with an id of a privileged customer. A client knows for sure that it passes the id of a privileged customer. We can freely downcast the object returned from the repository and perform an operation. This kind of downcast just, so to speak, reminds the compiler that the real type is PrivelegedCustomer. </p>
<h2>Sum Up</h2>
<p>Let’s sum up what common smells we may face with which indicate the LSP violation.</p>
<p>First of all, if a method throws the NotSupportedException from its body. Another notion which describes this case and which we haven’t discussed yet, but I like it very much is the notion of so-called “Refused Bequest”. So the meaning here is that the child class inherits something but it doesn’t now what to do with the inherited bequest and refuses it by throwing the NotSupportedException. </p>
<p>Another form of the same “Refused Bequest” is when a method has an empty implementation. This is the same case, the only difference is that, a method refuses bequest not so vehemently. Another smell concerns downcasts. Downcasts mean that a client has to know internal details of the abstraction it depends on. Here are some tips to conform with LSP:</p>
<ul>
<li>Try to keep in your mind the “Tell, Don’t Ask” principle which means in essence that the client’s code should be able to just pass messages without thinking of any internal details of the collaborator. Ideally, the client should not be bothered by checking any conditions.</li>
<li>Remember that LSP violation is often a consequence of OCP or ISP violation. We will talk about the Interface Segregation Principle in the next section, so just take into account for now that fact. In such cases, fixing the root cause leads to an automatic fix of the LSP violation.</li>
<li>If you have two classes that share some logic and they are not substitutable, then think of creating a new base class for that two classes. Then inherit those two classes from a base class and ensure that they are substitutable with the new base class.</li>
</ul>
<h2>Conclusion</h2>
<p>A simple definition sounds like this: “The Liskov Substitution Principle states that Subtypes must be substitutable for their base types.”<br />
It means that a client shouldn’t experience different behavior using different inheritors of the same base class or an interface. So, the code which is compliant to the LSP enables proper use of polymorphism and such code becomes more maintainable.<br />
There are two general rules you should adhere to keep your code compliant to the LSP:</p>
<ul>
<li>Do not violate a Contract by either strengthening preconditions or weakening postconditions;</li>
<li>Do not violate Covariance\Contravariance, explicitly mark the generic parameters by “in” or “out” keyword if possible;</li>
</ul>
<p>In practice, the LSP violation also demonstrates itself in the following ways:</p>
<ol>
<li>implementer throws NotSupportedException from a method which is inherited either from a base class or an interface.</li>
<li>implementer has empty implementations, or stubs instead of meaningful implementation.</li>
<li>switch-case statements appear here and there with checks of the actual type of an argument. Downcasts is a similar smell.</li>
</ol>
<p>Want to take &#8220;SOLID Principles Explained&#8221; video course? Take it <a href="https://www.udemy.com/solid-principles/?couponCode=BLOG-SOLID-2" rel="noopener" target="_blank">right now just for 10.99$.</a></p>
</div><div class="fusion-clearfix"></div></div></div></div></div><div class="fusion-fullwidth fullwidth-box fusion-builder-row-3 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-2 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-3"><p></cat></animal></animal></in></animal></dog></out></animal></dog></dog></t></object></b></a></p>
</div><div class="fusion-clearfix"></div></div></div></div></div></p>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/12/26/lsp/feed/</wfw:commentRss>
			<slash:comments>75</slash:comments>
		
		
		
		<series:name><![CDATA[SOLID]]></series:name>
	</item>
		<item>
		<title>Algorithms and Data Structures in C#: Complete Tutorial</title>
		<link>https://engineerspock.com/2018/12/03/algorithms-and-data-structures-in-c-complete-tutorial/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=algorithms-and-data-structures-in-c-complete-tutorial</link>
					<comments>https://engineerspock.com/2018/12/03/algorithms-and-data-structures-in-c-complete-tutorial/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Mon, 03 Dec 2018 13:22:28 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Video Courses]]></category>
		<category><![CDATA[Fundamentals]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[udemy]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2636</guid>

					<description><![CDATA[Why learn about data structures and algorithms? Algorithms and data structures constitute the fundamentals of programming. Good understanding of algorithms and data structures is one of the most important requirements for a great number of work positions. You'll have to solve many problems related to algorithms and data structures at coding interviews. Indeed, you can [...]]]></description>
										<content:encoded><![CDATA[<div class="fusion-fullwidth fullwidth-box fusion-builder-row-4 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-3 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-4"><h2>Why learn about data structures and algorithms?</h2>
<p>Algorithms and data structures constitute the fundamentals of programming.</p>
<p>Good understanding of algorithms and data structures is one of the most important requirements for a great number of work positions. You&#8217;ll have to solve many problems related to algorithms and data structures at coding interviews. Indeed, you can live without an understanding of algorithms and data structures, in general. However, you can do that until you face a real problem which requires to choose the right data structures and implement custom algorithms. If you haven&#8217;t ever faced such problems, believe me, this is just a matter of time. One day, you&#8217;ll face such a problem and if you don&#8217;t understand algorithms and data structures in depth, you&#8217;ll feel yourself ashamed and helpless. You&#8217;ll be stuck.</p>
<p>If you&#8217;re not good at algorithms and data structures, you&#8217;ll never pass a coding interview in a decent company. Almost all the companies prefer to hire those developers who have a good understanding of algorithms and data structures, remember that.  Do not delay the study of fundamental concepts.</p>
<p>Better hardware is not a solution for all the performance-related problems. Sometimes, you need to write software for very slow devices. And that very often depends on the budget of a customer, by the way, so you don&#8217;t have a control over it.</p>
<p>You&#8217;d better understand what&#8217;s going on under the hood at least one level in-depth. Indeed, if you don&#8217;t understand how List works, sometimes you&#8217;ll make sub-optimal or completely wrong decisions.</p>
<h2>Why this course?</h2>
<p>You may ask me &#8220;why should I take exactly your course?&#8221; And here is my answer:</p>
<ul>
<li>This course is a comprehensive tutorial which covers a great number of topics</li>
<li>I tried to do my best to make this course not dry</li>
<li>This course concentrates not only at algorithms and data structures in general but it uncovers the internals of data structures and algorithms built-in .NET BCL (.NET Core&#8217;s BCL is the same regarding fundamental data structures and algorithms)</li>
<li>This course is practical with exercises and solutions</li>
<li>This course will definitely help you to pass technical interviews</li>
<li>This course is made by a professional software developer with more than 10 years of real-world experience</li>
<li>and many other reasons <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
</ul>
<h2>What&#8217;s in the Course?</h2>
<p>For now, the course covers:</p>
<ul>
<li><strong>Introduction to Algorithms and Data Structures:</strong> what is a data structure, abstract data type and what&#8217;s the difference between these notions. What is an algorithm and why they are important to us?</li>
<li><strong>Introduction to Algorithm Analysis:</strong>  determine how long will a program work, build a log-log plot, approximations, order of growth (Big-O notation), memory consumption</li>
<li><strong>Arrays:</strong> arrays in C#, arrays in memory, time complexity of operations on arrays</li>
<li><strong>Sort Algorithms:</strong> bubble sort, selection sort, insertion sort, recursion, shell sort, merge sort, quick sort, stability of sort algorithms</li>
<li><strong>Lists:</strong> List built-in .NET BCL, nodes, linked list including singly and doubly linked lists, linked list built-in .NET</li>
<li><strong>Stacks:</strong> theory and practice; stack based on array, stack based on a linked list, stack built-in .NET</li>
<li><strong>Queues:</strong> theory and practice; queue based on array, circular queue, queue based on linked list, queue built-in .NET BCL</li>
<li><strong>Search Algorithms:</strong> linear search, binary search (more will be added soon)</li>
<li><strong>Immutable Collections:</strong> immutability and memory pressure, immutable stacks and queues, immutable list, immutable sets, immutable dictionaries, builders in immutable collections</li>
<li>Other big sections upcoming soon including: Trees, Heaps, Hashtables</li>
</ul>
<p>You, as a reader of my blog, are eligible for taking <strong>this course just for 9.99$ via the following link:</strong> <a href="https://bit.ly/2Ubm6B5">https://bit.ly/2Ubm6B5</a></p>
<p>Take this course now and you&#8217;ll be satisfied! Don&#8217;t forget that Udemy provides 30-day money back refund policy, so if you don&#8217;t like the course, you just click on a couple of buttons and get your money back!</p>
</div><div class="fusion-clearfix"></div></div></div></div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/12/03/algorithms-and-data-structures-in-c-complete-tutorial/feed/</wfw:commentRss>
			<slash:comments>88</slash:comments>
		
		
			</item>
		<item>
		<title>Introduction to Selenium</title>
		<link>https://engineerspock.com/2018/10/30/introduction-to-selenium/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introduction-to-selenium</link>
					<comments>https://engineerspock.com/2018/10/30/introduction-to-selenium/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Tue, 30 Oct 2018 18:47:26 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[UI Testing]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[udemy]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2537</guid>

					<description><![CDATA[What is Selenium Selenium is a portable software testing framework for web applications. Basically, it automates browsers what in other words means that it simulates how human beings interact with browsers, e.g. click on buttons, select check boxes, type in some text and so on. There are two major ways of using the power of [...]]]></description>
										<content:encoded><![CDATA[<div class="fusion-fullwidth fullwidth-box fusion-builder-row-5 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-4 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-5"><h2>What is Selenium</h2>
<p>Selenium is a portable software testing framework for web applications. Basically, it automates browsers what in other words means that it simulates how human beings interact with browsers, e.g. click on buttons, select check boxes, type in some text and so on.</p>
<p>There are <strong>two major ways of using the power of Selenium:</strong></p>
<ul>
<li><strong>Selenium IDE</strong> – There is Selenium IDE which, in short, allows us to click on the record button, do all the actions in the browser and then replay them by the means of the same IDE. In other words, it allows recording automation test scripts. IDE will generate scripts based on our actions in the browser. Though it allows editing such generated scripts manually, there are no problems with that.</li>
<li><strong>WebDriver</strong> – is a framework which enables writing UI-tests manually in code. Manually written tests are more maintainable comparing to generated scripts with ugly member names and it, of course, implies that there will be a full power of a programming language such as C# at your disposal.</li>
</ul>
<p>Testers very often rely on Selenium IDE when they need to automate some UI-tests, usually due to the lack of programming skills, while programmers more often rely on the WebDriver since it gives more freedom and power. In this course, we’re going to talk about the WebDriver 99% of the time.</p>
<p>In general, the <strong>WebDriver API can be consumed by different languages</strong> such as C#, Java, Ruby etc. So, we’re going to write code in C# referencing Selenium WebDriver NuGet packages. Roughly speaking, there are as many WebDriver API implementations as there are browsers. We’re going to work with the Chrome implementation. And, finally, a specific WebDriver API implementation directly manages the browser. Modern Selenium 3 WebDriver directly calls Web Browser commands rather than fiddling around some javascript code to manage browser and elements on a page. So, we need<strong> three components to work with Selenium:</strong></p>
<ul>
<li>Web Browser installed</li>
<li>Web Driver which is really a web server sending commands to a browser. Each browser has its own driver because each browser exposes different commands</li>
<li>A script which can be written as I already said in different programming languages such as Java or C# or Ruby.</li>
</ul>
<p>So, this is how the overall process works. In short, <strong>with the power of WebDriver, you can do literally anything you want:</strong></p>
<ul>
<li>Navigate to any URL</li>
<li>Resize the Browser window</li>
<li>Click on any button</li>
<li>Select any element</li>
<li>Upload files</li>
<li>Download files</li>
<li>and so on</li>
</ul>
<h2>Key Elements of Selenium</h2>
<p>The key parts when we work with Selenium are:</p>
<ul>
<li><strong>WebDriver</strong> &#8211; which is the most important class responsible for managing a browser. 99% of WebDriver API calls go through the WebDriver object.</li>
<li><strong>WebElement</strong> – another class which encapsulates any element on a web page such as a button, link or an input element. It provides methods for manipulating elements, clicking on them, sending a text to them and so on.</li>
<li><strong>By</strong> – a class which represents an extremely important notion which is called a “locator”. It encapsulates information used by WebDriver for searching for a particular element on a page.</li>
</ul>
<h2>Writing First Automation Example</h2>
<p>Let’s write our first automation example without digging into details too much. Visit the following link: <a href="https://www.ultimateqa.com/simple-html-elements-for-automation/">https://www.ultimateqa.com/simple-html-elements-for-automation/</a></p>
<p>You&#8217;ll see three buttons and a link. Here is the picture:</p>
<p><img decoding="async" width="1901" height="513" class="wp-image-2539" src="https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA.jpg" alt="" srcset="https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA-200x54.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA-300x81.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA-400x108.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA-600x162.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA-768x207.jpg 768w, https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA-800x216.jpg 800w, https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA-1024x276.jpg 1024w, https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA-1200x324.jpg 1200w, https://engineerspock.com/wp-content/uploads/2018/10/UltimateQA.jpg 1901w" sizes="(max-width: 1901px) 100vw, 1901px" /></p>
<p>I drew black boxes around elements that we want to click on. As I mentioned earlier, there is a concept of a &#8220;locator&#8221; that is used for searching the elements. Let&#8217;s talk about locators a bit.</p>
<h2>Selenium Locators</h2>
<p>The most important thing you need to learn to successfully use Selenium concerns the problem of locating web elements. To search for an element, you need to provide the so-called locator to a web driver. Locators are represented by the <em>By</em> class. We have <strong>eight ways of defining a locator.</strong></p>
<p>Assuming that a page has the following button:</p>
<p>[code lang=&#8221;html&#8221;]
    &lt;button id=&quot;UID&quot; class=&quot;beautifulbtn&quot; name=&quot;Name&quot;/&gt;[/code]</p>
<p>we can find it:</p>
<ul>
<li>by ID =&gt; By.Id(&#8220;UID&#8221;);<br />
Id stands for &#8220;identifier&#8221; and they are guaranteed to be unique in a document object model or DOM in short. Think of DOM as of a document structure.</li>
<li>by Name =&gt; By.Name(“Name”); Name is not guaranteed to be unique in a DOM but you’re still able to search for an element by its name if that element defines it. HTML-coders are not obliged to provide one.</li>
<li>by class name =&gt; By.ClassName(&#8220;beautifulbtn&#8221;); On complex web pages, the appearance of almost all the elements is defined by CSS classes. CSS stands for Cascade Style-Sheet and in general, it allows to apply styles to elements in a convenient fashion. So, you’re able to locate an element by its CSS class calling the corresponding API.</li>
<li>by tag =&gt; By.Tag(&#8220;button&#8221;); You can search for an element or elements by its or their tags. In most cases, searching by a tag, you’ll find more than element and then you’ll have to filter them out to find one that you really need to find. So, sayings by tag, we imply regular HTML tags such as &#8220;a&#8221;, &#8220;button&#8221;, &#8220;input&#8221;, &#8220;img&#8221; and so on.</li>
</ul>
<p>The next two options are about searching for an element by link text. Let’s assume that we have the following two hyperlinks defined in HTML:</p>
<p>[code lang=&#8221;html&#8221;]</p>
<p>&lt;div&gt;<br />
     &lt;a href=&quot;&#8230;&quot;&gt;text&lt;/a&gt;<br />
     &lt;a href=&quot;&#8230;&quot;&gt;Another text&lt;/a&gt;<br />
&lt;/div&gt;</p>
<p>[/code]</p>
<p>We can find them:</p>
<ul>
<li>by link text =&gt; By.LinkText(&#8220;text&#8221;); To find the first element by text, you need to call the LinkText method and pass a string that should fully match the link text. Of course, if you need to find the second element with this method, you need to pass &#8220;Another text&#8221; string.</li>
<li>by partial link text =&gt; By.PartialLinkText(“text”); PartialLinkText allows finding elements by searching for matching substrings within link texts. So, passing &#8220;text&#8221; in this case, you’ll find both elements. Passing &#8220;Another&#8221;, you’ll find only the second element.</li>
</ul>
<p>The remaining locators are:</p>
<ul>
<li>by CSS selector</li>
<li>by XPath</li>
</ul>
<p>These locators allow querying a document object model by writing either an XPath or a CSS selector. I’m going to cover these locators separately, especially the CSS selectors since they are the most important. After getting acquainted with Selenium locators, let&#8217;s try to find the buttons we talked about on <a href="https://www.ultimateqa.com/simple-html-elements-for-automation/">https://www.ultimateqa.com/simple-html-elements-for-automation/</a>.</p>
<h2>Automating Elements</h2>
<p>Before writing any code, we need to install two <strong>NuGet packages: Selenium.WebDriver</strong> and one of the drivers, for example, <strong>Selenium.WebDriver.ChromeDriver.</strong></p>
<p>The driver is an EXE file and after installing a ChromeDriver NuGet package, that executable will be copied to the bin folder as a result of building the application. It is a heart of a chrome web driver.</p>
<p>Assuming that we have a regular console application project, we can instantiate a web driver and navigate to a web page as follows:</p>
<p>[code lang=&#8221;csharp&#8221;]
class Program<br />
{<br />
    private static IWebDriver _driver;</p>
<p>    static void Main(string[] args)<br />
    {<br />
        _driver = new ChromeDriver();<br />
        _driver.Navigate().GoToUrl(&quot;https://www.ultimateqa.com/simple-html-elements-for-automation/&quot;);<br />
    }<br />
}[/code]</p>
<p>Before writing locators, I’ll implement a function which clicks on an element and navigates back to the initial page:</p>
<p>[code lang=&#8221;csharp&#8221;]
static void ClickOn(By locator)<br />
{<br />
    IWebDriver driver = new ChromeDriver();<br />
    IWebElement element = driver.FindElement(locator);<br />
    element.Click();</p>
<p>    //to have some time to watch what happens on the screen<br />
    Thread.Sleep(TimeSpan.FromSeconds(5));</p>
<p>    driver.Navigate().GoToUrl(&quot;https://www.ultimateqa.com/simple-html-elements-for-automation/&quot;);<br />
}[/code]</p>
<p>And now we can write the following locators:</p>
<p>[code lang=&#8221;csharp&#8221;]
static void TestSimpleLocators()<br />
{<br />
    ClickOn(By.Id(&quot;idExample&quot;));<br />
    ClickOn(By.Name(&quot;button1&quot;));<br />
    ClickOn(By.ClassName(&quot;buttonClass&quot;));<br />
    ClickOn(By.LinkText(&quot;Click me using this link text!&quot;));<br />
    ClickOn(By.PartialLinkText(&quot;Click me using&quot;));</p>
<p>    var buttons = _driver.FindElements(By.TagName(&quot;button&quot;));<br />
    foreach (var button in buttons)<br />
    {<br />
        //just logging<br />
        Console.WriteLine(button.Text);<br />
    }<br />
}</p>
<p>static void Main()<br />
{<br />
   &#8230;<br />
   TestSimpleLocators();<br />
}[/code]</p>
<p>If you did everything right, you can launch the app and watch how Selenium opens up a Chrome web browser, navigates to a specified webpage and clicks on buttons and links. Now you have the basic understanding of Selenium.</p>
<p><img decoding="async" class="alignleft size-medium wp-image-2050" src="https://engineerspock.com/wp-content/uploads/2017/06/promo-300x201.png" alt="" width="300" height="201" srcset="https://engineerspock.com/wp-content/uploads/2017/06/promo-300x201.png 300w, https://engineerspock.com/wp-content/uploads/2017/06/promo.png 305w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p>You, as a reader of my blog, are eligible <a href="https://www.udemy.com/software-testing-end-to-end/?couponCode=BLOG-TESTING">for taking my video course</a> <strong>&#8220;Automate Applications with SpecFlow and Selenium WebDriver in C#&#8221;</strong> with a maximum possible discount just for $9.99</p>
<p>&nbsp;</p>
</div><div class="fusion-clearfix"></div></div></div></div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/10/30/introduction-to-selenium/feed/</wfw:commentRss>
			<slash:comments>68</slash:comments>
		
		
		
		<series:name><![CDATA[SpecFlow &amp; Selenium]]></series:name>
	</item>
		<item>
		<title>Writing the First Acceptance Test with SpecFlow</title>
		<link>https://engineerspock.com/2018/10/22/first-acceptance-test-specflow/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=first-acceptance-test-specflow</link>
					<comments>https://engineerspock.com/2018/10/22/first-acceptance-test-specflow/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Mon, 22 Oct 2018 14:48:47 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Acceptance Testing]]></category>
		<category><![CDATA[SpecFlow]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2525</guid>

					<description><![CDATA[To write acceptance tests using SpecFlow, we need to properly set up the environment and a testing project. At first, we need to install a SpecFlow extension for Visual Studio. We need it because SpecFlow integrates into Visual Studio allowing us to easily format features and scenarios, generate corresponding code and other things. The installation process is [...]]]></description>
										<content:encoded><![CDATA[<div class="fusion-fullwidth fullwidth-box fusion-builder-row-6 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-5 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-6"><p>To write acceptance tests using SpecFlow, we need to properly set up the environment and a testing project.</p>
<p>At first, we need to install a SpecFlow extension for Visual Studio. We need it because SpecFlow integrates into Visual Studio allowing us to easily format features and scenarios, generate corresponding code and other things. The installation process is straightforward. The only thing is that it will require from you to restart Visual Studio.</p>
<p>Let&#8217;s assume that I have a class which implements the TicTacToe (Crosses and Noughts) game with the following API:</p>
<p>[code lang=&#8221;csharp&#8221;]
public class Game<br />
{<br />
    public void MakeMove(int index);<br />
    public Winner GetWinner();<br />
}[/code]</p>
<p>To write an acceptance test, create a separate project (class library). Install the SpecFlow NuGet package. Apart from that, we need to install a NuGet package for integration of SpecFlow and a unit testing framework which will be used to run tests and write assertions. In my case, I’ll install a package for integrating SpecFlow with NUnit. This package automatically installs the NUnit package to the project since it depends on it. Now we are ready to go.</p>
<p>At first, we need to add a spec flow file. Go to the project and add a new item, search for SpecFlow section, select it and select the &#8220;Feature File in English&#8221;. It’s hard to write high-level business requirements and scenarios for such a simple game, so we will pretend a bit.</p>
<p>Let’s describe a feature.</p>
<p>Feature: TicTacToe Play Game</p>
<p><em>       In order to play a TicTacToe game</em></p>
<p><em>       As a gamer</em></p>
<p><em>       I want to be able to put crosses or zeroes and determine a winner</em></p>
<p>Let’s describe at least one scenario.</p>
<pre>Scenario: Play game
       Given I started a new game
       When I put three crosses in a row       
       Then I should win</pre>
<p>This is the simplest form of a scenario. We can pass tables of values or constants to code from scenarios. SpecFlow supports many cool features.  To execute such a description, you need to generate C# code and implement the test. To generate the code, click on the right mouse button somewhere in the feature file and click on the &#8220;generate step definitions&#8221;.  In the popped up window, click &#8220;generate a file&#8221;. The following file will be generated:</p>
<p>[code lang=&#8221;csharp&#8221;]
[Binding]
public class TicTacToePlayGameSteps<br />
{<br />
    [Given(&quot;@I started a new game&quot;)]
    public void GivenIStartedANewGame()<br />
    {<br />
    }</p>
<p>    [When(@&quot;I put three crosses in a row&quot;)]
    public void WhenIPutThreeCrossesInARow()<br />
    {<br />
    }</p>
<p>    [Then(@&quot;I should win&quot;)]
    public void ThenIShouldWin()<br />
    {<br />
    }<br />
}[/code]</p>
<p>Here you can see the generated testing class. SpecFlow applied special attributes like Binding and Given, When and Then for the steps.</p>
<p>Let’s implement the test.</p>
<p>Given, when, and then steps directly map to the corresponding arrange-act-assert triplet. So, at the given step we need to arrange the object under test. Let’s do this.</p>
<p>[code lang=&#8221;csharp&#8221;]
[Binding]
public class TicTacToePlayGameSteps<br />
{<br />
    private Game _game;<br />
    [Given(&quot;@I started a new game&quot;)]
    public void GivenIStartedANewGame()<br />
    {<br />
        _game = new Game();<br />
    }<br />
}[/code]</p>
<p>At the When step, we should perform actions. Let’s implement it.</p>
<p>[code lang=&#8221;csharp&#8221;]
[Binding]
public class TicTacToePlayGameSteps<br />
{<br />
    private Game _game;<br />
    [When(@&quot;I put three crosses in a row&quot;)]
    public void WhenIPutThreeCrossesInARow()<br />
    {<br />
        _game.MakeMove(1); //1<br />
        _game.MakeMove(4);<br />
        _game.MakeMove(2); //2<br />
        _game.MakeMove(5);<br />
        _game.MakeMove(3); //3<br />
    }<br />
}[/code]</p>
<p>The combination of crosses put in the fields indexed first, two and three should lead to winning. Let’s verify this fact at the Then step.</p>
<p>[code lang=&#8221;csharp&#8221;]
[Binding]
public class TicTacToePlayGameSteps<br />
{<br />
    private Game _game;</p>
<p>    [Then(@&quot;I should win&quot;)]
    public void ThenIShouldWin()<br />
    {<br />
        Assert.AreEqual(Winner.Crosses, _game.GetWinner());<br />
    }<br />
}[/code]</p>
<p>After rebuilding, Visual Studio should detect the acceptance test and allow to run it as a regular unit test. This is how you can create executable documentation easily with the power of SpecFlow. I bet you see the difference between acceptance testing a unit testing. Acceptance tests are understandable for domain experts, while unit tests are not. Want to fill in the gap between domain experts and programmers, then learn SpecFlow and implement use cases in high-level business-readable acceptance tests.</p>
<p><img decoding="async" class="size-medium wp-image-2050 alignleft" src="https://engineerspock.com/wp-content/uploads/2017/06/promo-300x201.png" alt="" width="300" height="201" srcset="https://engineerspock.com/wp-content/uploads/2017/06/promo-300x201.png 300w, https://engineerspock.com/wp-content/uploads/2017/06/promo.png 305w" sizes="(max-width: 300px) 100vw, 300px" />I have a <strong>video course:<br />
&#8220;Automate Application with SpecFlow and Selenium WebDriver in C#&#8221;.</strong><br />
You, as a reader of my blog, are eligible <a href="https://www.udemy.com/software-testing-end-to-end/?couponCode=BLOG-TESTING">for taking a maximum possible discount.</a></p>
</div><div class="fusion-clearfix"></div></div></div></div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/10/22/first-acceptance-test-specflow/feed/</wfw:commentRss>
			<slash:comments>53</slash:comments>
		
		
		
		<series:name><![CDATA[SpecFlow &amp; Selenium]]></series:name>
	</item>
		<item>
		<title>Acceptance and UI Testing with SpecFlow and Selenium</title>
		<link>https://engineerspock.com/2018/10/22/acceptance-ui-testing/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=acceptance-ui-testing</link>
					<comments>https://engineerspock.com/2018/10/22/acceptance-ui-testing/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Mon, 22 Oct 2018 14:09:54 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[unit-testing]]></category>
		<category><![CDATA[Integration Testing]]></category>
		<category><![CDATA[UI Testing]]></category>
		<category><![CDATA[Acceptance Testing]]></category>
		<category><![CDATA[SpecFlow]]></category>
		<category><![CDATA[Selenium]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2518</guid>

					<description><![CDATA[Pyramid of Tests Basically, tests can be divided into three major groups: unit tests integration tests acceptance tests Unit tests are those tests which verify the behavior of a unit under test in isolation. That’s why when a unit under test has dependencies, we often mock them or in other words replace by special [...]]]></description>
										<content:encoded><![CDATA[<div class="fusion-fullwidth fullwidth-box fusion-builder-row-7 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-6 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-7"><h2>Pyramid of Tests</h2>
<p>Basically, tests can be divided into three major groups:</p>
<ul>
<li>unit tests</li>
<li>integration tests</li>
<li>acceptance tests</li>
</ul>
<p><strong>Unit tests</strong> are those tests which verify the behavior of a unit under test in isolation. That’s why when a unit under test has dependencies, we often mock them or in other words replace by special test doubles. Unit tests are great, and the majority of tests should belong to this type of tests. This is because this type of tests is hard to break and easy to run (of course, if they are written in a good style).</p>
<p>On the contrary, <strong>integration tests</strong> verify the behavior of either a part of a system or a whole system. Saying “part of a system”, I mean any significant part which consists of a few units which communicate with each other. Integration tests are brittle, easy to break, hard to maintain and slow. The only one benefit is that they verify how many components interact with each other without any mocks. Components are going to be tested in the environment close to the production’s environment. That’s why integration tests can detect defects undetected by unit tests.</p>
<p><strong>Acceptance tests</strong> verify the software from the user’s point of view. Acceptance tests are expressed in a regular English language. Yes, indeed, they allow customers to write tests in plain English just in a formal syntax. Of course, customers are not allowed to write novels, but writing acceptance tests is much easier than writing unit tests for customers. This way of writing tests allows to meet the requirements written by a customer himself. We will look into an example or a few of examples of how to write such tests in a corresponding section.</p>
<p>You should understand that each type of tests has its own pros and cons. Integrations tests are not better than unit tests or vice-versa. A wise approach to testing is to use different types of tests. Moreover, we usually end up with a pyramid of tests. Here is the pyramid:</p>
<p><img decoding="async" class="aligncenter wp-image-2519 size-full" src="https://engineerspock.com/wp-content/uploads/2018/10/Test-Automation-Pyramid-1.jpg" alt="" width="590" height="411" srcset="https://engineerspock.com/wp-content/uploads/2018/10/Test-Automation-Pyramid-1-200x139.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/10/Test-Automation-Pyramid-1-300x209.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/10/Test-Automation-Pyramid-1-400x279.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/10/Test-Automation-Pyramid-1.jpg 590w" sizes="(max-width: 590px) 100vw, 590px" /></p>
<p>There is no silver bullet regarding the right balance of different types of tests. That balance depends on the type of software you’re working on.</p>
<h2>Integration and UI Testing</h2>
<p>The most significant part of the pyramid consists of unit tests, then integration and acceptance tests go.</p>
<p>Integration tests verify the behavior of either a part of a system or a whole system. They verify how many components interact with each other without any mocks. Components are going to be tested in the environment close to the production environment. That’s why integration tests can detect defects undetected by unit tests. There is also a notion of UI tests. What are UI tests?</p>
<p>Remember that UI tests are integration tests in nature. UI Tests allow to drive the executing of an application by automatic actions performed on the UI. It allows saving much time since it doesn’t require manual testing. We just write code which performs all the actions on the UI. Assertions in UI tests verify what UI shows to users. Integration tests are not comprised of only UI tests. UI tests are only a part of the suite of integration tests.</p>
<h2>Why Write Automated UI Tests?</h2>
<p>Why we might want to write automated UI tests at all? The major benefits of writing UI tests are related to the benefits of any integration tests since UI tests are integration tests (in principle).</p>
<p>So, here are the main benefits of writing UI tests:</p>
<ul>
<li>UI tests can play a role of end-to-end tests which bring into play literally all the code layers of the application.</li>
<li>UI glitches &#8211; UI tests can catch any UI-glitches which is very important for providing the best user experience. For example, UI tests can catch such bugs as a help message doesn’t appear, a button gets disabled or enabled inappropriately and so on.</li>
<li>UI tests reduce (sometimes down to zero) the amount of work that needs to be done by manual testers.</li>
<li>In the case of Web UI tests, you’ll be able to run the same tests against different web browsers such as Firefox, Chrome, Opera and so on. I bet you understand what value it brings to the table, especially if you’re a web developer.</li>
</ul>
<p>I mentioned that UI tests can reduce the amount of work that needs to be done by manual testers. Actually, teams often try to compare automated UI testing versus manual UI testing. Let’s mark out some benefits of automated UI tests over manual tests:</p>
<ul>
<li>Automated UI tests run faster than manual tests and because of that, they provide feedback much faster. They also can be run at any point in time just by a couple of clicks.</li>
<li>Executing a suite of automated UI tests, you ensure the fullness of UI tests while human beings very often forget to perform some tests even when they work with a check-list.</li>
<li>Automated UI tests very often serve as a mechanism which is complementary to what manual testers do. I would say, that if your development team has manual testers, the software developers or sometimes even testers on their own can write all the automated UI tests which are simple to implement, leaving all the complex UI tests which are hard to implement in the code for manual execution. In such a case, UI-tests will free up human testers and allow them to use their skills more efficiently performing the so-called exploratory testing. Human beings are pretty smart and can discover such slick bugs that can’t be discovered automatically.</li>
</ul>
<h2>What is an Acceptance Test?</h2>
<p><strong>In general, acceptance tests are business readable automated tests. </strong>Why do we need them? There are several benefits of writing acceptance tests.</p>
<p>The first benefit is to bring people from the problem domain. In 99% of cases, people from the problem domain are not software engineers and know nothing about unit tests and coding process in general. They can only express the requirements in the natural language. So be it, acceptance tests allow non-technicians to write tests in the natural language. Not in the completely arbitrary style. There is a special form for writing scenarios. So, the first goal is to reduce or completely remove the gap between software developers and specialists from the problem domain. Another benefit is that acceptance tests form the documentation. And what even better, they form executable documentation. That documentation reflects:</p>
<ul>
<li>what features does the system have</li>
<li>how do those features work</li>
<li>what different usage scenarios does the system support</li>
</ul>
<p>The good thing is <strong>that tests reflect the needs of the end users what means that developers can build the right thing and build it right.</strong> Indeed, acceptance tests are electronic incarnation of use cases written on cards within the Agile.</p>
<p>Another benefit is that acceptance tests always reflect current requirements. Either we keep acceptance tests always updated or ditch the whole idea completely. There is no something in between these states. Acceptance tests should always stay in sync with the actual code. Acceptance tests, as well as any tests, are backed up by a framework. The most popular framework to write and run acceptance tests is called SpecFlow.</p>
<h2>Acceptance and UI-Automation Testing Frameworks</h2>
<p>I would mark out the following UI-testing frameworks:</p>
<ul>
<li>Selenium</li>
<li>Visual Studio Coded UI Test</li>
<li>TestStack.White</li>
</ul>
<p><strong>Selenium</strong> is a framework for testing web-UI while VS Coded UI Test allows writing UI-tests both for web-UI and desktop-UI. Selenium and <strong>VS Coded UI Test</strong> frameworks record all your actions and generate code which replays them. Selenium, however, supports another approach which is more suitable for developers and that approach allows to write tests manually. Such tests, in general, are more customizable, readable, and maintainable.</p>
<p><strong>TestStack.White</strong> doesn’t allow to record actions and replay them. It allows writing UI-tests manually in code. This approach takes more time, but it allows to write, as I already said, human-readable and well-maintainable code while the generated code is hard to understand and maintain. TestStack.White is faster than VS Coded UI Test roughly five times being tested on a WPF application.</p>
<p><strong>SpecFlow</strong> is a mature framework for writing acceptance tests. SpecFlow allows us writing special features files in a semi-formal language called Gherkin. We express business requirements and use cases in feature files. A SpecFlow extension that we need to install in Visual Studio allows generating executable C# code from the feature files. That code automatically gets bound to feature scenarios. In the generated code we write actual testing code and write assertions with the power of almost any unit testing framework we want to.</p>
<p>We will look into SpecFlow and Selenium further in this series of posts.</p>
<p><img decoding="async" class="alignleft wp-image-2050 size-medium" src="https://engineerspock.com/wp-content/uploads/2017/06/promo-300x201.png" alt="" width="300" height="201" srcset="https://engineerspock.com/wp-content/uploads/2017/06/promo-300x201.png 300w, https://engineerspock.com/wp-content/uploads/2017/06/promo.png 305w" sizes="(max-width: 300px) 100vw, 300px" />I have a video course &#8220;Automate Application with Specflow and Selenium WebDriver in C#&#8221;.<br />
You, as a reader of my blog, are eligible for<a href="https://www.udemy.com/software-testing-end-to-end/?couponCode=BLOG-TESTING"> taking it with a max possible discount.</a></p>
</div><div class="fusion-clearfix"></div></div></div></div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/10/22/acceptance-ui-testing/feed/</wfw:commentRss>
			<slash:comments>41</slash:comments>
		
		
		
		<series:name><![CDATA[SpecFlow &amp; Selenium]]></series:name>
	</item>
		<item>
		<title>Complete Practical LINQ Tutorial in C#</title>
		<link>https://engineerspock.com/2018/09/12/linq-tutorial/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=linq-tutorial</link>
					<comments>https://engineerspock.com/2018/09/12/linq-tutorial/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Wed, 12 Sep 2018 08:46:00 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Video Courses]]></category>
		<category><![CDATA[LINQ]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2510</guid>

					<description><![CDATA[LINQ to Entities, LINQ to Objects, LINQ to XML, Functional Programming and LINQ Extension methods were introduced in C# 3 and since then became an indispensable part of the .NET platform. That enormously powerful feature allowed to build a whole framework built upon it called LINQ or Language Integrated Query. I’ve seen many code [...]]]></description>
										<content:encoded><![CDATA[<div class="fusion-fullwidth fullwidth-box fusion-builder-row-8 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-7 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-8"><h2>LINQ to Entities, LINQ to Objects, LINQ to XML,<br />
Functional Programming and LINQ</h2>
<p data-pm-slice="0 0 &#091;&#093;">Extension methods were introduced in C# 3 and since then became an indispensable part of the .NET platform. That enormously powerful feature allowed to build a whole framework built upon it called LINQ or Language Integrated Query. I’ve seen many code bases which avoid using LINQ and rely on the old procedural style of programming. <strong>If you still feel uncomfortable with LINQ or you want to improve your understanding of LINQ, then this course is for you</strong>.  As you might know, LINQ was inspired by functional paradigm and F# in particular. So, <strong>this course is not only about LINQ but about the fundamentals of functional programming as well. </strong></p>
<p>This course covers:</p>
<ul>
<li><strong>The basics of LINQ:</strong> extension methods, the idea of pipelining, IEnumerable, implementing our own extension, query syntax, pitfalls of LINQ operations, how to alter a list</li>
<li><strong>Generating data streams:</strong> Enumerable class and its main operations, implementing your own extension which generates a stream of data</li>
<li><strong>Filtering, Ordering, Projecting:</strong> Parsing a CSV file, ThenBy, First, Last, Single, TakeWhile, SkipWhile, Any, All, Contains, SequenceEqual, Select and SelectMany</li>
<li><strong>Joining, Grouping, Aggregating:</strong> Join, Group, GroupJoin, Zip, Sum, Average, Min, Max</li>
<li><strong>Conversions:</strong> OfType, Cast, ToArray, ToList, ToDictionary, ToLookup, AsEnumerable, AsQueryable</li>
<li><strong>LINQ to XML:</strong> overview, generating XML from a collection, reading XML</li>
<li><strong>EF and LINQ: </strong>Expression Trees, Inserting  into and Reading from a database</li>
<li><strong>Extendibility in C#:</strong> what is functional programming (FP), purity and side effects, extending IDisposable, general-purpose extensions, extending StringBuilder, Primitive Obsession</li>
</ul>
<p>In short, this is a great course, so <a href="https://www.udemy.com/master-linq-csharp/?couponCode=LINQ-BLOG">enroll right now</a> and start learning LINQ and the fundamentals of functional programming <strong>just for 10.99$</strong>.</p>
</div><div class="fusion-clearfix"></div></div></div></div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/09/12/linq-tutorial/feed/</wfw:commentRss>
			<slash:comments>20</slash:comments>
		
		
			</item>
		<item>
		<title>Double Your Coding Speed with Visual Studio and ReSharper</title>
		<link>https://engineerspock.com/2018/09/12/vs-resharper-mastery/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=vs-resharper-mastery</link>
					<comments>https://engineerspock.com/2018/09/12/vs-resharper-mastery/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Wed, 12 Sep 2018 07:57:19 +0000</pubDate>
				<category><![CDATA[Video Courses]]></category>
		<category><![CDATA[udemy]]></category>
		<category><![CDATA[junior programmer]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[R#]]></category>
		<category><![CDATA[ReSharper]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2503</guid>

					<description><![CDATA[Learn how to speed up the coding process in bear Visual Studio 2017 and VS empowered by ReSharper (R#). Modern integrated development environments or IDEs, in short, allows us to perform miracles. Why? Because we live in the twenty-first century and modern computers are so powerful that modern IDEs become indispensable assistants which can [...]]]></description>
										<content:encoded><![CDATA[<div class="fusion-fullwidth fullwidth-box fusion-builder-row-9 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-8 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-9"><p>Learn how to speed up the coding process in bear Visual Studio 2017 and VS empowered by ReSharper (R#).</p>
<p data-pm-slice="0 0 &#091;&#093;">Modern integrated development environments or IDEs, in short, allows us to perform miracles. Why? Because we live in the twenty-first century and modern computers are so powerful that <strong>modern IDEs become indispensable assistants which can save us thousands of hours.</strong> A decade ago, no one could imagine how much powerful IDEs will become in the future. However, nowadays, developers are armed by superpowers such as deep static analysis, automatically performed refactorings, code fixes, super simple navigation, and many other things.</p>
<p>This is a developer without a powerful IDE.</p>
<p><img decoding="async" class="wp-image-2504 alignnone" src="https://engineerspock.com/wp-content/uploads/2018/09/c81c42b89e6b848ce7d09b5e5550ab50.jpg" alt="" width="645" height="428" srcset="https://engineerspock.com/wp-content/uploads/2018/09/c81c42b89e6b848ce7d09b5e5550ab50-200x133.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/09/c81c42b89e6b848ce7d09b5e5550ab50-300x199.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/09/c81c42b89e6b848ce7d09b5e5550ab50-400x266.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/09/c81c42b89e6b848ce7d09b5e5550ab50-600x398.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/09/c81c42b89e6b848ce7d09b5e5550ab50.jpg 735w" sizes="(max-width: 645px) 100vw, 645px" /></p>
<p>Abject worm. Go and kill yourself against the wall.</p>
<p>Or become a real developer. Here is how a real developer looks like:</p>
<p><img decoding="async" class="wp-image-2505 alignnone" src="https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-1024x576.jpg" alt="" width="647" height="364" srcset="https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-200x113.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-300x169.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-400x225.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-600x338.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-768x432.jpg 768w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-800x450.jpg 800w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-1024x576.jpg 1024w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-1200x675.jpg 1200w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers.jpg 1920w" sizes="(max-width: 647px) 100vw, 647px" /></p>
<p><strong>Want to become an iron developer? Then listen to me. </strong></p>
<p>This course consists of two main parts. The first one concerns the features of a bear visual studio without any super-powerful plugins and  it covers:</p>
<ul>
<li><strong>Navigate through the code base:</strong> how to select code, how to find code, camel humps in IntelliSense, navigating through the tabs</li>
<li><strong>Edit and format the code base:</strong> deleting and removing code, formatting, commenting and applying refactorings</li>
<li><strong>Run and debug your code</strong>: working with breakpoints, new features of a modern visual studio, different debugging windows</li>
<li><strong>Code snippets</strong>: existing code snippets and creating custom code snippets</li>
<li><strong>Extensions for Visual Studio</strong>: Color VS Output, NCrunch, PInvoke, .NET Portability Analyzer, Roslynator</li>
</ul>
<p>The second part is dedicated to <strong>ReSharper (R#)</strong>. ReSharper is one of the flagship tools developed by JetBrains. I need to warn you that R# is a paid tool but despite this fact, t<strong>he majority of professional developers use it on an everyday basis.</strong> In my opinion, apart from programming fundamentals, R# is exactly that tool which makes you that guy from the picture:</p>
<p><img decoding="async" class="wp-image-2505 alignnone" src="https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-1024x576.jpg" alt="" width="670" height="377" srcset="https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-200x113.jpg 200w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-300x169.jpg 300w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-400x225.jpg 400w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-600x338.jpg 600w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-768x432.jpg 768w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-800x450.jpg 800w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-1024x576.jpg 1024w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers-1200x675.jpg 1200w, https://engineerspock.com/wp-content/uploads/2018/09/iron-man-jarvis-backgrounds-Is-Cool-Wallpapers.jpg 1920w" sizes="(max-width: 670px) 100vw, 670px" /></p>
<p><strong>R# is a Visual Studio plugin which empowers it by tons of refactorings, analytical features, fixes and a ton of other features.</strong> So, the second part is dedicated to R# and it covers:</p>
<ul>
<li>Installing R#</li>
<li>R# Settings</li>
<li>Creating Code with R#</li>
<li>Exploring Code with R#</li>
<li>Refactoring with R#</li>
<li>Unit Testing with R#</li>
<li>R# Annotations</li>
</ul>
<p>This is only an introduction to R#. <strong>I’ll update this course from time to time </strong>teaching you other cool features provided by R#.</p>
<p><strong>Enroll and start learning</strong> how to <strong>double your coding speed</strong> in bear Visual Studio and Visual Studio empowered by R# for <a href="https://www.udemy.com/vs-resharper/?couponCode=VS-SPEED-BLOG"><strong>only 10.99$ right now!</strong></a></p>
</div><div class="fusion-clearfix"></div></div></div></div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/09/12/vs-resharper-mastery/feed/</wfw:commentRss>
			<slash:comments>27</slash:comments>
		
		
			</item>
		<item>
		<title>Multithreading and Parallel Programming in C#</title>
		<link>https://engineerspock.com/2018/07/25/parallel-csharp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=parallel-csharp</link>
					<comments>https://engineerspock.com/2018/07/25/parallel-csharp/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Wed, 25 Jul 2018 10:18:35 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Multithreading]]></category>
		<category><![CDATA[Video Courses]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[udemy]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2500</guid>

					<description><![CDATA[For the last two decades, computers became faster by increasing the number of CPU cores. However, the fact of having more cores itself doesn’t make a computer drastically faster if those cores are not used by software properly. We, as software developers, should know how to write asynchronous and parallel executing code to make our [...]]]></description>
										<content:encoded><![CDATA[<p data-pm-slice="0 0 []"><img decoding="async" class="alignleft size-thumbnail wp-image-1801" src="https://engineerspock.com/wp-content/uploads/2016/01/CSharp-150x150.png" alt="CSharp" width="150" height="150" srcset="https://engineerspock.com/wp-content/uploads/2016/01/CSharp-90x90.png 90w, https://engineerspock.com/wp-content/uploads/2016/01/CSharp-150x150.png 150w, https://engineerspock.com/wp-content/uploads/2016/01/CSharp-220x220.png 220w, https://engineerspock.com/wp-content/uploads/2016/01/CSharp-300x300.png 300w, https://engineerspock.com/wp-content/uploads/2016/01/CSharp.png 375w" sizes="(max-width: 150px) 100vw, 150px" /></p>
<p data-pm-slice="0 0 []">For the last two decades, computers became faster by increasing the number of CPU cores. However, the fact of having more cores itself doesn’t make a computer drastically faster if those cores are not used by software properly. We, as software developers, should know how to write asynchronous and parallel executing code to make our applications faster and more responsive.</p>
<p>This course is all about developing more responsive and fast programs. Multithreading and Parallel Computing are topics for those who already have some experience in programming, otherwise, you may face difficulties with understanding the content. Anyway, <a href="https://www.udemy.com/parallel-csharp/?couponCode=PARALLEL-BLOG">this course</a> covers:</p>
<ul>
<li><strong>Theoretical foundations</strong> of asynchronous programming: main concepts, processes, threads and so on</li>
<li><strong>Low-level Thread API, APM, and EAP </strong></li>
<li><strong>Task Parallel Library (TPL)</strong> including starting tasks, canceling tasks, chaining tasks, waiting for tasks, IO-based tasks, exceptions handling and other</li>
<li><strong>Async and Await</strong> feature of C#</li>
<li><strong>Synchronization </strong>including atomicity, Interlocked, Monitor (lock), ReaderWriterLockSlim, Semaphore, SynchronizationContext, and Mutex</li>
<li><strong>Signaling constructs</strong> such as AutoResetEvent and ManualResetEventSlim, CountdownEvent and Barrier</li>
<li><strong>Spinning </strong>including SpinWait, SpinLock and our own UpdateableSpin</li>
<li><strong>ConcurrentCollections </strong>including ImmutableStack, ImmutableQueue, ImmutableList, Immutable Sets, ImmutableDictionary, ConcurrentStack, ConcurrentQueue, ConcurrentBag, BlockingCollection</li>
<li><strong>Parallel Programming</strong> including Parallel class and PLINQ</li>
</ul>
<p><a href="https://www.udemy.com/parallel-csharp/?couponCode=PARALLEL-BLOG">Enroll and start learning</a> the foundations of multithreading and parallel computing in .NET.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/07/25/parallel-csharp/feed/</wfw:commentRss>
			<slash:comments>35</slash:comments>
		
		
			</item>
		<item>
		<title>Master the Art of Writing Clean Code in C#</title>
		<link>https://engineerspock.com/2018/07/25/cleancode-csharp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cleancode-csharp</link>
					<comments>https://engineerspock.com/2018/07/25/cleancode-csharp/#comments</comments>
		
		<dc:creator><![CDATA[EngineerSpock]]></dc:creator>
		<pubDate>Wed, 25 Jul 2018 09:26:46 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[Video Courses]]></category>
		<category><![CDATA[udemy]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[API-Design]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[anti-pattern]]></category>
		<guid isPermaLink="false">https://engineerspock.com/?p=2496</guid>

					<description><![CDATA[Foundations of building object-oriented infrastructures Despite the fact that C# is a very rich on features language, it's very common to see poorly designed and implemented types in a real world. In fact, C# is one of the richest on features language among object-oriented languages in the world nowadays. But with great power comes great responsibility. It's [...]]]></description>
										<content:encoded><![CDATA[<div class="fusion-fullwidth fullwidth-box fusion-builder-row-10 nonhundred-percent-fullwidth non-hundred-percent-height-scrolling" style="background-color: rgba(255,255,255,0);background-position: center center;background-repeat: no-repeat;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-bottom: 0px;margin-top: 0px;border-width: 0px 0px 0px 0px;border-color:#eae9e9;border-style:solid;" ><div class="fusion-builder-row fusion-row"><div class="fusion-layout-column fusion_builder_column fusion-builder-column-9 fusion_builder_column_1_1 1_1 fusion-one-full fusion-column-first fusion-column-last" style="margin-top:0px;margin-bottom:0px;"><div class="fusion-column-wrapper fusion-flex-column-wrapper-legacy" style="background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;padding: 0px 0px 0px 0px;"><div class="fusion-text fusion-text-10"><h2><img decoding="async" class="alignleft size-medium wp-image-1801" src="https://engineerspock.com/wp-content/uploads/2016/01/CSharp-300x300.png" alt="CSharp" width="300" height="300" srcset="https://engineerspock.com/wp-content/uploads/2016/01/CSharp-90x90.png 90w, https://engineerspock.com/wp-content/uploads/2016/01/CSharp-150x150.png 150w, https://engineerspock.com/wp-content/uploads/2016/01/CSharp-220x220.png 220w, https://engineerspock.com/wp-content/uploads/2016/01/CSharp-300x300.png 300w, https://engineerspock.com/wp-content/uploads/2016/01/CSharp.png 375w" sizes="(max-width: 300px) 100vw, 300px" /></h2>
<h2><strong>Foundations of building object-oriented infrastructures</strong></h2>
<p>Despite the fact that C# is a very rich on features language, it&#8217;s very common to see poorly designed and implemented types in a real world. In fact, C# is one of the richest on features language among object-oriented languages in the world nowadays. But <em>with great power comes great responsibility. </em>It&#8217;s challenging to use all those features in a right way.</p>
<p>You probably have already heard the following well-known statement: <em>most code sucks.</em> Well, this course is all about how to produce code which doesn&#8217;t suck.</p>
<p>Owning skills of producing a well-designed and well-implemented types is the prerequisite for the other developers to treat you as a real professional.</p>
<p data-pm-slice="0 0 &#091;&#093;">Learn how to design and implement types in C# so that the other developers won&#8217;t hate you when using one of the types developed by you. It means you are going to learn how to write code of the high quality: readable, understandable and reliable.</p>
<p data-pm-slice="0 0 &#091;&#093;">That&#8217;s why I decided to create a <a href="https://www.udemy.com/clean-code-csharp/?couponCode=CLEANCODE-BLOG">full-fledged video course &#8220;Master the Art of Writing Clean Code in C#&#8221;</a></p>
<p><strong>Improve your knowledge of object-oriented programming in the context of clean coding and building types of high quality:</strong></p>
<ul>
<li>Learn how to give the best names for API members</li>
<li>Learn all the tricks related to writing clean functions</li>
<li>Avoid common architectural smells. Get rid of unpleasant smells</li>
<li>Apply principles of functional programming: achieve immutability, remove side effects, extend types</li>
<li>Avoid smells related to dependency injection</li>
<li>Write cleaner unit tests</li>
<li>Practice Test-Driven Development</li>
</ul>
<h2><strong>Content and Overview</strong></h2>
<p>This course is aimed at all the C# developers, from beginners to seniors. Topics which are covered in the course are relevant for all kinds of C# developers since all developers design and implement APIs. The topics complexity is very different. There are plenty of very simple topics, and at the same time, there are topics which require from you a solid C# background. There are plenty of code examples throughout this course, so you will learn both theoretical and practical material.</p>
<h3><strong>The course covers the following topics:</strong></h3>
<ul>
<li>Meta Principles: DRY, KISS, YAGNI, SoC, CQS, PoLA, Encapsulation</li>
<li>How to give better names to API members and what naming conventions exist in the .NET platform and suited for C#</li>
<li>Common problems encountered by C# developers in the process of designing and implementing APIs: classes vs structures, creational patterns vs constructors,  poor naming, excessively long methods, output parameters and so on.</li>
<li>Common Architectural Design Smells such as Primitive Obsession, Hidden Dependencies, Violation of Law of Demeter and other.</li>
<li>Functional Programming: immutability, temporal coupling, pipelining, extending IDisposable, Builder Design Pattern, abusing extension methods, dealing with errors</li>
<li>DI-related anti-patterns: control freak, hidden dependencies, temporal coupling, ambient context, facade service, bastard injection, cyclic dependencies</li>
<li>Clean Unit Tests: singletons and static classes, an excessive number of interfaces, testing trivial code, testing of a single concern, different best practices</li>
<li>Practicing TDD: definition, 3 laws, parsing roman numerals, continuous testing, implementing Tic-Tac-Toe</li>
</ul>
<p>The list is far from being complete. The course covers a great number of topics.</p>
<p><a href="https://www.udemy.com/clean-code-csharp/?couponCode=CLEANCODE-BLOG">Enroll and start <strong>Mastering the Art of Writing Clean Code in C#!</strong></a></p>
</div><div class="fusion-clearfix"></div></div></div></div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://engineerspock.com/2018/07/25/cleancode-csharp/feed/</wfw:commentRss>
			<slash:comments>29</slash:comments>
		
		
			</item>
	</channel>
</rss>
