Showing posts with label Design Pattern. Show all posts
Showing posts with label Design Pattern. Show all posts

Friday, August 5, 2016

SOLID Design Principles C#

In computer programming, SOLID (single responsibility, open-closed, Liskov substitution, interface segregation and dependency inversion) is a mnemonic acronym introduced by Michael Feathers for the "first five principles" named by Robert C. Martin in the early 2000s that stands for five basic principles of object-oriented programming and design. The intention is that these principles, when applied together, will make it more likely that a programmer will create a system that is easy to maintain and extend over time. The principles of SOLID are guidelines that can be applied while working on software to remove code smells by causing the programmer to refactor the software's source code until it is both legible and extensible. It is part of an overall strategy of agile and Adaptive Software Development.
SOLID are five basic principles which help to create good software architecture. SOLID is an acronym where:-
  1. SRP The Single Responsibility Principle: - a class should have one, and only one, reason to change.
  2. OCP The Open Closed Principle: - you should be able to extend a class's behavior, without modifying it.
  3. LSP The Liskov Substitution Principle: - derived classes must be substitutable for their base classes.
  4. ISP The Interface Segregation Principle: - make fine grained interfaces that are client specific.
  5. DIP The Dependency Inversion Principle - depend on abstractions not on concrete implementations.
1. Single Responsibility Principle (SRP)
The single responsibility principle states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. 
  • All its services should be narrowly aligned with that responsibility
As per SRP, there should not be more than one reason for a class to change, or a class should always handle single functionality. If you put more than one functionality in one Class in C# it introduce coupling between two functionality and even if you change one functionality there is chance you broke coupled functionality, which require another round of testing to avoid any surprise on production environment.

2. Open Closed Principle (OCP)
In object-oriented programming, the open/closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.

3. Liskov substitution principle (LSP)
The Liskov substitution principle (LSP) is a particular definition of a subtyping relation, called (strong) behavioral subtyping, that was initially introduced by Barbara Liskov in a 1987 conference keynote address entitled Data abstraction and hierarchy
  • if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program
In order to follow this principle we need to make sure that the subtypes respect the parent class.

4. Interface Segragation principle (ISP)
The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.
  • 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.
  • ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy.
ISP is one of the five SOLID principles of Object-Oriented Design, similar to the High Cohesion Principle of GRASP

5. Dependency Inversion principle (DIP)
The Dependency Inversion principle refers to a specific form of decoupling software modules. It states:
  • High-level modules should not depend on low-level modules. Both should depend on abstractions.
  • Abstractions should not depend on details. Details should depend on abstractions.
The Dependency Inversion principle (DIP) helps us to develop loosely couple code by ensuring that high-level modules depend on abstractions rather than concrete implementations of lower-level modules
 

Wednesday, April 20, 2016

Object Modeling

The goal in object modeling is to render a precise, concise, understandable object-oriented model, or "blueprint," of the system to be automated. This model will serve as an important tool for communication:
  • To the future users of the system that we are about to build, an object model communicates our understanding of the system requirements.
  • To the software development team, an object model communicates the structure and function of the software that needs to be built in order to satisfy those requirements. This benefits not only the software engineers themselves, but also the folks who are responsible for quality assurance, testing, and documentation.
  • Long after the application is operational, an object model lives on as a "schematic diagram" to help the myriad folks responsible for supporting and maintaining an application understand its structure and function.
The design of complex systems invariably changes during their construction, so care should be taken to keep the object model up-to-date as the system is built.
Modeling Methodology = Process + Notation + Tool
According to Webster's dictionary, a methodology is
    A set of systematic procedures used by a discipline (to achieve a particular desired outcome).
A modeling methodology, ideally involves three components:
  • A process: The "how to" steps for gathering the requirements and determining the abstraction to be modeled
  • A notation: A graphical "language" for communicating the model
  • A tool: An automated way of rendering the notation, typically in "drag-and-drop" fashion
Although these constitute the ideal components of a modeling methodology, they are not all of equal importance.
  • Adhering to a sound process is certainly critical.
  • However, we can sometimes get by with a narrative text description of an abstraction without having to resort to portraying it with formal graphical notation.
  • And, when we do choose to depict an abstraction formally via a graphical notation, it isn't mandatory that we use a specialized tool for doing so.
Object modeling tools fall under the general heading of Computer-Aided Software Engineering, or CASE, tools. CASE tools afford us with many advantages, but aren't without their drawbacks.

The Advantages of Using CASE Tools:
  • Ease of Use - CASE tools provide a quick drag-and-drop way to create visual models.
  • Added Information Content - CASE tools produce "intelligent" drawings that enforce the syntax rules of a particular notation. This is in contrast to a generic drawing package, which will pretty much let you draw whatever you like, whether it adheres to the notational syntax or not.
  • Automated Code Generation - Most CASE tools provide code generation capabilities, enabling you to transition from a diagram to skeletal C# (or other) code with the push of a button.
  • Project Management Aids - Many CASE tools provide some sort of version control, enabling you to maintain different generations of the same model.
  • Flexibility - Some CASE tools support multiple graphical notations, enabling you to initially create a diagram in one notation but to then convert the diagram to another notation quickly and effortlessly.

