Monday, 10 August 2015

Encapsulation and SOLID Plural Site Lecture Notes

Encapsulation and SOLID Plural Site Lecture Notes

 

http://www.c-sharpcorner.com/UploadFile/damubetha/solid-principles-in-C-Sharp/




SOLID

Single Responsibility Principle
O
pen Closed Principle
L
iskov Substitution Principle
I
nterface Segregation Principle
D
ependency Inversion Principle



-Code that is not up to standard will have par effects on
  • Long Term Productivity
  • Maintainability (you may get version 1 out of the door, but if you've built up technical debt future releases suffer)
We spend  up to 20 times more time reading code than writing code, so we need to find a way to make that ratio better so when adding new features, we can spend less time reading/understanding code and have more time for writing code.

- the point of creating solid code is to make code so supple, so apply-able, that when requirements change you can easily change the code to match the new requirements.

SOLID directs you to a more OO design.
Purpose of SOLID is to make you more productive by making code more maintainable through decomposition and decoupling.

Helps defend against a
  • Rigid design (the design is difficult to change)
  • Fragility - code is easy to break
  • Immobility - The design is difficult to reuse.
  • Viscosity - difficult to do the right thing
  • Needless Complexity - prevents over-design
- One of the problems with SOLID when people encounter it, is that when you apply the Single Responsibility Principle and when you start to apply the Open Closed Principle and the whole append only strategy, you end up having a lot of small classes, and many programmers when they see this for the first time, they really have a strong reaction to it. because they think there's a lot more code, but they really isn't (its called unit bias).

Single Responsibility Principle

 Classes should only have a single responsibility.
-  'responsibility' meaning 'reason for change'
 - single responsibility meaning a class should only have a single reason to change.
 - separation of concerns - a class should do one thing and do it well.

Open Closed Principle

- class should be open for extensibility, but closed for modification, essentially what this means is that when you have written a class and put the class in production or other clients rely on that class you are no longer allowed to make changes to that class. instead if you want to redefine the behavior of that class, it should be open for extensibility, which means that anyone should be able to extend the class in order to redefine parts of its behavior. the only exception to the rule that you are not allowed to make changes through classes that are already used, except for when you find bugs in that class.    bug fixes are ok, but other then that you are not really allowed to make changes to that class when its being used by other clients.

- Favor composition of inheritance

Liskov Substitution Principle


- The LSP talks about polymorphism and that an important aspect of understanding how to go about composition.
- Favor composition of inheritance
Sub-types must be substitute-able for their base types
- A client should be able to consume any implementation of a given interface without changing the correctness of the system. (correctness of the system - meaning the correct behavior of the system)
- The formal definition of Liskov Substitution Principle states that: If S is a subtype of T, then objects of type T may be replaced with objects of type S without altering any of the desirable properties of the program.


eg. if you have a client that talks to version-a of an interface and that does not cause the entire system to crash, if that client changes to talk to an implementation b of the same interface, and that causes the system to crash, then you have changed the correctness of the system, but if the implementation b of the interface also doesn't cause the entire system to crash, then you probably haven't changed the correctness of the system.

The Interface Segregation Principle

-The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.[1] ISP splits interfaces which are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. Such shrunken interfaces are also called role interfaces
- clients should not be forced to depend on methods they do not use.
-  who owns/defines the interface? A client owns/defines the interface, not the concrete classes that implement those interfaces. its the client that needs the interface. so the client owns the interface and the client defines what it needs, there is no reason for a client to define a member of an interface if it doesn't use that member. so remember interfaces arnt defined by the concrete class that implements the interface, they are defined by classes that consume them interface.

-favor
role interfaces (interfaces defined by client for a certain behavior)
over
header interfaces (interfaces defined for concrete classes i,e a entity/DTO with loads of properties)
 
- will help with the violations of the Liskov Substitution Principle


Dependency Inversion Principle

=================================================================







Encapsulation 


-Compartmentalizing a classes behavior elements from its contracted structural elements .

-Encapsulation serves to separate the contractual interface of an abstraction and its implementation

- The process of compartmentalizing the elements of an abstraction that constitute its structure and behavior;


-Concentrate on building a class based on structural elements, and encapsulating the varying behavior
elements. Separating\

  • Information hiding  (implementation hiding)
    -  shifting the code's dependency on an uncertain implementation (design decision) onto a well-defined interface. hiding the implementation details.


Command Query Separation Principle (postels law) - architectural pattern - oo design

Command Query Separation -> "Your operations should be either commands or queries, but not both"
 
 -
Command is an operation that has an observable side affect in the system (i.e. they mutate a state) .
    ie. a save operation is a command as the side effect would be that the saving the data into a database.
-- should return void

- Query is an operation that returns data. (doesn't not mutate state)
-- should return a type

Avoid creating an operation that triggers side effects and also returns data.

i.e Never have a single operation mutates a state and returns data

code example

public class FileStore
{
   public string WorkingDirectory {get;set;}  <- property value is used by save and read operations

    public string Save(int id, string message) //-- is a command-query, saved the message and returned a file name - this is what we're trying to avoid,

     public EventHandler<MessageEventArgs> MessageRead; // returns message
    public void Read (int id);

}

the problem with the "save method" is that we straight away don't understand what the return string value is for, this affects readability for a programmer as he/she will need to look into the code to figure it out. Its  been noted that we spend 10x more time reading code then writing code, by following the command query separation query principle like below, we can easily shorten the time a fellow programmer takes to understand our code.


// how we seperate the above "save" command-query operation
public class FileStore
{
    public string WorkingDirectory {get;set;} 
    public void Save(int fileId, string message) <-- a command clearly states it just saves\
    {
        var path = this.GetFileName(fileId);
        File.WriteAllText(path,message);
      }


    public string Read (int fileId)
   {
      var path = this.GetFileName(fileId);
      var msg = File.ReadAllText(path);  
      return msg;
    }

    public string GetFileName(int fileId)<-- a query that clearly states that it returns a file name.
   {
       return Path.Combine(this.WorkingDirectory, fileId + . ".txt")
    }

 }

Question!! given the implementation we have above, the inputs and the outputs, focusing on the inputs, is there anything that can go wrong here, given the various inputs. the answer is yes, as the WorkingDirectory property which is used by save and read operations can be null, it will throw an error on all operations if its not provide, which is probably.  how can we guard against this invalid object state, one step would be to create a constructor that takes a WorkingDirectory as an input. yet there is still two ways the WorkingDirectory can still be null, the first that the WorkingDirectory property that has a public setter, so its possible to assign null to that setting, we need to make the setter private, so it can only internally be set. The second is that its still possible to invoke the constructor with a null value though the constructor, as a string datatype is a reference type and allows for nulls. In order to protect us against that, we need to add a guard clause, a guard clause is something that only valuates whether or not working directory is null or not at run-time and it fails fast, if it turns out that working directory is null.

we should also fail fast if they provide an invalid working directory string.


// how we seperate the above "save" command-query operation
public class FileStore
{
    public string WorkingDirectory {get; private set;}

   public FileStore(string workingDirectory)
   {
       if (workingDirectory== null)
           throw new ArgumentNullException("workingDirectory);

      if (!Directory.Exists(workingDirectory))
      {
          throw new ArgumentException("working direcorty string does note referend a working
                                                                 directory","workingDirectory")
       }

         this.WorkingDirectory = workingDirectory

   }
 
    public void Save(int fileId, string message) <-- a command clearly states it just saves\
    {

        var path = this.GetFileName(fileId);
        File.WriteAllText(path,message);
      }

    public string Read (int fileId)
   {
      var path = this.GetFileName(fileId);
      var msg = File.ReadAllText(path);  
      return msg;
    }

    public string GetFileName(int fileId)<-- a query that clearly states that it returns a file name.
   {
       return Path.Combine(this.WorkingDirectory, fileId + . ".txt")
    }

 }


 Query's should not return null values when operation cant find a result (effects readability)

you should create and make use of an operation that checks if its legal or not to invoke the query operation beforehand .
- the stronger guarantee that something will be returned, the easier your API will be able to be consumed by a client programmer.

scenario - trying to getting a person object via id, but Id passed in may not associated person in db.

you can do this via the

tester/doer way
 if (doesPersonExist(id)) <---- tester
then { getPerson(id) }

try read way.

public outputObject

if (tryGetPerson(id, out outputObject)) {}

Maybe way (for collections)
return a empty collection



the bottom line of command query separation is that it makes it easier to reason about the code if you strictly follow that principle, so if you can agree with your team, that in a particular code base that you will strictly adhere to the command query separation principle, you will begin to experience that you can trust the code without fully understanding all the implementation details, so if your looking at a piece of code, and you can see that code calls 3 other methods, and you can identify those methods as either commands or queries. and you can also read the names of those method. you will begin to have a high level understanding of how those things interact with each other, without actually having to go through and understand all the implementation details.
Reused abstractions principle

- If you have abstractions, in this case if you have interfaces or abstract base classes, and those abstractions are not being re-used by being implemented by various different concrete classes, then you probably have poor abstractions.

- An Abstraction is the elimination of the irrelevant and the amplification of the essential.
- interfaces are not defined, they are discovered as the system grows.

1. start with the concrete classes
2. discover the abstractions as commonality emerges.

follow the Rule of Three


 Rule of three is a code refactoring rule of thumb to decide when a replicated piece of code should be replaced by a new procedure. It states that the code can be copied once, but that when the same code is used three times, it should be extracted into a new procedure.




Sunday, 9 August 2015

Compound Patterns

Compound Patterns

Defined

A compound pattern combines two or more patterns into a solution that solves a recurring or general problem.

Model View Controller is an example of a compound pattern (MVC is just a few patterns put together)
MVC is a paradigm for factoring your code into functional segments, so you brain does not explode.
The Model View Controller Pattern (MVC) is a compound pattern consisting of the Observer, Strategy and Composite Patterns.

Diagrams

Diagrams for MVC




Patterns in MVC

Lets start with the model. As you might have guessed the model uses the Observer pattern to keep the views and controllers updated on the latest state changes.
The view and the controller, on the other hand, implement the Strategy Pattern. The controller is the behavior of the view, and it can be easily exchanged with another controller if you want different behavior. The view itself also uses a pattern internally to manage the windows, buttons and other components of the display: the composite pattern.









Bullet Points

  • The Model View Controller Pattern (MVC) is a compound pattern consisting of the Observer, Strategy and Composite Patterns.
  • The model makes use of the Observer Pattern so that it can keep observers update yet stay decoupled from them. 
  • The controller is the strategy for the view. The view can use different implementations of the controller to get different behavior.
  • The view uses the Composite Pattern to implement the user interface, which usually consists of nested components like panels, frames and buttons.
  • These patterns work together to decouple the three players in the MVC model, which keeps designs clear and flexible
  • The Adapter Pattern can be used to adapt a new model to an existing view and controller.

Friday, 7 August 2015

The Proxy Pattern

The Proxy Pattern

Defined

The Proxy Pattern provides a surrogate or placeholder for another object to control access to it.

Diagram


Bullet Points

  • The Proxy Pattern provides a representative for another object in order to control the clients access to it. There re a number of ways it can manage that access. 
  • A Remote Proxy manages interaction between a client and a remote object.
  • A Virtual Proxy controls access to an object that is expensive to initiate.
  • A Protection Proxy control access to the methods of an object base on the caller.
  • Many other variants of the Proxy Pattern exist including catching proxies, synchronization proxies, firewall proxies, 
  • Proxy is structurally similar to Decorator, but the two differ in purpose.
  • The Decorator Pattern adds behavior to an object, while a Proxy controls access.
  • Like any wrapper, proxies will increase the Sumner of classes and objects in your design.

Thursday, 6 August 2015

The State Pattern

The State Pattern


Defined

The State Pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.

Encapsulates state-based behavior and delegate behavior to current state

Diagrams



Code Examples

 


 


Bullet Points

  • The State Pattern allows an object to have many different behaviors that are base on its internal state.
  •  Unlike a procedural state machine, the State Pattern represents state as a full blown class.
  • The Context gets its behavior by delegating to the current state object it is composed with.
  • By encapsulating each state into a class, we localize any changes that will need to be made.
  • The State and Strategy Patterns have the same class diagram, but they differ in intent.
  • Strategy Patterns typically configures Context classes with a behavior or algorithm.
  • State Pattern allows a Context to change its behavior as the state of the Context changes.
  • State transitions can be controlled by the State classes  or by the context classes.
  • Using the State patter will typically result in a great number of classes in your design.
  • State classes may be shared among Context instances.

Wednesday, 5 August 2015

The Composite Pattern

 The Composite Pattern

 Defined

The Composite Pattern allows you to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uni-formally.

The Composite Pattern allows use to build structures of objects in the form of trees that contain both compositions of objects and individual objects as nodes.

Using a composite structure, we can apply the same operations over both composites and individual objects, in other words, in most cases we can ignore the difference between compositions of objects and individual objects.



Lets think about composition in terms of menus: this pattern gives us a way to create a tree structure that can handle a nested group of menus and menu items in the same structure. By putting menus and items in the same structure we create a part-whole hierarchy; that is, a tree of objects that made of parts(menus and menu items) but that can be treated as a whole, like on big uber menu.


Once we have our uber menu, we can use this pattern to treat "individual objects and compositions uniformly".
What does that mean? it means if we have a tree structure of menus, sub menus, and perhaps subsubmenus with menu items, then any menu is a "composition" because it can constrains both other menus and menu items, The individual objects are just the menu items, they don't hold other objects,

A composite contains components, components come in two flavors: composites and leaf elements A composite holds a set of children, those children may be other composites or leaf elements.

Diagrams

Tree Structure

Pattern Structure






Diagram shows example how we can tree like structure, where a menu can compose of menu items, and other menus that can contain their own menu items or menus.

 

 

Code Example






 

Bullet Points

  • The Composite Pattern provides a structure to hold both individual objects and composites.
  • The Composite Pattern allows clients to treat composites and individual objects uniformly.
  • A Component is any object in a Composite structure. Components may be other composites or leaf nodes.
  • There are many design trade offs in implementing Composite. You need to balance transparency and safety with your needs.

Single Responsibility Principle

Single Responsibility Principle - Class should only have one reason to change

When we allow a class to not only take care of its own business (managing some kind of aggregate) but also take on more responsibilities. then we've given the class two reasons to change.

We know we want to avoid change in a class like the plague; as modifying code provides all sorts of opportunities for problems to creep in. Having two ways to change increase the probability that class will change in the future and when it does, its going to affect two aspects

Every responsibility of a class is an area of potential change. More than one responsibility means more than one area of change.
The Principle guides us to assign responsibility to one class and only one class.

Separating responsibility is one of the hardest things to do. The only way to succeed is to be diligent in examining your designs and to watch out for signals that a class is changing in more than one way as your system grows.


Tuesday, 4 August 2015

The Iterator Pattern

 The Iterator Pattern

Defined

The Iterator Pattern provides a way to access the elements of an aggregate sequentially without exposing its underlying representation.

Diagram




Code Example

Below is a code example of how to allow a client  to iterate through a collection,  without  caring about if the collection is an array or a list etc, and to do all of this without having to modify the client code, i.e if another collection type of an object presents itself, client code doesn't need changing. Open-closed principle ;)

 public interface IIterator
{
  bool HasNext();
  object Next();
}

public abstract class CatenatedStringInterator : IIterator
{
   protected string _theStringToIterateOver;
   protected int lastSubstringPoint = 0;
  
   public abstract bool HasNext();
   public abstract object Next();
  
}

public class CommaSeperatedStringInterator : CatenatedStringInterator
{
 

    public CommaSeperatedStringInterator(string theStringToIterateOver)
    {
       _theStringToIterateOver = theStringToIterateOver;
    }

     public override bool HasNext()
    {
       //Check if there is a next string by looking for commas
    }
   
    public override object Next()
    {
       //get next string
    }
}

public class AstrixSeperatedStringInterator : CatenatedStringInterator
{
    private string _theStringToIterateOver;
    private int lastSubstringPoint = 0;

    public AstrixSeperatedStringInterator(string theStringToIterateOver)
    {
       _theStringToIterateOver = theStringToIterateOver;
    }

     public override  bool HasNext()
    {
       //Check if there is a next string by looking for Astrixes
    }
   
    public override object Next()
    {
       //get next string
    }
}

public class CatenatedStringPrinter
{
     public void PrintStringsInFile(IIterator iterator)
      {
   
       if (iterator.HasNext())
      {
          System.Print((String)iterator.Next());
       }
   }
}


Bullet Points 

  •  An iterator allows access to an aggregates elements without exposing its internal structure.
  • An Iterator takes the job of iterating over an aggregate an encapsulates it in another object.
  • When using an Iterator, we relieve the aggregate of the responsibility of supporting operations for traversing its data.
  • An Iterator provides a common interface for traversing the items of an aggregate, allowing you to use polymorphism when writing code that makes use of the items of the aggregate.
  • We should strive to assign only one responsibility to each class.

The Hollywood Principle (Dont call us, we'll call you)

The Hollywood Principle (Don't call us, we'll call you)

Gives us a way to prevent dependency rot.
Dependency rot happens when you have high level components depending on low-level components depending on high-level components depending on side-way components depending on low-level components and so on.

With the Hollywood principle,  we allow low-level components to hook themselves into a system, but the high-level components determine when they are needed, and how. in other words, the high-level components give the low level components the "Don't call use, we'll call you" treatment.


The connection between the template design method and the Hollywood Principle is somewhat app-rant. Considering it is the abstract class (the higher level component) that calls the Subclasses implementations of its abstract methods.

Subclasses (low level components) never call abstract classes (high level components) without being called first.


Q: is a low level component disallowed from calling a method in a high-level component?

A Not really, IN, fact a low level component will often end up calling a member defined above in its inheritance hierarchy purely through inheritance. But we want to avoid creating explicit circular dependencies between the low-level component and the high-level ones.




Monday, 3 August 2015

The Template Method Pattern

The Template Method Pattern



Defined

The template method defines the skeleton of an algorithm within a method, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changes the algorithm structure.

The Template Method Defines steps of an algorithm and allows subclasses to provided the implementation of on or more steps.

Diagrams

Code Example

example of a normal template method

 example of a template method with a hook


A hook is a method that is declared in the abstract class, but only given an empty or default implementation. This gives subclasses the ability to "hook into" the algorithm at various points, if they wish; a subclass is also free to ignore the hook.


The use the hook, we override it in our subclass.

Bullet Points

  •  The "template method" defines the steps of an algorithm, deferring to subclasses for the implementation of those steps. 
  • The Template Method Patter gives us an important technique for code re-use.
  • The Template Methods abstract class may define concrete method, abstract methods and hooks.
  •  Abstract method are implemented by subclasses.
  • Hooks are methods that do nothing or default behavior in the abstract class, but may be overridden in subclasses. 
  • To prevent subclasses from changing the algorithm in the template method, declare the template method as final. 
  • The Hollywood Principle guides use to put decisions making in high-level modules that can decide how and when to call low level modules. 
  • You'll see lots of uses of the Template Method Pattern in real world code, but don't expect it all (like any Pattern) to be designed by the book. 
  • The Strategy and Template Method Patterns both encapsulate algorithms, one by inheritance and one by composition. 
  • The Factory Method is a specialization of Template Method.