Some Drawbacks of CASE Tools:
  • CASE tools can be expensive; it's not unusual for a high-end CASE tool to cost hundreds or even thousands of dollars per "seat."
  • It's easy to get caught up with form over substance! This is true of any automated tool - even a word processor tends to lure people into spending more time on the cosmetics of a document than is warranted, long after the substantive content is rock solid.

Monday, November 30, 2015

SOA : Service-Oriented Architecture

What is Service-Oriented Architecture?
Service-Oriented Architecture (SOA) is an architectural style. Applications built using an SOA style deliver functionality as services that can be used or reused when building applications or integrating within the enterprise or trading partners. It is a method of design, deployment, and management of both applications and the software infrastructure where:
  • All software is organized into business services that are network accessible and executable.
  • Service interfaces are based on public standards for interoperability.
Key Characteristics of SOA
  • Uses open standards to integrate software assets as services
  • Standardizes interactions of services
  • Services become building blocks that form business flows
  • Services can be reused by other applications
  • Quality of service, security and performance are specified
  • Software infrastructure is responsible for managing
  • Services are catalogued and discoverable
  • Data are catalogued and discoverable
  • Protocols use only industry standards
What is an Enterprise Service Bus (ESB)?
  • An enterprise service bus is an infrastructure used for building compound applications
  • The enterprise service bus is the glue that holds the compound application together
  • The enterprise service bus is an emerging style for integrating enterprise applications in an implementation-independent fashion
  • An enterprise service bus can be thought of as an abstraction layer on top of an Enterprise Messaging System
Key Characteristics of an ESB
  • Streamlines development
  • Supports multiple binding strategies
  • Performs data transformation
  • Intelligent routing
  • Real time monitoring
  • Exception handling
  • Service security

Monday, February 9, 2015

CQRS (Command Query Responsibility Segregation) Pattern

Command–query separation (CQS) is a principle of imperative computer programming. It was devised by Bertrand Meyer. It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, methods should return a value only if they are referentially transparent and hence possess no side effects.

Command Query Responsibility Segregation (CQRS) applies the CQS principle by using separate Query and Command objects to retrieve and modify data, respectively. CQRS Pattern segregate operations that read data from operations that update data by using separate interfaces. This pattern can maximize performance, scalability, and security; support evolution of the system over time through higher flexibility; and prevent update commands from causing merge conflicts at the domain level.

CQRS is a pattern that segregates the operations that read data (Queries) from the operations that update data (Commands) by using separate interfaces. This implies that the data models used for querying and updates are different. The models can then be isolated, although this is not an absolute requirement.
Compared to the single model of the data that is inherent in CRUD-based systems, the use of separate query and update models for the data in CQRS-based systems considerably simplifies design and implementation.
The query model for reading data and the update model for writing data may access the same physical store, perhaps by using SQL views or by generating projections on the fly. However, it is common to separate the data into different physical stores to maximize performance, scalability, and security; as shown in Figure.
The read store can be a read-only replica of the write store, or the read and write stores may have a different structure altogether. Using multiple read-only replicas of the read store can considerably increase query performance and application UI responsiveness, especially in distributed scenarios where read-only replicas are located close to the application instances. Some database systems, such as SQL Server, provide additional features such as failover replicas to maximize availability. Separation of the read and write stores also allows each to be scaled appropriately to match the load.

When to Use this Pattern
This pattern is ideally suited to:
  • Collaborative domains where multiple operations are performed in parallel on the same data.
  • Use with task-based user interfaces (where users are guided through a complex process as a series of steps), with complex domain models, and for teams already familiar with domain-driven design (DDD) techniques.
  • Scenarios where performance of data reads must be fine-tuned separately from performance of data writes, especially when the read/write ratio is very high, and when horizontal scaling is required
  • Scenarios where one team of developers can focus on the complex domain model that is part of the write model, and another less experienced team can focus on the read model and the user interfaces.
  • Scenarios where the system is expected to evolve over time and may contain multiple versions of the model, or where business rules change regularly.
  • Integration with other systems, especially in combination with Event Sourcing, where the temporal failure of one subsystem should not affect the availability of the others.
This pattern might not be suitable in the following situations:
  • Where the domain or the business rules are simple.
  • Where a simple CRUD-style user interface and the related data access operations are sufficient.
  • For implementation across the whole system. There are specific components of an overall data management scenario where CQRS can be useful, but it can add considerable and often unnecessary complexity where it is not actually required.

Event Sourcing and CQRS
The CQRS pattern is often used in conjunction with the Event Sourcing pattern. CQRS-based systems use separate read and write data models, each tailored to relevant tasks and often located in physically separate stores. When used with Event Sourcing, the store of events is the write model, and this is the authoritative source of information. The read model of a CQRS-based system provides materialized views of the data, typically as highly denormalized views. These views are tailored to the interfaces and display requirements of the application, which helps to maximize both display and query performance.
Using the stream of events as the write store, rather than the actual data at a point in time, avoids update conflicts on a single aggregate and maximizes performance and scalability. The events can be used to asynchronously generate materialized views of the data that are used to populate the read store.
Because the event store is the authoritative source of information, it is possible to delete the materialized views and replay all past events to create a new representation of the current state when the system evolves, or when the read model must change. The materialized views are effectively a durable read-only cache of the data.