Software Architecture: Meta and SOLID Principles for C# Developers | Elias Spock | Skillshare

Playback Speed


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Software Architecture: Meta and SOLID Principles for C# Developers

teacher avatar Elias Spock, Chance favors the prepared mind.

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

61 Lessons (4h 53m)
    • 1. 00 Promo

      5:51
    • 2. 01 Outline

      2:17
    • 3. 02 SOLID Intro

      8:53
    • 4. 03 Problem Statement

      8:07
    • 5. 04 Demo of the Problem

      5:48
    • 6. 05 Refactoring to a Better Design

      2:19
    • 7. 06 More Examples of SRP Violations

      4:21
    • 8. 07 SRP Related Patterns

      5:19
    • 9. 08 Conclusion

      2:20
    • 10. 01 Outline

      2:17
    • 11. 02 OCP Definition

      8:06
    • 12. 03 Demo of the Problem

      6:50
    • 13. 04 Refactoring to a Better Design

      2:59
    • 14. 05 OCP Related Patterns

      10:43
    • 15. 06 Common Smells of OCP Violation

      1:30
    • 16. 07 Conclusion

      1:55
    • 17. 01 Outline

      2:17
    • 18. 02 LSP Definition

      3:52
    • 19. 03 Contracts

      6:59
    • 20. 04 Demo of the Problem

      5:48
    • 21. 05 Refactoring to a Better Design

      2:19
    • 22. 06 More Examples of LSP Violations

      6:10
    • 23. 07 Common Smells of LSP Violation

      2:06
    • 24. 08 Conclusion

      2:20
    • 25. 01 Outline

      2:17
    • 26. 02 ISP Definition

      4:51
    • 27. 03 Demo of the Problem

      6:50
    • 28. 04 Refactoring to a Better Design

      2:59
    • 29. 05 Demo of the Problem

      5:50
    • 30. 06 Refactoring to a Better Design

      1:51
    • 31. 07 Common Smells, Fixes, and Related Patterns

      7:38
    • 32. 08 Conclusion

      2:20
    • 33. 01 Outline

      2:17
    • 34. 02 DIP Definition

      3:30
    • 35. 03 Dependencies 01

      4:12
    • 36. 04 Volatile and Stable Dependencies

      2:53
    • 37. 05 IoC and DI Definitions

      3:18
    • 38. 06 DIP Violation Demo

      2:25
    • 39. 07 Refactoring to a Better Design Applying Dependency Injection

      8:12
    • 40. 08 DI Techniques

      5:54
    • 41. 09 Architectural Implications

      5:24
    • 42. 10 Pure DI and IoC Containers

      4:31
    • 43. 11 Building a Simple IoC Container

      3:55
    • 44. 12 Demo of a Real World App Built with an IoC Container

      10:27
    • 45. 13 Common Smells of DIP Violations

      2:11
    • 46. 14 Conclusion

      2:15
    • 47. 01 Outline

      2:17
    • 48. 02 DRY

      9:50
    • 49. 03 KISS

      7:37
    • 50. 04 YAGNI

      11:42
    • 51. 05 SoC

      4:28
    • 52. 06 CQS

      2:14
    • 53. 07 Law of Demeter

      7:01
    • 54. 08 PoLA

      3:03
    • 55. 09 Encapsulation

      5:58
    • 56. 10 API

      14:28
    • 57. 11 SOLID VS YAGNI

      2:58
    • 58. 12 OCP VS YAGNI

      2:48
    • 59. 13 SRP and ISP

      1:47
    • 60. 14 Architecture and Design

      4:56
    • 61. 15 Conclusion

      4:23
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

278

Students

--

Projects

About This Class

Teaching Approach

No fluff, no ranting, no beating the air. I esteem your time. The course material is succinct, yet comprehensive. All important concepts are covered. Particularly important topics are covered in-depth. For absolute beginners, I offer my help on Skype absolutely free, if requested.

Take this course, and you will be satisfied!

SOLID is an acronym which stands for SRP, OCP, LSP, ISP and DIP. These five acronyms in their turn stand for:

  • Single Responsibility Principle
  • Open/Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

In this course, you’ll learn how to apply meta and SOLID principles so that your application will live a long healthy life. It means you are going to learn how to write code of the high quality: readable, understandable and reliable.

Improve your knowledge in object-oriented programming

  • Understand the meta principles on which all the other development principles are based
  • Understand the symptoms of code defects
  • Learn the foundations of SOLID principles
  • Learn how to detect the violations of SOLID principles and how to fix the problems
  • Learn how meta principles and SOLID principles are related to each other and how to find the balance between them    

Foundations of writing object-oriented code

Despite the fact that C# is a very rich on features language, it's very common to see poorly designed and implemented applications in a real world. Language by itself does not guarantee that the architecture of an application will be great. In order to design and build maintainable software, we need to understand the principles of software development. This video course is exactly about how to achieve clean and maintainable software.

You probably have already heard the following well-known statement: most code sucks. Well, this course is all about how to produce code which doesn't suck.

Owning skills of producing a well-designed and well-implemented types is the prerequisite for the other developers to treat you as a decent professional.

Content and Overview

This course is aimed at middle and senior developers. Solid experience in C# is required.

There are plenty of code examples throughout this course so that you will learn both theoretical and practical material.

Starting with SOLID principles we will go further to the meta-principles. Going through the SOLID principles, you’ll also learn about the related patterns. Then we will get to the problem of contradictions between different principles. You’ll learn about the relationships between SOLID principles and meta principles.

In general, you’ll learn in this course:

  • SRP
  • OCP
  • LSP
  • ISP
  • DIP

These are the SOLID principles. You’ll learn the background problems that can be solved by particular principle, you’ll see the demonstrations in code, you’ll learn the related patterns to every principle.

Learning DIP you’ll in addition learn what is Dependency Injection, Inversion of Control, IoC-Containers and what are the architectural implications of DI.

Here are other topics you’ll learn in the course:

  • DRY – don’t repeat yourself
  • KISS – keep it simple stupid
  • YAGNI – You Ain’t Gonna Need It
  • SoC – separation of concerns
  • CQS – command query separation
  • Law of Demeter
  • Principle of Least Astonishment
  • Information Hiding and Encapsulation
  • API Development Principles
  • Contradiction between SOLID and YAGNI
  • Contradiction between OCP and YAGNI
  • What is Architecture and Design

How long is this course: The course is around 4.5 hours. All are video lectures. You will be able to download all the slides and code samples used in the course.

------------------------------------------------------------

Keywords related to the course:

  • Software Architecture
  • Software Design
  • SOLID Principles
  • SRP, OCP, LSP, ISP, DIP

Meet Your Teacher

Teacher Profile Image

Elias Spock

Chance favors the prepared mind.

Teacher

I'm thankful enough for that I love what I do.
I began my career as a postgraduate student participating in Microsoft ImagineCup contest.
I've been working with .NET platform since 2003. I've been professionally architecting and implementing software for nearly 7 years, primarily based on the .NET platform. I'm passionate about building rich and powerful applications using modern technologies. 
I'm a certified specialist in Windows Applications and Service Communication Applications by Microsoft.
I'm one of the coordinators of the MSK.NET User Group in Moscow.

"If it's work, we try to do less. If it's art, we try to do more." - Seth Godin.

What I can say is that software is my art.

See full profile

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. 00 Promo: Hi. Welcome to the course software, architectures, matter and solid principles. I'm Let's put a K injury spark from injures park dot com, and they'll be letting you for the course. I began my career. A supposed graded Students participating in Microsoft Imagine Cop contest. I've been working with Dr Left since 2003. I've been a professional architect on implementing software for nearly seven years, primarily based on the DOT net platform. I am passionate about building reach and powerful applications using modern technologies. I'm a certified specialist in Windows applications on service communication applications by Microsoft. And here is my teaching approach. No plot, no ranting, no beating the air ice team your time. The course material is 16 yet comprehensive. Full important constants are covered. Particularly important. Topics are covered in depth for absolute beginners. I offered my help on Skype absolutely free if requested. Take this course and you'll be set his five. Solar is an acronym, which stands for S R. P o c p, L S P and D E F e. Another five Konitz These five crimes in their turn stand for single responsibility principle. Open closed Principal Lisk of substitution Principle in tow. Face segregation principle and dependency. Invert inference. In these courts, you learn how to fly solid and meta principles so that your application will live a long, healthy alive. It means you're going to learn how to write code of high quality, readable on the standard and reliable. Improve your knowledge in object oriented programs. Understand them at the principles on which, on the other development principal start based. I understand the symptoms of gold defects. Learned foundations of solid principles. Learn how to detect violations of solid principles and how to fix the problems. Learn how meta principles and Sony principles are related to each other and how to find the balance between. Despite the fact that See Shop is a very region features language, it's very common to see poorly designed and implemented applications in the real world. Programming language by itself does not guarantee that the architectural applications will be great. In order to design and build maintainable software, we need to understand the principles off software development. The video, of course, is exactly about how to achieve clean and maintainable software you probably have already hurt with following world known statement. Most go Sox well, its course is all about how to produce code, which doesn't suck. Voting excuse of producing and well designed and well implemented times is the prerequisite for the other developers to treat you as a decent professional. This course is aimed at middle and senior developers. Off course. Some experience. See shop is required. If you're a junior programmer, then I would say that you have to have a least health of the Year of Real World Experience in enterprise development. If you don't know how to work in visual studio, this course is not for you. Yet. There are plenty of good examples throughout discourse so that you learn both radical practical material. Starting with solid business. We will go further to the matter. Prince going through the solid brings. You'll also learn about the related matters. Then we will get to the problem off contradictions between different principles. You learn about the relationships between solar prints on metal prints in general, you learning this course five solid principle srp gossipy L S P. I speak day. These are the solid principles. You'll learn the background problems that can be solved by particular principle. You'll see the demonstrations in code, you learn they relate presence to every principle learning that being you in addition learned what is dependency injection inversion of control. I see containers how to build a simple RC container. And what are the architectural implications of dependence injection? Here are the other topics you learned in this course Dry. Don't repeat yourself. Principal keeps principal. Keep it simple. Stupid yard New principal U N gonna needed sock principal Separation of concerns Sick U. S. Command query separation principles the law off the meter and for principle of list astonishment, information hiding and encapsulation AP I Development Bring suppose contradictions between solid and Yarden contradictions between OCP and young What is architecture and design you'll get tones are very important to know information in role and start learning the solid and metal principles of building software systems. 2. 01 Outline: Hi. This is the last for fun of baking engineer spot. And in this section, we're going to learn where the principles are. We refer to the principles we're going to talk about in this section as to matter principles because they are the roots off all the other more concrete principles adhering to which we're actually trying to conform with the matter principles. We will start from the dryer. Don't repeat yourself principle. You learn the definition of the most common smells of violating the dry principle. After that, you learned the keys or keep it simple. Stupid principle. Here we're going to talk about simplicity and complexity, accidental and essential complexity and how to achieve simplicity. The next meta principle we're going to talk about is the young me or you ain't gonna need it principle. It is related to the needless complexity smell and concerns the anticipations off common features. We will look into practical problems which we face and what other consequences off implementing features we actually don't need. After that, we're going to talk about the sock or separation of concerns principle. This principle underlies incense. All the solid principles. Separation of concerns is very important for achieving well maintainable applications. You'll see the most common ways of violating the separation of concerns. Principle Command query separation principle makes easier to reason about. The code will discuss the low of Demeter, which is the principal off list knowledge. Separately, we will talk about the principle off least astonishment you. Then we will touch the topic of information hiding and encapsulation. By the way, I will use the word principle instead of matter principle in this section. Further, just for the sake of saving some time in the next lecture, you learn about the dry principle. Let's get started. 3. 02 SOLID Intro: Hi, This is Engineer Spark, and I will be leading you through the course before investigating what the solid principles are and how to apply them properly. We need to understand why do we need them at all? So that principals are all about designing software but what is designed? How to define the Design off software? Robert C. Martin, in his book A Child Principles, Patterns and Practices in C Shop, stated that the design off software is source code itself. Modern Folder wrote in his blawg that architecture is the shape which go takes. Why is this so engineers produce documents, blueprints which specify how to build a product. The only thing which truly specifies how software works is the source code. You may say that source code is the product, but the product is the running program, not the source code itself. Look at this from the following perspective. What is the input to factory off circuit boards? Special electronics diagrams in the case off software development for Have a Factory, which is gold compiler, we feed it by the source code. A compiler builds software using the source code, and this leads to interesting thoughts regarding costs, model off building software and, say houses. When we build a house, it's much cheaper to create a good design up front rather than rebuild an entire house. If we don't like the result, it's just not feasible to rebuild a house each time. We don't like the result. The opposite we can say about software development. We can build bine Aries in a minute. Roughly speaking, big upfront design in case off software development is much more expensive than to draw a sketch, build the software and then tweak it along the way. The software development process is somewhat unique because conducting a big upfront design , we actually can't guarantee that we take into account all the possible requirements. The software is the fluid substance, and requirements tend to change very quickly because off such a fluid, uncertain nature off software requirements, we need to constantly keep the design as clean as we can, saying clean. I mean this maintainable as we can to determine where the source code is clean or not, we need to mark out of the science of designer rotting developers refer to such science. That's design smells. We can mark out five major design, smells, rigidity, French il ity, immobility, viscosity and needless complexity. Let's define them one by one. The software is region. If the cost of making a single change is very high, if something very simple takes many hours to implement than the software is region. To overcome this problem, you might need to redesign the software. The primary source off rigidity is the high coupling between modules. When modules are tightly coupled, then it's very hard to introduce any changes with ease. The softer is fragile when small changes in one module cause box appearance in other, sometimes even unrelated modules. The smell is also often caused by poorly designed relationships between modules, toe overcome fragility. You need toe isolate dependencies. The software is in model when its components cannot be reused in other systems. Most of the time, we should be able to extract a component without too many efforts and adapt for using in another system and what is surprised? The smell is most likely caused by tight coupling between components. To overcome this smell, you need to decouple components well. The softer is viscous when adding a single feature evokes dealing with tons of aspects, including say transport, layer, security marshalling and such things. In practice, you also can detect the smell by observing heart to perform chickens, checkouts and merges. And most likely, the primary reason for the smell is tight coupling between components. The softer is needlessly complex when developers all the time are trying to forecast the future. Anticipating upcoming changes, introducing excessive points of extension developers should concentrate on the current requirements. They should construct the supple architecture which can band to be able to meet new requirements. Heading not needed. Points off extension yet is a bad practice which leads to any of those complexity. Did you notice that almost all the smells are related to bed dependencies Management. The major difference between object oriented and not object oriented languages is that other languages are capable off harnessing the power off dynamic dispatch By using virtual functions and interfaces, we can invert the dependencies in o languages. When we make a call, we don't know which object will handle that call. This is because of polymorphism or dynamic dispatch. So the key to achieving a good architecture is to manage the dependencies well. And here we reach the point when we are ready to talk about solid principles. Solid principles are five principles which can be referred to as dependency management principles. There are all about relationships and operations between objects. In this volume, we're going to dive deeply into the solid principles. The solid acronym was first introduced by Robert Martin. A k uncle Bought Solid implies five principles off software development, SRP Single responsibility principle. Also be open. Closed principle ls be risk of substitution principle. I speak into face segregation principle and the i p dependency inversion principle. Menu of this principles are based on the classic work of Bertrand Meyer. We're going to discuss all the principles one by one, looking at examples off poor design and how to fix it. Applying an appropriate principle. We will also notice the difference between Myers and Martin's definitions off some principles. What is also important for deep understanding? What I also want to emphasize is that solid principles are not bound to any technology. You can apply them in any programming language in job of for example. Another point is that solid is not a goal by itself. The thing is that fully solid code is an oxymoron. It's impossible to write software, which confirms solid in every single line. It's impossible to measure the solid nous off the code base. Solid are the five principles which help us to create better software. They involve a great deal of philosophy, and you might think that this is bad. Well, you can treat it as a floor, but actually it's not. It's very important to feel this philosophy of designing softer to become a better developer. And in this course you'll see all the trade offs developers face applying solid principles . You'll feel the philosophy of designing software. Okay, you have learned the common design smells and that we apply solid principles to remove that smells. In the next lecture, we'll dive into solid principles, starting with outline off the SRP section. 4. 03 Problem Statement: the single responsibility principle or a Sarpy in short states that every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. This definition is taken from Wikipedia. It's very hard to understand. What does it mean? For example, the 1st 2 questions which come to my mind are how to define those responsibilities and how to calculate the number off responsibilities off a certain class. Such definitions are not very helpful from the practical perspective. Robert Martin, a key Uncle Bob, clarified this definition by saying that there should never be more than one reason for a class to change. Sounds much clearer, though it's too needs further clarification. The responsibilities of a class can be treated as access off change. It might be simpler to understand it as access off changing requirements, for example, in the class implements, logging and cashing on its own. Then it has at least two responsibilities. We also can view the responsibilities of a class from the perspective off its users any a p I has its users. These users are the source of changes, understanding that we can calculate how many excess off change a glass has. For example, if the class deals with a database, then we have one x of changes since DB Architect's are those users who can request changes . If that glass deals with celery reports as well, then you have to excess scenes. Accountants are those who can request changes to reports. Apparently the more responsibilities a class has, the more likely is going to be changed. So applying the SRB, we want to separate different concerns. A class should do one thing and do it well. By the way, the same principle can be applied at the level of modules. Modules should have only one logical responsibility, so the SRP can be applied at different levels at the functional level, object level and at the module level. Sometimes we find SRP violations at functions level were a factor out different responsibilities to glasses, and then we separate glasses by their responsibilities into different modules or a semblance. If you wish we discussed the SRP, but you might wonder how the concrete problem look like in real life caused by the SRP violation. Imagine the problems which are caused by the SRP violation. Here we have a class. Look at it how many responsibilities does it have? I see at least four dependencies. Let's count them. The very first method, called charge, is responsible for interacting with the bank terminal. It should know how to initialize a device properly and send a corresponding command to it. The next method gold Create Report knows how to grate a report about the payment transaction. It knows how to format all the day to properly. Reports are usually so complex that there are two responsibilities may be hidden. One separate concern could be the process of creating airport, and the second is the formatting itself. If the process of creating an object is too complex, then very often we treated as a separate concern and we turned toe isolate such responsibilities by extracting affect er class, which knows all the details about reports creation. The third method, called Brings Report, knows how to deal with printers driver and how to send commands to it. And finally, the safe payment method is responsible for interacting with a database. To save all the data about a payment transaction, we often have a hidden responsibility. In such cases, we can call that responsibility orchestration. We often need some high level object, which knows how to integrate all the responsibilities together. Now imagine that we need to change the payment, processing and saving to a database simultaneously. Two different programmers are responsible for these two different parts of the system. Unfortunately, these two different parts recite in the same class. As a result, these two programmers need to change the same class, and in then they will need to merge their changes to finish a check in. Aside from this problem, such glasses, which a camel? Eight many responsibilities are hard to understand. Such glasses become a big ball of mud. One day no one will understand what the hell is going on that glass. Another problem is that sometimes we need to introduce changes into only one responsibility . Let's say we need to change the payment processing because several responsibilities re side in the single object classes which represent them will also very compiled and redeployed. Nowadays, this problem in the majority of cases may seem like not a problem at all. But for example, if we develop in C plus plus, then it can cause some issues. In the end. The thing is that such careless attitude to dependencies management leads to a long compilation Time C plus plus is much harder to compile, so this problem is very important In such cases. If we had isolated these dependencies in different modules, we would have needed to re compile under redeploy only one module, the module, which has been changed so went as harpies violated responsibilities. Start to KAL eight with each other. What means that they become coupled? What we need to strive to do is to gather all the same responsibilities together and separate from each other, those which are different. When we gather the same responsibilities, we try to achieve the so called high cohesion. When we separate different responsibilities, we try to achieve low coupling at the level of functions. Cohesion means the following a set of functions and into face is considered cohesive. When each function is closely related to another, coupling indicates how dependent modules are on the inner workings off each other. Tightly coupled modules rely extensively on the specific state off each other, sharing variables and many types. Loosely coupled modules are fairly independent. They have a few well named AP eyes and share a limited amount off or no data at all. Okay, let's look at the problem off a Sarpy violation in visual Studio on another example. 5. 04 Demo of the Problem: this lecture is titled Ellis Be Violation Demo. Let's consider a classic example of Phyllis P. Violation. I love this example because of two reasons. The 1st 1 is that it actually demonstrates the L S P violation, and this reason is obvious. And the second reason is that it shows that object oriented programming often can directly map the relationships between objects in the real world into the same model off relationships between them in code. A great number of developers think that writing code in Hopi language, they're modeling aerial world domain problems. And partly this is true. But the real world relationships between objects sometimes can be motile directly in Opie language. Here's one of the naive hopey statements child glasses. Implement is a relationship with based classes. 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 are inheritors. Unfortunately, sometimes this kind of design doesn't work as expected, and you'll see this in a minute. So let's reflect the relationships between two riel 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 off rectangle . It's others because square is a rectangle with equal sides. Okay, let's switch to visual studio. Let's create a rectangle and square. I created the rectangle class, which has two properties with and height, and the square, which inherits from their tangle class. Separately, I'll create the class, which is responsible for calculating areas of that shapes. Looks fine. From the first side. 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 that first, I'll just create a rectangle with with equals two and hide equals five. After that, I'll call the ST IC Cal correct angle method and get the result, and I also send the result to the console. Now I want to create a square. Wait a minute. What the hell is this? How a square can contain sides of different length. I'm not even going to run the program, since it's obvious that something is wrong here with a pile of square square allows to set different length to width and height. This design clearly violates the list of substitution. Principal square is not substitute hable for rectangle rectangle implements the in variant , which states that width and height could be off. Different Land Square has to implement another in variant 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. 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 era, such a method could look like this. This method checks the type of the accepted parameter and run the appropriate calculation algorithm. What do you think? Is it a good way to define methods all over the code base which have to work with rectangles? Doesn't it resemble you something we've seen previously? Yes, indeed, this is a violation of the open close principle. This method is open for modification. What will happen if we introduce a new shape? Correct. We'll have to modify. That's which statement this example of Gillespie violation is a hidden violation off OCP. In the next lecture, we will look at how to fix this problem 6. 05 Refactoring to a Better Design: Obviously we need to make impossible setting different length offsides for a square to fix the problem. For now, the expectations of the squares clients are broken. The air, a calculator class now demonstrate that there is a problem off separated data and behavior . The calculation algorithms are separated from the rectangle and square glasses, which own the data required for calculations. The area calculator 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 disease, where always should construct proper abstractions. What we want to obstruct away is the business logic of calculating the area. Each shape has its own algorithm off calculation. The area. It is much better to make behavior shared rather than data. Let's obstruct away the calculate area method by introducing the I shaped interface. I want the rectangle and square to inherit from the eye shape. Implementing their own algorithms, Square now defines its own property named side length. Now a client can't misuse. It's a P I. Here's an example of a client in case of rectangle calling to calculate area, A client will give the area off a rectangle, while in case of square, a client will get the area of a square. The client can set different length, off width and height to a square. Great. In the next lecture, we will look at other ways off ls be violation. 7. 06 More Examples of SRP Violations: here we have a method named Get Reppert in the body. We can see that it gathers some statistical data, then creates formatted strings and put them together. How do you think? Does this method violate SRP? With this method clearly violates the SRP. It has two responsibilities. The 1st 1 gathering the statistical data and the 2nd 1 is formatting. Junior programmers very often makes the formatting responsibility with business logic off course. Sometimes if we're sure for 99% that formatting will never be changed and it doesn't interfere with the other cold. We can leave such code s cities, but more likely it would be better to at least extract formatting into a separate method. Let's look at another case. Here we have the find alarm device. It scans through serial ports trying to find the device. And if it finds it, it sets a global state by setting the alarm can be used property. How do you think? Does this method violate the SRP? But this method clearly violates the SRP. It makes is that the policy or business logic with mechanics remember that high level policy should be decoupled from the low level details we could re factor it by introducing a special class which is responsible for interacting with global state. That glass could receive notifications by events or any other appropriate way. Let's look at the next case. Here we have the method named draw Rectangle. It calculates where to draw a rectangle, then picks a cooler and draws the rectangle feeling it with that color. How do you think? Does this method violate the SRP? This case is trickier than previous ones. The previous examples demonstrate very popular smells of violating the SRP. It's harder to determine their responsibilities here. The number of factual responsibilities always depend on the users, other actors or users who might be interested in managing the color. If there are such users, then it might be better to separate the responsibility off picking a caller. A separate interesting question is whether the creation often object is itself a responsibility or not. We're not going to answer this question in this section. We will keep it for the section about D. I. P. In the end, I also want to least some common SRP violations first, mixing logic and infrastructure when business logic is mixed with views or a persistence. Layer a glass or a module, serves different layers, calculates income and sends emails, Bar says XML and analyze the results before going further. I just want to skim through one function I faced in practice. This function is about 5000 lines long. It consists off switch case, and if statements, it relies on them massively. This is a really hell andan extreme example. Off SRP violation. I wanted to show you this example just for fun. The majority off developers don't believe me when I say that I've seen such a function. No such functions exist, and developers who write such functions also exist. As you may guess, in the next lecture, I want to say a couple of words regarding designed patterns related to the SRP. 8. 07 SRP Related Patterns: Sometimes we apply the SRP to reflector apart off a system, and we end up with many small classes. Clients off such an A p. I may struggle with understanding the whole part of the system because they need to understand their relationships between all that smoke glasses. It's not that bad as it sounds. As I've already said, there is always a trade off between different solutions in such cases. Therefore, sock pattern may come to the rescue. It wraps all those little glasses, just delegating all the responsibilities to them. It doesn't make the facade a violator off the SRP. The only responsibility off such a facade is to bring the functionality required by client together. It may seem like it violates this R P, since we will see the responsibilities off different layers reflected in the FBI off the facade. But as I said, aggregating the functionality which allows solving a single clients problem is not bad. It simplifies the interaction process with the system from the client's perspective, and that's all. Nothing more so. There are two million reasons for using the facade. Better provide for a client, a simple A p I for interaction with a set of complex objects and provide for a client a cleaner FBI for interaction with poorly designed A P I. Sometimes it's much easier to roll out if Assad, rather than a rewrite a poorly designed part off a system. And this is what the second point is about from the SRP is prospect. We're interested in the example, which demonstrates the first reason off using the facade better. Here you can see a diagram, which demonstrates an example of the facade. Better. You can see here that the purchase facade class depends on all the other classes it contains or, in other words, wraps all these classes. The wrapped entities don't have to be classes. They could be interfaces as well. So imagine that initially a client was dependent on all these glasses. We introduced the facade to simplify the indirection process with the system. If a client depends on the on the facade, it doesn't have to directly interact with many classes. Let's switch to visual studio, where I'll show this example in code. Here is an example. Let's say we have a client which uses our system to sell goods from the store online, so the clients code looks like this. It creates a customer object using the ST Ick method. Find customer passing mean the customer i d. After that, it creates a load through the state IQ. Find method off the stock class, passing in the good i D. Then it gets the info about the customer's credit card, creates the bank gateway and calls the charge card passing required parameters. I bet such indirection process looks like a mockery indeed. It's our duty to simply file lives off our clients so we can create a facade which hides all these details off processing a purchase I created here. The Purchase facade class, which exposes a single method. This method requires two integer parameters and hides all the details inside its body. Now a client doesn't have to know about all the glasses and how to interact with them, which methods to call. The only thing the client should know is that it can just great if Assad and called one method to achieve the goal. That's all. There are many patterns which are related to a Sarpy decorator and composite bedrooms are also very closely related to their Sarpy, according to the definition from the Gang of Four book composite pattern allows to compose objects into tree structures to represent part whole hierarchies. Composite patron. Let's glance. Treat individual objects and compositions off objects uniformly. According to the same book. The decorator pattern allows the behavior to be added to an individual object, either statically or dynamically, without affecting the behaviour off other objects from the same class. The decorator pattern is often useful for adhering to the single responsibility principle as it allows functionality to be divided between classes with unique areas of concern. We're not going to discuss design presence in this course deeply, so I can just recommend you some sources to look it to get a deeper understanding of design veterans and their relationship to solid principles. 9. 08 Conclusion: this lecture is titled Conclusion. The principal we discussed throughout this section was the interface segregation prince or I speak in shirt, there s P has a simple definition. Clients should not be forced to depend on methods they do not use. So these definition implies that you have to strive to great, small, cohesive and focused interfaces. Off course, different clients can use only a subset off FBI members they depend upon. Unless that AP, I start to grow transforming into a very fat interface with unrelated members to each other , where, when similar but different methods appear to satisfy the requirements of different clients . A typical way of violation you saw, was when an interface was too broad. What led to some smells like implementer throw not implemented exception or clients have to see all the mass in the intelligence thinking off what they actually need to use as we discussed, there are several ways of dealing with I speak violations. Sometimes it is just enough to extract a separate interface from a fat one and use it where appropriate. Sometimes you need to come out with a facade which hides irrelevant. Ap I members. Sometimes you need to apply an adapter pattern, especially if you don't own the fat interface, and thus you cant modify its source code. The intelligent adhering to the interface segregation principle makes an application easier to maintain what is extremely valuable, especially in the long term. Abusing I speak you can end up with tones. Off to small interface is what makes them harder to use by old clients. This is a smell known as anti ice. Be so we reached the end of this section. That was an interesting investigation. But there is another principle waiting for us the dependency inversion principle. The next section is dedicated to the D. I. P. Let's get straight to business. 10. 01 Outline: Hi. This is the last for fun of baking engineer spot. And in this section, we're going to learn where the principles are. We refer to the principles we're going to talk about in this section as to matter principles because they are the roots off all the other more concrete principles adhering to which we're actually trying to conform with the matter principles. We will start from the dryer. Don't repeat yourself principle. You learn the definition of the most common smells of violating the dry principle. After that, you learned the keys or keep it simple. Stupid principle. Here we're going to talk about simplicity and complexity, accidental and essential complexity and how to achieve simplicity. The next meta principle we're going to talk about is the young me or you ain't gonna need it principle. It is related to the needless complexity smell and concerns the anticipations off common features. We will look into practical problems which we face and what other consequences off implementing features we actually don't need. After that, we're going to talk about the sock or separation of concerns principle. This principle underlies incense. All the solid principles. Separation of concerns is very important for achieving well maintainable applications. You'll see the most common ways of violating the separation of concerns. Principle Command query separation principle makes easier to reason about. The code will discuss the low of Demeter, which is the principal off list knowledge. Separately, we will talk about the principle off least astonishment you. Then we will touch the topic of information hiding and encapsulation. By the way, I will use the word principle instead of matter principle in this section. Further, just for the sake of saving some time in the next lecture, you learn about the dry principle. Let's get started. 11. 02 OCP Definition: this lecture is titled Problem Statement. The second principle we're going to talk about is the open close principle. If we look at Wikipedia, we will see the following definition. The open close principle states that software entities, glasses, modules, functions etcetera should be open for extension but closed for modification. What it means, in essence, is that when we need to introduce a change, we shouldn't dig deep into the system and change its behavior. By changing those ends of classes, we should be able to introduce a change by adding you code not by changing the existing such software, which allows changes by introducing new classes rather than by changing the existing source code is open for extension and closed for modification. How to change behavior without changing the code base. The answer is simple. Dynamic dispatch or pollen. More fees we can achieve very supple, designed by harnessing the power off object oriented programming. In practice, it means that we need to rely on abstractions rather than on concrete or direct implementations, even see shop. We would rely on into faces and abstract glasses. OK, but what is the problem with changing existing code? Why do we need to adhere to the open, close principle at all. The first reason is that there is a high chance off introducing box during the modification process. It's much easier to enter. Use a bug, modifying something that is complex and already exists. Plan to introduce a bug heading new code. The second reason is irrelevant, and it is almost always relevant when you're trying to modify the behavior of an FBI, which is already in used by many clients. The first danger here used to change the behavior expected by clients. Imagine that there are 1000 clients of a method which returns 100 in the case of failure and that clients have some compensation logic for that case. Imagine, then that you modified the behavior of the method upon which of those 1000 clients depend. The consequences are dramatic. I would pray for the developer who decided to introduce such a change, which breaks the code off 1000 clients. The second danger is to modify the FBI signatures. Such modifications immediately break all the dependent clients. Believe me, clients will not thank you for such modifications. By the way, breaking changes may also cause ripple effects because there can exist hundreds off clients which depend on other clients which depend on your code. Modifying the behaviour by eating you code is actually conforms to what customers think when they ask for new features. When customers ask for a new feature, they think that features will be added. They don't think that developers will modify anything. The idea might seem ridiculous from the first sight. Indeed. Is that possible to write Go that will never be modified again? Off course. This is not possible in practice. Well, theoretically, it's possible to write all the code in this way, but it's not practical in programming. We often set some ideal goals which can be ever achieved, for example, who strive to write correct Golden. Theoretically, we can write code that correctness off, which can be statically verified. Unfortunately, in 99% of cases, such development process is so expensive that I want is capped bull off investing so much money, another point, which is obvious. But I need to mention it's that we absolutely must modify the existing code if it contains a bug. So back fixing is okay from the open close principle point of view. Let's take a step back and look into 1988 1988 is the year when Bertrand Meyer described OCP for the first time, Meyer treated OCP a little bit differently than Uncle Bob. OCP from Marius Point of View, was essential, an equivalent to the protected variation pattern. The protective variation pattern means the following identify points off predicted variation and create a stable interface around them. Talking here about an interface we don't need the C shop into face construct. Ending to Face implies any P. I. A Class has its own interface, which is represented by its public. A P I. We can notice here a subtle difference between the Mars and Martin's definitions. Myers definition is more about backward compatibility at the A P R level. So if changes don't break the backward compatibility, though, sippy is Matt. When exactly may we need to change the behavior of changing the interface. For example, when a new client appears, which requires very similar but a little bit different behavior, the last point I want to address is the single choice principle closely related to the open close principle. I prefer to name this principle the single source principle and you understand why shortly , Let's imagine the case when we need to decide which implementer to create. Depending on an argument for solving such problems, we often rely on the factory better. Here's an example. As you see here, we have a factor method which takes a parameter off banter. Nall model in admiration. Depending on that parameter, the factor method creates a corresponding implementation off the I ban terminal interface. Does this factor method violate the open close principle? Off course it does. If we roll out a new implementation off the eye bank terminal interface, we will modify this gold by adding in UK statement, How can we solve the problem? Adhering to the open close principle, we can create a factory of the bank terminal factory but who create that factor of this factory somewhere. In the end, we need to select the appropriate implementation and create the instance. We can partly solve the problem by introducing an icy container, but this will just move the problem. It doesn't solve the problem entirely if you're not familiar with the notion of dependency injection and I've see containers as a side note, I'd recommend you to books. The 1st 1 is from the Back Bob Library, which is named Mastering Inject for Dependency Injection and another one which is an absolute bestseller written by Mark Semen Dependency Injection in dot net. So the principal off single choice sounds like this. Whenever software system must support a set off alternatives, one and only one module in the system should know their exhaustive list. Yes, we're violating those sippy by having such an implementation of the factor method. But there is no meaning to try to push the gossipy further by any means. We should understand that in such cases, all we need is to isolate such a responsibility in a single module, and only that module should be changed in case of introducing new implementations. Okay, let's look at the problem off gossipy violation and how to fix it in our beloved visual studio. 12. 03 Demo of the Problem: this lecture is titled Ice Be Violation Dama one. I Want to Show You Ariel Case from my practice, which was related to the problem off into face segregation. I've been working with devices a lot, and once I faced the following case before granting, I want to say that I like to give examples to students which reflect the whole picture of aerial 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. So on the top level we have a monolithic WBF application, which works on point off service 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 pass terminals, so all of them had to be supported. The interpretation with bank terminals is not direct. Ban terminal producers provide their own applications through which our application can work with their bank terminals. Their applications are implemented as come servers. If you don't know what is a com server just think off it as a stand alone executable service. The diagram reflects the flow of operations. Let's look at code. There is the bare minimum off operations, which are supported by any possible bank terminal. That's why I defined the Eye Bank terminal interface, which reflects the B I provided by services which Inter operate with bank terminals directly. Now I have three implementations off the eye bank terminal interface, Zap Terminal, his own terminal and PDQ terminal. I am entered the rial implementation, since it would complicate the example too much. And there is no meaning to show you the guts and low level details. And now I'll describe the problem which arose. The thing is that bank terminals are different. The some terminal is a black box solution which physically is a box which on its own works with credit card arrears. Great ID card readers are those devices which accept your card, read the cheap or a magnetic stripe and dispense back card back to you. So his own terminal doesn't expose guy for Inter operating with card readers because the service application automatically sets old and accessory things up At the same time, the other two bank terminals, PDQ Terminal and Zap Terminal don't take responsibility for Inter parading with card readers automatically. On the contrary, they delegate this responsibility to a client, exposing a P I for inter parading with card readers. So in the first case, our application doesn't need to do anything at all. While in the other two cases are application has to show a window to post terminal maintenance engineers to provide the ability to set up the bank terminal devices properly. Let's look at the View Model Class, which is a presenter for that window, which allows maintenance engineers to set up the bank terminals devices. The window has four buttons, which allow to test if contact or contact with the readers are in a certain port. And to find them by scanning through all the available ports in the system, we need to passing the card readers Communicator of Your Models, Constructor Independence, which is capable of testing and searching for card readers on ports. Now ask yourself, What would you do to solve the problem? The straightforward ways to add for method signatures right into the eye bank terminal? Let's do this and look at what will happen. Okay, since we have three implementer Z when you to implement the just edit a Prime Members, - huh ? What we're going to do here Zone Terminal service doesn't provide in a cry for communicating with card readers seemingly, we need to throw, not supported exceptions from the implemented members. Doesn't this case remind you something? Something we've seen in the previous section? Off course. This is a violation off the list of substitution principle. But what we're talking about is the interface segregation principal, 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 their wispy violation as a consequence, off ice be violation if we stick with the current solution and we require the ibon terminal interface as a parameter off the card readers communicator of your models constructor. One day someone will pass the zone terminal into the constructor, and then user will get an exception after clicking on the testing or searching button in the window. So if we want to avoid such unfortunate events, we need to acknowledge the fact that the eye bank colonel interface is too fat. It contains excessive AP I members. OK, in the next lecture, we're going to quickly reflector the problem. 13. 04 Refactoring to a Better Design: in the previous lecture were concluded that the eye Bank colonel interface is too fat, the manger and double sir. Factoring technique, which will usually apply to adhere to the SP, 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 Inter operating with card readers. So I'll do that. Now. We should implement this new interface of our two models off Bank Terminal, which actually can inter operate with card readers. PDQ Terminal already implement this interface and zip terminal as well. Great. Now we can require the i card readers Community cable into face in the view models. Constructor. 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 a prime members to use here. Since we have a one purpose interface here, this view as a client off the interface should not be bothered by excessive AP I members of the Eye Bank terminal thinking off their role. Now everything stands on its shelves. By playing the SP, we achieve the low coupling between methods which are different by their meaning, and thus we achieve high cohesion between them in segregated interfaces. In the next lecture, we will look at another case of feisty violation. 14. 05 OCP Related Patterns: This lecture is titled O. C. B. Related patterns. The two commonly used designed patterns to adhere the O. C. P. R. Template, method and strategy. Damn Plett Method and strategy are the so called behavioral design patterns. The template method is a veteran which we haven't discussed yet. The template method pattern is useful in such scenarios when there is an algorithm, and some small part of that algorithm may very again before. Defines template method pattern s define this skeleton often algorithm in an operation deferring some steps to sub glasses. Template method. Let's sub classes redefine certain steps, often algorithm without changing the algorithms structure. Let's look at the simple example in code. Here you have an abstract based class which defines the algorithm off processing transactions. The algorithm consists off three steps. Withdraw money, calculate bonus and send greetings. After that, we have to inheritors which implement that algorithm. This pattern allows declaring an algorithm in the base class, creating an extension point, since we can implement as many implementations off that algorithm as we want. The template better and can be implemented with a default implementation off algorithmic steps in the parent class by removing the abstract G word from the class declaration and making methods virtually instead of abstract. Actually, we can code a default implementation, keeping the parent class abstract just by turning algorithmic methods intra virtual instead of abstract. We're not obliged to remove the AB secured from the class declaration to have a default implementation. The template method pattern creates a point of extension for implementing various algorithms. That's how you can adhere to the gossip. In such cases. Let's look at the diagram of the strategy pattern. These diagram demonstrates how we can implement a sorter with a strategy pattern. The sorter takes the strategy an interface which defines the sort method. There are three implementations off that interface. The 1st 1 implements Bubble sort, the second quick sort and the last one selection sort. The clients code will use the sort and should decide which strategies wants to use to perform sorting. We're not going to look a ting examples in code, since we have already seen how we could use the strategy pattern in order to switch implementations off, I can operate with cash or I can pay by a credit card into faces in this R. P section. So here is the definition of the strategy pattern. The strategy pattern enables in algorithms behavior to be selected at runtime. The strategy pattern defines a family off algorithms, encapsulate each algorithm and makes the algorithms interchangeable within that family. So we often have two ways of defining obstructions. In Si shop, we can rely either on absurd classes or on interfaces, how to choose between them. Interfaces are made of stone. They can be easily changed without breaking existing clients at the same time into faces. A reason extendable by Cline's A client can extend a link to face by extension methods. And by the way, if a client wants to implement an interface on a class which already inherits from another class, client can easily do that. A client couldn't do that with an abstract class. Instead, often interface. Since multiple inheritance in C shop is depreciated, any class can implement its many interfaces as it wants to, so invent and interface is more supple from the client's perspective. Unfortunately, an interface is more regent. From the developers perspective, it can be easily changed, and it doesn't support any kind of reusability. Abstract classes support reusability. They support encapsulation, and they can be extended easily without breaking existing clients. As a result, an abstract class is supple from the developers perspective and at the same time, more region from the client's perspective, since multiple inheritance is depreciated. With all that said, we can conclude the interesting rule of thumb used abstract glasses for building internal AP eyes and use interfaces for providing external points of extension. Remember, this is not a dogma. This is a rule of thumb recall, for example, that Basile provides I collection. I least I notify property changed and turns off other interfaces. This is done so because they extends ability from the client's perspective, is more important in these cases. In the lecture where we did their factoring, I said that a Napster class with several implementations leads to a situation when it's hard to add new operations, since you'll have to implement them in each class. There is another problem. What if we want to provide an opportunity to our clients to define operations on their own ? In such a case, you may be interested in applying the visitor designed pattern. Look at the diagram. The visitor pattern is quite difficult to understand, especially just by looking at a diagram. In short, the visitor pattern allows to define an operation which can be performed on any class off a certain hierarchy without modifying classes off that hierarchy. Let's look at an example in visual studio. Last time we came out with the following design, we extracted the I device interface to abstract the way devices operations. Here we have the fine method. After that, we created to implementer going dispenser Cube for and Bill dispenser E C D. M. Let's say we want to add operations on the client side, and the client doesn't have access to the eye device interface. For that, we will apply the visitor pattern before implementing that better. Let's create a port property here and the same in the coin dispenser coop. For now, we can implement the visas or pattern. Well, that's great that I device visitor interface, which exposes visit methods for all the device models. Now we can implement the base class for devices to pass their instances to the visitor. Now I want to add a new command for that. At first I had the close command visitor class which implements the new feature for not using off this visitor. I would also create an extension method on the device class as this. Now the clients coat can easily use the new clothes command on any devices, - and now everything works fine. This is a very powerful pattern, which allows you to come up with a supple design. If you expect the extension of types than most likely, it would be better to stick with a classic hierarchy. We came up with performing the first or factory. On the contrary, if you expect that the hierarchy is not volatile and the operations are going to be implemented by clients, then the visitor pattern is the way to go. Adding new types to the visitor can be problematic in the next lecture. Let's sum up what we learned about the OCP and try to briefly describe the common smells off OCP violation 15. 06 Common Smells of OCP Violation: the most common smell off gossipy violation is the appearance off many conditional branches , either with if else or with switch case statements. Generally, you have three common approaches to adhere to the S a p building handling sequences with delegates, which are naturally the implementations off the chain of responsibility pattern. Look for the chain of responsibility bedroom. The spectrum is almost built in with events into the dot net platform, so we use it when we need to pass a message and handle it by several handlers. The chain of responsibility provides the way to implement that in a loosely coupled manner . Otherwise, you can end up with coupled objects. Another way is to rely on a classic inheritance with a template method pattern, or to implement a visitor pattern. If you need to provide the ability for a client to define operations, the last way is to rely on a composition rather than on inheritance. Most likely, you will rely on the strategy better to implement a composition. Remember that composition is generally more prefer than classic inheritance. Okay, in the next lecture, we're going to summarize what we learned in these section 16. 07 Conclusion: This lecture is titled Conclusion. The open close principle is all about changes. Following OCP, you can achieve every supple design which is ready for introducing new features without pain. To achieve the supple design, it should be open for extension and closed for a modification, so the most frequently changing parts of the system have to be isolated. One very important thing is that we need to isolate a responsibility for creating objects in a single module and Onley that module should be changed in case of introducing new implementations. This principle is called the Single choice principle. You've learned that you can adhere to the OCP by harnessing the power off abstract classes for interfaces. Most common designed patterns we apply to adhere to the LCP are the template, method and strategy. You've learned that an interface is more supple from the client's point off view. While an abstract quest is more supple from the developers point off you. We've also learned that we don't have at our disposal any magic tools which allow us to protect ourselves from all the possible changes completely, and it doesn't mean that we should start to create tons of extensions, points anticipating changes in the future all over the code base. To overcome the problem, we're trying to use the so called gile design. Congratulations. You've reached the end of the OCP section in the next section. We're going to look at the list of substitution principle, seemingly the hardest to understand prince among solid principles. 17. 01 Outline: Hi. This is the last for fun of baking engineer spot. And in this section, we're going to learn where the principles are. We refer to the principles we're going to talk about in this section as to matter principles because they are the roots off all the other more concrete principles adhering to which we're actually trying to conform with the matter principles. We will start from the dryer. Don't repeat yourself principle. You learn the definition of the most common smells of violating the dry principle. After that, you learned the keys or keep it simple. Stupid principle. Here we're going to talk about simplicity and complexity, accidental and essential complexity and how to achieve simplicity. The next meta principle we're going to talk about is the young me or you ain't gonna need it principle. It is related to the needless complexity smell and concerns the anticipations off common features. We will look into practical problems which we face and what other consequences off implementing features we actually don't need. After that, we're going to talk about the sock or separation of concerns principle. This principle underlies incense. All the solid principles. Separation of concerns is very important for achieving well maintainable applications. You'll see the most common ways of violating the separation of concerns. Principle Command query separation principle makes easier to reason about. The code will discuss the low of Demeter, which is the principal off list knowledge. Separately, we will talk about the principle off least astonishment you. Then we will touch the topic of information hiding and encapsulation. By the way, I will use the word principle instead of matter principle in this section. Further, just for the sake of saving some time in the next lecture, you learn about the dry principle. Let's get started. 18. 02 LSP Definition: this lecture is titled Problem Statement. The official definition from Barbara Liska off the list of substitution principal sounds like this if s is a subtype off team than objects off type T may be replaced with objects off type s without breaking the program. It's not very hard to grasp what this definition means, but I'll quote the definition off L S P from the book off Uncle Bob. Agile principles, Patterns and Practices in C sharp Just in case we find there the following definition off the list of substitution principle the list of substitution principle states that subtypes must be substituted ble for their base types. By the way, Barbara Lisk off is a scientist who described this principle in 1988. The original paper was written in Greece and it was very hard to understand and apply toe object oriented programming in practice. Let's try to clarify what it was he means for developers in practice. What does it mean to be substituted ble for a class? Let's pretend that we have a client which uses the FBI off interface be there are two. It is implemented by classes A and C Class C can be considered Substitute hable 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. Actually, the L S P is strongly related to her object oriented languages. Allow us to use inheritance. If Glenn's be inherits from a, then we can use B S A. But we can to use a SB. Thus, clients off a can use both A and B even if they know nothing about be. This is basics off polymorphism. Despite this is basics developers all the time. I violate the logic off 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 dark typing. If a bird swims like a duck, it quacks like a duck. Then I called advert a duck. 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 a message, I mean a call to the method, since in dynamically type languages, it's better to say Send a message rather than call a method. Let's get back to the main topic. There are two ways of breaking the substitute ability. Violating contract and violating co variance or control variants. For a significant number of developers, it's unclear what does it mean? So it requires the further clarification. Without understanding, these fundamental concepts will not be able to design types which don't violate their speak . Sooner or later, you'll bump into the horrible problems caused by, oh speed violation. So keep patients and let's start with contracts in the next lecture. 19. 03 Contracts: This lecture is titled Contracts. Programming to Contracts was elaborated by Burton Meyer in his classic book, Object Oriented Software Construction. He described the advantages off programming to contracts. He even came out with the whole new language called Eiffel, which was built with programming to contracts in mind. So what's the contract? Many developers makes the notions off an interface and the contract. The statement becomes more convincing with the fact that in WC, if we treat interfaces and contracts equally in W. C. F. A service contract can only be represented by an interface in the real world, including the real world. Outside of programming, contracts have some semantic payload. Usually, they determine some kind off relationships between people, writes objects and so on into faces have no any semantic payload. They determine nothing except signatures, but signatures don't bear any significant semantic payload. An interface represents just a shape. Thus, interfaces are not contracts. Here is an example of a contract provided by Christophe Kulina. This contract says that when an item is added to the collection, the count properties incriminated by one. In addition, this contract is locked for all subtypes. So a contract off a method constitutes off the following parts. Acceptable and unacceptable input values or types and their meanings. Return values or types and their meanings. Error and exception condition, values or types that can a cure and their meanings, side effects, preconditions, post conditions. And in variance from the learning perspective, we're mostly interested in preconditions, post conditions and in variance for conditions. Off a function is the set off requirements. A function applies to the input parameters and sometimes the state of the object to which that function belongs. I have a simple example from my own practice. Eases off course, simplified and presented in a form off a skeleton for the sake of simplicity. Here have two different bank terminal models. Both models derive from the eye bank terminal interface, which defines the process payment operation. These terminals share significant amount of business logic, and they have very similar interfaces, so developers decided to join them by introducing that I bank terminal interface. Unfortunately, both terminals have their own payment gateways with different interfaces. One requires a unique i d to be generated by client, while another doesn't to make the A P. I. Universal developers just rolled out a single method with two parameters. The implementation off the first terminal just ignores the second parameter, while the second checks the unique I D. And if it's now or right space, it throws the argument exception. A client, which worked with the first terminal, doesn't expect such a behavior working with the 2nd 1 This happens because the second inheritor strengthens the preconditions. The first terminal accepts the unique I D, which can be equal to any value. No restrictions were applied. The corollary is that a client has to be aware of different behaviour of these Ben terminals. Those clients who worked with the first terminal would not expect any exceptions. Working with the 2nd 1 passing now as a unique i d. The hierarchy not only violates their WASPy strengthening the preconditions, but also it violates they'll a speed by weakening the post conditions the first terminal returns The result code off type you end what means that the response code is equal or greater than zero? In the second case, the result code can be less than zero off course. In the second case, the internal logic of the payment gateway, my guarantee that it returns only codes that are equal or greater than zero but pretend that it doesn't provide such guarantees. Developers wanted to roll out the universal interface, so they defined the process payment. It's a method which returns an integer. Here we see that the first terminal returns a you end, but it has to cast it toe end to satisfy the interface Very often. In such cases, clients are aware of the guarantees provided by one of the implementer. For example, in this case, the method explicitly says in commands that the returning response is always positive. The second terminal weakens the post conditions comparing to the first terminal. That's why developers had to define the process payment method with integer assay returning type. They attempt to make a universal interface fails because clients have to know the internal details. In the end, they know that the first model actually guarantees that it returns. Positive codes, despite the signature doesn't reflect it. The overall idea is that by weakening post conditions, 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 you can write contracts on the dot net platform in C shop with a special library called code contracts. Not surprisingly, using code contracts, you can harness the power off stated code verification on correctness due to some practical problems and problems related to the poor implementation off the code contracts library. It's not a very popular approach. Nowadays, for example, called contracts work very slow on big solutions. And this is only one of the reasons this library is out of the scope of the scores. So if you're interested in code contracts, you can just Google for it. Another problem I want to demonstrate is related to the violation off in variance on a classic example in the next lecture. 20. 04 Demo of the Problem: this lecture is titled Ellis Be Violation Demo. Let's consider a classic example of Phyllis P. Violation. I love this example because of two reasons. The 1st 1 is that it actually demonstrates the L S P violation, and this reason is obvious. And the second reason is that it shows that object oriented programming often can directly map the relationships between objects in the real world into the same model off relationships between them in code. A great number of developers think that writing code in Hopi language, they're modeling aerial world domain problems. And partly this is true. But the real world relationships between objects sometimes can be motile directly in Opie language. Here's one of the naive hopey statements child glasses. Implement is a relationship with based classes. 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 are inheritors. Unfortunately, sometimes this kind of design doesn't work as expected, and you'll see this in a minute. So let's reflect the relationships between two riel 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 off rectangle . It's others because square is a rectangle with equal sides. Okay, let's switch to visual studio. Let's create a rectangle and square. I created the rectangle class, which has two properties with and height, and the square, which inherits from their tangle class. Separately, I'll create the class, which is responsible for calculating areas of that shapes. Looks fine. From the first side. 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 that first, I'll just create a rectangle with with equals two and hide equals five. After that, I'll call the ST IC Cal correct angle method and get the result, and I also send the result to the console. Now I want to create a square. Wait a minute. What the hell is this? How a square can contain sides of different length. I'm not even going to run the program, since it's obvious that something is wrong here with a pile of square square allows to set different length to width and height. This design clearly violates the list of substitution. Principal square is not substitute hable for rectangle rectangle implements the in variant , which states that width and height could be off. Different Land Square has to implement another in variant 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. 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 era, such a method could look like this. This method checks the type of the accepted parameter and run the appropriate calculation algorithm. What do you think? Is it a good way to define methods all over the code base which have to work with rectangles? Doesn't it resemble you something we've seen previously? Yes, indeed, this is a violation of the open close principle. This method is open for modification. What will happen if we introduce a new shape? Correct. We'll have to modify. That's which statement this example of Gillespie violation is a hidden violation off OCP. In the next lecture, we will look at how to fix this problem 21. 05 Refactoring to a Better Design: Obviously we need to make impossible setting different length offsides for a square to fix the problem. For now, the expectations of the squares clients are broken. The air, a calculator class now demonstrate that there is a problem off separated data and behavior . The calculation algorithms are separated from the rectangle and square glasses, which own the data required for calculations. The area calculator 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 disease, where always should construct proper abstractions. What we want to obstruct away is the business logic of calculating the area. Each shape has its own algorithm off calculation. The area. It is much better to make behavior shared rather than data. Let's obstruct away the calculate area method by introducing the I shaped interface. I want the rectangle and square to inherit from the eye shape. Implementing their own algorithms, Square now defines its own property named side length. Now a client can't misuse. It's a P I. Here's an example of a client in case of rectangle calling to calculate area, A client will give the area off a rectangle, while in case of square, a client will get the area of a square. The client can set different length, off width and height to a square. Great. In the next lecture, we will look at other ways off ls be violation. 22. 06 More Examples of LSP Violations: this lecture is titled More Examples Off L S P violation. We are meted the discussion off a very important topic. Variance Variance is a very complicated concept. So we're going toe only touch this topic. Despite that it is related to the L S P variance is the notion that describes the types compliance. It branches out to two notions, coherence and contra variance. Assuming the type A canned the cast to type B Type X is co variant in case X off a canned the cast two x off b, for example. I borrow stream can because to my bar off object this gold snippet shows that s is called Aaron too. Oh, here's a simple example which demonstrated the problem off casting as human would have the following class hierarchy the base glass animal and the inheritors dog and cat and a nave generic implementation off stack. The following code will not compile in C shop c sharp d proc eights this to prevent the possibility off writing the following code we're trying here to add cats to dogs A raise in C shop are co variant because of historical reasons. So the following code will compile and the violation off the L S P will be detected Onley in the run time. There will be an exception. Starting from C shop for generic interfaces. Allow variants through special keywords in and out generic classes. At the same time, don't allow variants. The out keyword guarantees that inside the implementation off 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. Even the stack class from the previous example implement this interface than the following code will compile and be absolutely correct. On the contrary, we can use the in keyword to ensure that the generic parameter is only used as the input. Here's the code snippet, which demonstrated the idea if the stack glass implements this interface than the following code will compile and be absolutely correct. Another example I want to show you comes from the Basile off the dot net framework. It is also well known example of the SP violation. There is a generic interface named I collection, often defined in the BCL. The stop derives from the innumerable of tea, and it defines the following methods. Add clear. Contains copy, too. Remove. There's old surgeon air class named read only Collection off team, which derives from the I collection of team. Yes, you can guess from the name off the read only collection off T. It implements a collection which cannot be changed after initialization at the same time, read only collection Off T derives from the I collection of tea. What means that it should support all the operations defined in that parent, a generic interface. A second sequence, the read only collection has to implement, add clear and remove methods somehow but how it is supposed to implement them, taking into account that these operations are dip located to perform on a read only collection off course, there is no meaningful way to solve this problem. So there it only collection just throws. They're not supported. Exception from that modification methods. It clearly violates the list of substitution principle, since clients that work with my collection of tea don't expect such behavior. And this is logical because other implementations off I collection of tea, such as a list of tea don't throw is not supported exception. They just work is expected from a class which exposes modification methods. Throwing, not supported exception is a strong smell off l S P violation. Another smell which indicates the L S P violation demonstrates itself by appearing off too many down casts in the code base. If a client is constantly checking the actual types of based classes or interfaces, it automatically means that a client is concerned about different implementer. Zobaie. Some reason it means that a clan knows some internal details about the objects hierarchy construction. The smell is a consequence off the SP violation An example of such a smell you've seen in the lecture where we discussed the relationships between square and rectangle. The code snippet on the slide demonstrates this problem as well. Down costs are not always the indication off SP 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. For example, if we're absolutely sure that this function is called only with an I d off a privileged customer, then 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 rial type is privileged customer. In the next lecture, we will mark out some common smells which indicate analysts be violation. 23. 07 Common Smells of LSP Violation: this lecture is titled Common Smells Off LS Be Violation. Let's sum up what common smells we may face with which indicate Bayliss be violation. First of all, if a method throws then not supported exception from its body and other notion, which describes this case is the notion off so called refused bequest. The meaning is that the child quest inherits something, but it doesn't know what to do with the inherited bequest and refuses it by throwing than not supported exceptions. Another form of the same refused bequest is when a method has an inter implementation. This is the same case. The only difference is that a method refuses bequest not so vehemently, and other smell concerns down casts down casts mean that a client has to know internal details of the obstruction. It depends on. Here are some tips to conform with l S B. Try to keep in your mind the tell don't ask principle, which means, in essence, that the clients code should be able to just pass messages without thinking off any internal details off the collaborator. Ideally, the clients should not be bothered by checking any conditions. Remember that l S P violation is often econ sequence off OCP or SP violation. We will talk about interface segregation principle in the next section, so just take in to account for now that fact In such cases, fixing the root cause leads to an automatic fix off the L S P violation. If you have two classes that share some logic and they're not substitute Hable, then think of creating a new base class for that two glasses. Then inherit those two classes from a base class and ensure that their substitute hable the new base class. In the next lecture, we will draw a conclusion. 24. 08 Conclusion: this lecture is titled Conclusion. The principal we discussed throughout this section was the interface segregation prince or I speak in shirt, there s P has a simple definition. Clients should not be forced to depend on methods they do not use. So these definition implies that you have to strive to great, small, cohesive and focused interfaces. Off course, different clients can use only a subset off FBI members they depend upon. Unless that AP, I start to grow transforming into a very fat interface with unrelated members to each other , where, when similar but different methods appear to satisfy the requirements of different clients . A typical way of violation you saw, was when an interface was too broad. What led to some smells like implementer throw not implemented exception or clients have to see all the mass in the intelligence thinking off what they actually need to use as we discussed, there are several ways of dealing with I speak violations. Sometimes it is just enough to extract a separate interface from a fat one and use it where appropriate. Sometimes you need to come out with a facade which hides irrelevant. Ap I members. Sometimes you need to apply an adapter pattern, especially if you don't own the fat interface, and thus you cant modify its source code. The intelligent adhering to the interface segregation principle makes an application easier to maintain what is extremely valuable, especially in the long term. Abusing I speak you can end up with tones. Off to small interface is what makes them harder to use by old clients. This is a smell known as anti ice. Be so we reached the end of this section. That was an interesting investigation. But there is another principle waiting for us the dependency inversion principle. The next section is dedicated to the D. I. P. Let's get straight to business. 25. 01 Outline: Hi. This is the last for fun of baking engineer spot. And in this section, we're going to learn where the principles are. We refer to the principles we're going to talk about in this section as to matter principles because they are the roots off all the other more concrete principles adhering to which we're actually trying to conform with the matter principles. We will start from the dryer. Don't repeat yourself principle. You learn the definition of the most common smells of violating the dry principle. After that, you learned the keys or keep it simple. Stupid principle. Here we're going to talk about simplicity and complexity, accidental and essential complexity and how to achieve simplicity. The next meta principle we're going to talk about is the young me or you ain't gonna need it principle. It is related to the needless complexity smell and concerns the anticipations off common features. We will look into practical problems which we face and what other consequences off implementing features we actually don't need. After that, we're going to talk about the sock or separation of concerns principle. This principle underlies incense. All the solid principles. Separation of concerns is very important for achieving well maintainable applications. You'll see the most common ways of violating the separation of concerns. Principle Command query separation principle makes easier to reason about. The code will discuss the low of Demeter, which is the principal off list knowledge. Separately, we will talk about the principle off least astonishment you. Then we will touch the topic of information hiding and encapsulation. By the way, I will use the word principle instead of matter principle in this section. Further, just for the sake of saving some time in the next lecture, you learn about the dry principle. Let's get started. 26. 02 ISP Definition: this lecture is titled Problem Statement. Before giving a definition, I want to say a couple of wars about what we mean here. By the word interface. Off course. Into Face is a reserved keyword in C shop, which allows to declare a non. Such a construction defines an FBI as shape, which has to be implemented by inheritors of that interface. At the same time, it's not necessary to implement an interface to expose an interface. What I mean is that glasses which don't implement any interface have their own interface is comprised of publicly visible members. The set of public members of a glass represents the interface of that class. So simply put, and interface is what clients see and use a great simple definition off. The interface segregation principle was given in the book. You have already heard off in jail principles, patterns and practices in C shop. So the definition is the interface. Segregation principle states that clients should not be forced to depend on methods they do not use. A simple conclusion 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 only a P I members are logically related to each other. 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. This finding monster wants to eat. And that's why it says that if I require food, 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, I require food, it would be silly to have methods like lunch aircraft or kill character exposed by the interface. Here's an interesting historical note about the I speak. I'm pretty sure that I Speed was first used long ago before Robert Martin, but the first public formulation belongs Toa Robert C. Martin, a k Uncle Bob. He applied there, speak first time, well consulting for Xerox. Xerox had created a new printer system that could perform a variety of tasks such a stapling and faxing. The software for that 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, often our, which made development nearly impossible. The redeployment cycle took so much time because at that time there were no see shopper job . These languages compiled very fast what we can't say about C plus plus, for example, a bad design off a C plus plus program can lead to significant compile elation time. The consequences are dramatic. Let's get back to the story. The design problem was that a single job class was used by almost all of the tasks. Whenever a bring job or a stapling job needed to be performed, a call was made to the job class. This resulted in the fact glass, with multitudes off method specific to a variety of different clients. Because of these design, a staple job would know about all the methods off the print job, even though there was no use for them to solve the problem. Uncle Bob came up with an idea which is called into face segregation principle. Today, Uncle Bo created and need to face layer between the job glass and its clients, using the dependence inversion principle which we're going to talk about in the next section instead of having one large job glass, a staple job interface or a print job interface was created that would be used by the staple or print classes, respectively. Calling methods off the job glass. Therefore one into face was created for each job type, which were all implemented by the job class so into face segregation. Principal violations result in classes that depend on things they do not need, increasing coupling and reducing flexibility and maintain ability. In the next lecture, we look more closely at the problem off ice P violation. 27. 03 Demo of the Problem: this lecture is titled Ice Be Violation Dama one. I Want to Show You Ariel Case from my practice, which was related to the problem off into face segregation. I've been working with devices a lot, and once I faced the following case before granting, I want to say that I like to give examples to students which reflect the whole picture of aerial 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. So on the top level we have a monolithic WBF application, which works on point off service 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 pass terminals, so all of them had to be supported. The interpretation with bank terminals is not direct. Ban terminal producers provide their own applications through which our application can work with their bank terminals. Their applications are implemented as come servers. If you don't know what is a com server just think off it as a stand alone executable service. The diagram reflects the flow of operations. Let's look at code. There is the bare minimum off operations, which are supported by any possible bank terminal. That's why I defined the Eye Bank terminal interface, which reflects the B I provided by services which Inter operate with bank terminals directly. Now I have three implementations off the eye bank terminal interface, Zap Terminal, his own terminal and PDQ terminal. I am entered the rial implementation, since it would complicate the example too much. And there is no meaning to show you the guts and low level details. And now I'll describe the problem which arose. The thing is that bank terminals are different. The some terminal is a black box solution which physically is a box which on its own works with credit card arrears. Great ID card readers are those devices which accept your card, read the cheap or a magnetic stripe and dispense back card back to you. So his own terminal doesn't expose guy for Inter operating with card readers because the service application automatically sets old and accessory things up At the same time, the other two bank terminals, PDQ Terminal and Zap Terminal don't take responsibility for Inter parading with card readers automatically. On the contrary, they delegate this responsibility to a client, exposing a P I for inter parading with card readers. So in the first case, our application doesn't need to do anything at all. While in the other two cases are application has to show a window to post terminal maintenance engineers to provide the ability to set up the bank terminal devices properly. Let's look at the View Model Class, which is a presenter for that window, which allows maintenance engineers to set up the bank terminals devices. The window has four buttons, which allow to test if contact or contact with the readers are in a certain port. And to find them by scanning through all the available ports in the system, we need to passing the card readers Communicator of Your Models, Constructor Independence, which is capable of testing and searching for card readers on ports. Now ask yourself, What would you do to solve the problem? The straightforward ways to add for method signatures right into the eye bank terminal? Let's do this and look at what will happen. Okay, since we have three implementer Z when you to implement the just edit a Prime Members, - huh ? What we're going to do here Zone Terminal service doesn't provide in a cry for communicating with card readers seemingly, we need to throw, not supported exceptions from the implemented members. Doesn't this case remind you something? Something we've seen in the previous section? Off course. This is a violation off the list of substitution principle. But what we're talking about is the interface segregation principal, 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 their wispy violation as a consequence, off ice be violation if we stick with the current solution and we require the ibon terminal interface as a parameter off the card readers communicator of your models constructor. One day someone will pass the zone terminal into the constructor, and then user will get an exception after clicking on the testing or searching button in the window. So if we want to avoid such unfortunate events, we need to acknowledge the fact that the eye bank colonel interface is too fat. It contains excessive AP I members. OK, in the next lecture, we're going to quickly reflector the problem. 28. 04 Refactoring to a Better Design: in the previous lecture were concluded that the eye Bank colonel interface is too fat, the manger and double sir. Factoring technique, which will usually apply to adhere to the SP, 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 Inter operating with card readers. So I'll do that. Now. We should implement this new interface of our two models off Bank Terminal, which actually can inter operate with card readers. PDQ Terminal already implement this interface and zip terminal as well. Great. Now we can require the i card readers Community cable into face in the view models. Constructor. 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 a prime members to use here. Since we have a one purpose interface here, this view as a client off the interface should not be bothered by excessive AP I members of the Eye Bank terminal thinking off their role. Now everything stands on its shelves. By playing the SP, we achieve the low coupling between methods which are different by their meaning, and thus we achieve high cohesion between them in segregated interfaces. In the next lecture, we will look at another case of feisty violation. 29. 05 Demo of the Problem: In the previous case, the implementer often interface itself from you too much. It used something that it shouldn't know. That's why it couldn't implement some members properly. So the existence of a problem has Lloreda been obvious at the level off into face implementer. Very often the problem goes deeper. When the problem shows itself on Lee at the implementer client level, consider the following example. I have a configuration class here which is implemented s sort off a singleton. It's constructor is closed and it only can be created by the initialized method. Used to serialize is an XML configuration file. Not surprisingly, would have a class which utilizes this app config. Here we have the report glass which implements some business logic off reports generation. Currently it directly depends on the conflict glass. Because of that, we can't easily write a unit test for the report class. What only can do is to write an integration test which deals with XML configuration file, setting it up properly. What we can do is to obstruct away the configuration class but introducing an interface, let's extract an interface and I'll extract all the public members. Now we can request this interface to be passed in the constructor off the report Class grade. Now we can write a union test. What's wrong with this test? I sit up all the properties, even those which are not required by the internal logic of the report. Glass. You could ask me why. I indeed said all the properties I could set only those which are required partly your right. This would solve the problem off excessive gold. 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 best. Would you be so sure that you set all the properties required by the quest under test? No, you wouldn't. You'll constantly see all that mass in the intelligence asking yourself whether that class requires that or another property to be said. The only way to get rid of the mass and make the code clear and cleaner is to apply the interface segregation principle to solve the problem. We will apply the I speak in the next lecture 30. 06 Refactoring to a Better Design: to cure the disease. We should. Cigarette gave the configuration interface. The report. Glass should know only the part of configuration related to generating reports. Let's extract that part into separate interface and we requested this interface to the past in the reports Glass Constructor. Now the report class is aware off only those things which are relevant to the reports. Business logic. Let's implement the unit test now. Great. Now we don't need to think of Forell and stuff that this test is simple, clean and understandable. In the next lecture, we will learn the common smell Suffice P violations. What fixes we can apply and what the design patrons related to the I speak Do we have at our disposal? 31. 07 Common Smells, Fixes, and Related Patterns: this lecture is titled Common Smells Fixes End related patterns. So let's talk about common smells, which indicate that your cold violated interface segregation principle. In the first example, you've seen a smell which was similar to the violation off. The list of substitution principle we can refer to this smell is to degenerate implementation off into face methods. If a method which either rides a method off a base glass or implements a method inherited from an interface throws an exception, most likely not implemented exception or just does nothing. What is called degenerative implementation that indicates that I speed may be violated. This is logical, since there is a very high chance that a client off such glass don't want to know about that math it and don't want to use it at the same time. This is an indication of fella speed violation. Seen such a quest can't act as a substitution for the base glass or an interface. Sometimes in such cases, there was violation is the root cause off the problem. But often their cause is the violation of the ice. Be so you should study your particular case and figure out what causes the problem. Another smell, which you've seen in the second demo, can be described as the case when a client's called references a class but only uses a small portion off. It's a P I. It obviously indicates that there is a local Haitian between such glasses. This should suggest you that something is wrong here, and you need to stop the investigation of the problem. Often you'll find that the problem hides behind the two fat into faces. 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 change the interface because you can't modify its source code. In that case, it might be useful to apply if Assad better. You've seen the application off this pattern in the SRP section. In the case of feisty violation, we used facade to narrow down the width off fat glasses, a p I. If you have a fat interface and it's a P, I is not compatible with an interface on the client side. When you try to use it, then you may find that there is also a possibility to apply the adapter better. First, let's look at the adapter pattern. Generally, what is a Deborah pattern? According to the Gang of Four book Deputy Pattern is intended to convert the interface off a glass into nothing to face clients. Expect adapter lets glasses work together that couldn't otherwise. Because of incompatible interfaces, this slide demonstrates a case of an adapter can be applied. Imagine that at first to 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 wizard adapter, which implements the fighter interface and internally uses the Wizard. It adapts it in our case, when we talk about them to face segregation principle. We don't have a classic problem when adapter is usually applied because we don't deal with incompatible into faces. In our case, interfaces are not incompatible. One is just too fat for another. Nevertheless, the adapter bedroom can also be applied in our case as well. Let's look at the code and visual studio, which demonstrates this case off applying the adapter pattern in order to adhere to the I speak. I didn't come out with a real case, so I'll just show you a completely synthetic example. Here is the case. At first you see that we have the Eye Wide interface, which defines four methods A, B, C and D. The clients Cold wants to see only methods A and B. To apply the deputy pattern, we can define a separate I narrow interface, which defines on the A and B methods. The adapter itself is going to implement that I narrow interface while it accepts the eye wide interface. Instance in the constructor as the implementation off A and B methods adapter just delegates the responsibility to the eye wide interface. Instance, the clients gold now can rely on the A narrow interface. Taking the instance in the constructor. We can pass in the adapter instance, and the client will get the access only two methods A and B. This is how the adapter pattern can be applied to adhere to the ice be There is another tricky case related to the adapter pattern. Let's say we have a class purse Easter, which is directly used by many clients. And now let's say new clients require a new method in the purse Easter, and they will depend only on that method. Then we can do the following Now. Old clients can use the per sister as they used before, and they will not see the new method. While new clients will see only than you method this implementation off the interface is called the Explicit Implementation. You can call such method only through the interface, so the following clients code will compile. Let's get back to the slides. The general way of fixing a problem with a fat interface is to create, and there are interface with only absolutely required methods in it. Then have the Fed interface implement your new interface and then use that new interface in the client's code, which don't need to know about irrelevant AP I members off a fat interface. This is exactly what we did in the second row, factoring Dama while fixing the problem with configuration. And the last point here I want to address is that you shouldn't crash all your interfaces into single method into faces just because this will make the ice P violation impossible. It Blinder affect Oring techniques only when you feel that there is a technical dad stopped to appear here and there or if a technical dad hasn't started to spread yet. But you know for sure that it will if you don't fix the ice P violation. The last tip I want to say about concerns the dependency management on a binary level. So the deep is that it's better whenever possible to keep the interface within the client's assembly. It makes easier to change the interface. If something is wrong, a client will be able to change the interface exactly how it wants to instead of rolling out any adapters. Okay, that's great. We've reached the end of the section. In the next lecture, we will conclude what you've learned in this section. 32. 08 Conclusion: this lecture is titled Conclusion. The principal we discussed throughout this section was the interface segregation prince or I speak in shirt, there s P has a simple definition. Clients should not be forced to depend on methods they do not use. So these definition implies that you have to strive to great, small, cohesive and focused interfaces. Off course, different clients can use only a subset off FBI members they depend upon. Unless that AP, I start to grow transforming into a very fat interface with unrelated members to each other , where, when similar but different methods appear to satisfy the requirements of different clients . A typical way of violation you saw, was when an interface was too broad. What led to some smells like implementer throw not implemented exception or clients have to see all the mass in the intelligence thinking off what they actually need to use as we discussed, there are several ways of dealing with I speak violations. Sometimes it is just enough to extract a separate interface from a fat one and use it where appropriate. Sometimes you need to come out with a facade which hides irrelevant. Ap I members. Sometimes you need to apply an adapter pattern, especially if you don't own the fat interface, and thus you cant modify its source code. The intelligent adhering to the interface segregation principle makes an application easier to maintain what is extremely valuable, especially in the long term. Abusing I speak you can end up with tones. Off to small interface is what makes them harder to use by old clients. This is a smell known as anti ice. Be so we reached the end of this section. That was an interesting investigation. But there is another principle waiting for us the dependency inversion principle. The next section is dedicated to the D. I. P. Let's get straight to business. 33. 01 Outline: Hi. This is the last for fun of baking engineer spot. And in this section, we're going to learn where the principles are. We refer to the principles we're going to talk about in this section as to matter principles because they are the roots off all the other more concrete principles adhering to which we're actually trying to conform with the matter principles. We will start from the dryer. Don't repeat yourself principle. You learn the definition of the most common smells of violating the dry principle. After that, you learned the keys or keep it simple. Stupid principle. Here we're going to talk about simplicity and complexity, accidental and essential complexity and how to achieve simplicity. The next meta principle we're going to talk about is the young me or you ain't gonna need it principle. It is related to the needless complexity smell and concerns the anticipations off common features. We will look into practical problems which we face and what other consequences off implementing features we actually don't need. After that, we're going to talk about the sock or separation of concerns principle. This principle underlies incense. All the solid principles. Separation of concerns is very important for achieving well maintainable applications. You'll see the most common ways of violating the separation of concerns. Principle Command query separation principle makes easier to reason about. The code will discuss the low of Demeter, which is the principal off list knowledge. Separately, we will talk about the principle off least astonishment you. Then we will touch the topic of information hiding and encapsulation. By the way, I will use the word principle instead of matter principle in this section. Further, just for the sake of saving some time in the next lecture, you learn about the dry principle. Let's get started. 34. 02 DIP Definition: this lecture is titled Definition Off the A P. The dependence inversion principle is all about decoupling. This is very important, so I'll remind you what coupling is. Coupling indicates how dependent modules are on the inner workings off each other. Tightly coupled modules rely extensively on the specific state off each other, sharing variables and many types loosely coupled modules are fairly independent. They have a few well defined AP eyes and share a limited amount off or no data at all. So the coupling is what was trying to it is the process of achieving the loosely coupled modules. You can understand modules here, both as classes were Assam bliss. The D I P is applicable a different levels at the source code level in the binary level. If you look at Wikipedia, you'll see that low coupling is often a sign off. A well structured computer system and the good design and when combined with high cohesion , supports the general girls off higher irritability and maintain ability Well said indeed. So what is the formal definition? According to the child principles, patterns and practices in Souchard by Uncle Bob, 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. Seems like this is a definition with two levels. The first level concerns modules and the second concerns abstractions. This is a great definition, however. It's always It requires some further clarification, since it's very hard to apply in practice. Such advice is without seeing any practical examples. I want to show you a picture which demonstrates the D I pena real life. Given the lamp socket and a soldier. A question. Arise. Would you soldier a lamp directly to the electrical wiring in a wall? If you do that, you'd be able only to use that socket for that lamp because they're so to speak tightly coupled. To fix the problem, we need to come out with a standard plug, which you can see on the right small picture. If all the devices implement such a plug, then they can block into the socket. The same is true for dependencies and code. The high level policies should not directly depend on low level details in case of four picture devices are not directly dependent sockets. You can find an exception from almost all the rules. So look at this picture. This is a cheap hotel where the hair dryer is wired to the socket directly. But in this case, this is done intentionally, and actually it is meaningful. The intention in this case is to defend the dryer from thieves again. This is a rare case in this lecture. We mentioned the notion off the dependency. In the next lecture, we will look at dependencies more closely. 35. 03 Dependencies 01: This lecture is titled Dependencies, Let's define what we mean by a dependency. There are several types of dependencies on the framework on third body leaves, external systems like file system database or any system resource and sewn dependency on a custom type built on top of the dotnet framework. In this section, the most important type of dependencies for us is the dependencies on custom types which are developed by us. For example, here on the slide, the person glass depends on personal repository class. A person can't provide its features without relying on the personal repository class. The person repository is a low level class which Inter operates with a database, while the person is the high level domain object. So in this particular case, the high level object depends on the low level object. Such a case is aligned with how beginners build software. Traditionally, this is a high level of you on a classic application, with three tears on the top, we have a user interface. A user interface calls a p I off objects which implement business logic objects which implement business logic, call the guy off low level infrastructural objects which implement into operation with a database, external Web service and so on. What's wrong with the relationships between layers on this diagram? Do know what it is? The problem is that high level objects off the domain layer directly depend on low level objects of the infrastructural layer. The lamp is soldered to the socket like a vice. What would you do if a requirement to change the database management system comes into play ? It's hard as hell to replace a dependency. If there is a tight coupling between the dependencies, the most frequently changing parts recite on boundaries off a system user interface and DB related stuff are irrelevant from the domain perspective, so the domain logic should be independent off irrelevant things. To fix the problem, we need to revert the dependency which points towards the infrastructural layer. On this example, I'll show you how we can decouple one obstruction from another. A fundamental theory. Mawf software engineering states that we can solve any problem by introducing an extra level of indirection. So let's do exactly that to the couple person from the repository. Here's the slide, which reflects the changes made by a simpler factoring we often refer to such interfaces as to seems, these scenes allow us to inject any dependency we want. Which off course implements that interface? This is a simple yet powerful technique to invert the dependencies, achieving low coupling between components. Another interesting aspect. Concerns around time and compile time. Dependencies. Look at the diagram here. Have a module A that goes function F on module. Be through the interface when we use polymorphism creating an interface, inserting it between module A and module B. We end up with that module A has around time dependency on B, but it doesn't have a compile dependency on it. We can compile just more Jewel A. If we want to. Without your compilation of module being in languages like C Plus plus, it helps to significantly reduce the amount of compilation time. That was the basics of what the dependencies are in. The next lecture will take a closer look at two major types of dependencies 36. 04 Volatile and Stable Dependencies: but this lecture is titled Volatile and Stable Dependencies. In the previous lecture, you saw on a simple example how to invert the dependency on the repository by introducing a layer off in direction a logical question, which comes to mind concerns what dependencies should whips tracked away. And to answer this question, the first thing we need to do is to realize that all the dependencies can be divided into two camps. Will a tile and stable dependencies let's define volatile or, in other words, unstable dependencies? According to Mark semen, a dependency should be considered volatile. If any of the following criteria is true, the dependency itself depends on the environment, forcing the cooler to set up that environment. A classic example would be a dependency on a database or any types that imply into reparation with a database. Any other external systems, like Web servers, also fall into this category. The dependency doesn't yet exist and is still under development. This is a regular deal when we want to write code, which, among other things, inter operate with an object in existence. At this point, we don't want to wait that object to be written, so we're just introduced a seam, which reflects the A P I off that object and make calls through that scene. The dependency, which is not installed on all machines off developers and the dependency, has an under 10 minute stick behavior. It can depend on daytime now random numbers generation and similar unstable by their nature . Things in general. We can define stable dependencies as dependence is that are not volatile. It may sound odd, but it quite simple and useful, so we'll stick with the definition. Volatile dependencies are those which will want to abstract away by introducing levels from direction. Since they're unstable, we at least need to have a way to replace them by test doubles in unit tests. Otherwise, we may end up with untested BLE application. Remember that you can treat an application testable until its design allows to write union tests. If an application allows only integration tests, it should be considered untested ble. Let's elaborate the topic of diet be by learning very close terms. I o. C and D I. We will talk about them in the next lecture 37. 05 IoC and DI Definitions: this lecture is titled Definitions Off Fire C and D I. In the lecture where we discussed the notion of dependencies, we saw this diagram. If you look more closely, you'll notice that Mogul A has a relationship off composition with the interface. It means that we need to inject the module B as the implementer off that interface. Somehow, this example demonstrates what is dependency. Injection dependence Injection is one of the most important notions will use throughout this section. So let's separate dependency, injection and dependence inversion principle to avoid misunderstanding off these closely related to each other concepts. There is actually another general term in the version of control, and you also should understand the difference between these term and the previous two we talked about. So let's give definitions to this terms, and we will start from the IOC. Inversion of Control is a very general term, which reflects the motile off relationships between a cooler and a collie. A classic flow of control implies that a client has a full control over the environment and sequence off calls to library methods. The inversion of control implies that Macaulay we can imply any library methods when we say calling. Take the control over some colds between the color and the calling. The simplest form of a new version of control is cold backs. The main idea off a callback is to provide a way for a calling to call a color back. So that's why there is a very important difference between the regular libraries and frameworks. Frameworks rule the client. Coat frameworks provide blocks which have to be just field by clients. Frameworks also have the control over the environment. This is the inversion of control in action dependence. Inversion principle is a more detailed version off the inversion of control notion D. I. P. Concretize is that high level modules should not depend on low level modules and so on. Inversion of control is a matter of principle. In a sense, according to the definition off the dependency injection given by Mark Semen in his book Dependence Injection in dot net, which Air Command to you very much. Dependency injection is a set off software design principles and patterns that enable us to develop loosely coupled code. At the same time, you need to understand that I've see can exist without d I IOC is possible without die because we can change implementation by relying on subclass ing, for example, by playing the template pattern which was discussed earlier. Nevertheless, the main way to perform the inversion of control is to reply dependency injection techniques. In the next lecture, you'll see an example of day P violation. 38. 06 DIP Violation Demo: Here's a simple dama, which demonstrates the essence of a problem. In this case, you have a class named Divergence Checker, and here's what it does you have to physical devices, which are represented by two classes, encounter and fiscal registration. Er, this is a case from my practice in the Russia. When we sell anything, we need to register the selling operation in a special device called Fiscal Registration. ER, in my case, will have a separate device which performs encrypting and decrypting operations and unfortunately, has to double the responsibility off a fiscal registration, keeping all the details about cells in safety. As a consequence, we need to periodically check that there is no divergence between counters off a fiscal registration and that special device represented here by the counter class to perform the check. I implemented this class Right now. This quest logically has to dependencies. It depends on a counter and fiscal registration. ER, these classes directly talked to physical devices in the real world, the game divergence checker exposed more than one public method, but in this case, it's enough to have the only one this method actually checks. If there is a divergence between counters off two devices. This method uses both dependencies. It takes two counters from one device and logically same counters from another device, but then it just checks. If corresponding values are equal, let's say we want to write a unit test for the heads Divergence method. How are we going to do this with the current design, there is no way to write a union test to gain divergence. Checker class is tightly coupled to the counter and fiscal registration. ER, these dependencies are unstable or volatile since they represent riel physical devices. Physical devices are always inclined toe unstable ba hair. That's why we can't write trustworthy unit tests. In the next lecture, we will look at three ways off applying dependence injection to fix the problem. 39. 07 Refactoring to a Better Design Applying Dependency Injection: The root cause of the UN testable design in this case is that this class is dishonest. It lies to its clients. It lies about the fact that it has to. Dependence is it lies by hiding them. The, um, first way to fix the problem is to make dependence is visible. There are three major ways to accomplish that Constructor injection, property injection and method injection. Constructor injection is when the request dependencies to be passed via the constructor. So the obvious reflector and can be done is this. The first thing we need to do is to create a scene which will serve as a boundary between the main logic and external devices. Now we can continue our re factoring process. Now a client can't create the gain dear against Checker without thinking of dependencies. A client sees them and has to decide what to Passan. The responsibility is shifted to the client's side and this is good. Now we can write a unit test replacing these dependencies by test doubles which are under a full control of clients code. Before writing a unit test. Look at the other two options property injection and method injection. Firstly, let's look at how called Luke lack with a property injection. - The difference between this option and the previous one is that the clients code can reset the dependency whenever it likes at the same time. From the perspective, a client now can create the gain Divergence checker and forget to set the dependencies. After that, it can call that has divergence, method and face than other reference exception. It means that the encapsulation of this class is broken. It doesn't provide guarantees that its methods will work as expected. Another option is to request the dependencies in the method where they are needed. It may look like a little bit weird, but it is absolutely valid option. In this case, the clients code will be unaware of any dependencies until it calls the method. This design preserves the encapsulation. It provides guarantees that they has divergence. Method works as expected. In any cases. Let's write a unit test, which validates the correctness of the heads Divergence method grade . The death passes. In this lecture, you've seen a simple example of applying the dependency injection techniques there indeed, really simple. In larger examples, the techniques will remain the same before continuing. I want to give a summary off the three day techniques we just applied in the next lecture 40. 08 DI Techniques: this lecture is titled D. I. Techniques. Constructor injection implies that dependencies are going to be passed in via constructor. The most beneficial aspect of constructor injection is that it protects the in variance of the object the object wants. Create will always be invalid state. However, you should be aware of the following possible pitfalls. In large systems, constructor injection tends to a camel. Eight many dependencies. You may see more than three dependencies requested via constructor. However, this is not the drawback off the constructor injection itself. Most likely, this is a smile of violating this R P. In case a constructor requires more than three or four dependencies to be passed in, consider the possibility to extract any responsibilities into separate classes. Sometimes it happens that several dependencies tend to be passed in together. Here's a code snippet, which shows that if your model takes for dependencies and imagine that many other view models take the same dependencies as well. In such cases, it would be wise to create a container object for them and require that containers object to be best in the constructors. Seems like it has no effect, but it is always a good idea to join objects which go together in many cases. One day you want to introduce a custom validation mattered, which is related, told the dependencies or something like this, however most likely more than for parameters is the smell of this Artie violations, I said. So take a closer look at the responsibilities of a class which requires so many dependencies. Another interesting case concerned this, so to speak. Non obligatory dependence is like a logger. It's a valid solution to expose several constructors, some off which said the default implementations off the dependencies. You can see here an example. In this case, you may replace in the unit test the I A logger By a damn, it is double which it does nothing while in the production code, clients can just use the default constructor, since in the majority of cases, no one cares about the logging mechanisms. Another beautiful you might stumble upon is that such frameworks, like the entity framework or other object relational mappers, may require from objects to have a public default constructor. In such a case, you will be forced to expose the public default construction. Otherwise, you'll get an exception in the round time. Of course, you can consider writing a wrapper around such an object, which stands very close to a bounder of a system, thus preserving the encapsulation. If a certain dependency is used only a single method, then consider removing that dependency from the constructor and requested as an argument of the method which certainly needs it and can't provide it serves without it. In other words, consider to use the method injection property injection implies exposing the dependencies via properties with public setters. It allows to replace the dependency during the entire lifetime of the object. The flexibility is the main advantage. In this case, however, the drawbacks are so heavy that we should strive to rely on this way of injecting Onley in case of non obligated. Independence is such a Slager's. In such cases, there should always be default implementation off the dependency, and it should be set in a default constructor or right in the property. Do you see the example on the slide? This golden additional relies on the sea shop. Six Feature off property initialization. In any other cases, you should avoid property injection, since it easily can break the encapsulation off a class and make the dependence is hidden. Independence is exposed as properties are hidden because no one is obliged to remember all the internal details of a class method. Injection is an interesting technique. Dependencies, which are set fire properties, or constructors, are usually used by many methods throughout the lifetime of the object. However sometimes and implementation lee vary from one call to another call or if the method is static, for example, the conversion of one currency to another requires an object which gets the rate. A similar example is the I format provider, which is required in such methods like double bars. However, think twice before implementing method injection. If you want to pass a dependency directly to a math. Just because Onley that method among 20 other methods uses that dependency, then this is a smell of a syrupy violation, maybe a separate responsibilities hiding inside of the glass. Another problem with this approach is that IOC containers can't automatically inject the dependencies. Two methods I see containers are tools which helped automate the process of dependency injection, and we will discuss it further in this section. Okay, now we got the idea of dependency injection and three major techniques. These simple techniques have fundamental implications off course. In the rial, live things can be slightly harder than was selling this lecture. The problems, it beauty, the architectural level. Let's talk about architectural implications off the inversion of control Independence injection in the next lecture. 41. 09 Architectural Implications: this lecture is titled Architectural Implications. Inverting Dependence is is the means by which we create boundaries between software modules . When we want to create a boundary, we choose which dependencies to invert against the flow of control. So all of them point in the same direction across the boundary boundaries, like on this slide out of the way we create bludgeons. A plug in is a module that is anonymously called by another module. In other words, of the collar has no idea who or what it is calling in this case. The module it doesn't know it calls the module. Being bludgeons can be deployed independently and moreover, their independently develop a ble. We divide the system by boundaries and then invert. The dependence is that crossed those boundaries so bludgeons defining the boundaries off your system. The old model of building software systems with three tiers is that data centric motile in such architectures of the database and that schema is the center of the system. It drives all the other parts of the system. Frankly speaking, this approach is still alive and sometimes could be beneficial. But now days were inclined to treat data basis and your I s tools, which can be replaced in data centric architectures. A significant part of the main logic is going to be implemented at the database site so it will be implemented in stored procedures with a language like sequel. The major problem with this approach is that data processing related languages like Sequel , which are very efficient in processing off pupils, were not designed to implement business logic at least significant chunks of business logic . Database related languages are very poor on features which allowed to motile relationships between domain objects. This is one of the major reasons why the worldwide community of developers shifted to another approach where the database is treated as a low level detail. And here we reached the point when we continue to analyze the implications off the architecture based on plug ins. Here is a diagram where the domain is in the center. When we treat database and you wise tools, which are mostly irrelevant, we come up with the idea that the core of fine application is the domain logic. Demand logic is the most stable part of the system. Seems domain policies changed relatively rare. For example, the right part changes far more frequently. Notice that all the dependencies point towards the domain. If you enlarge this diagram, assuming that these big lairs are comprised of many objects, you'll get the following diagram. I've got this diagram right from the block off Mark Semen. I noticed that all the dependence is still point toward the center off application. If you enter the layers to this diagram, you'll end up with the following. This diagram depicts what architectures call onion architecture. There are other similar notions, such as hexagonal architecture and ports and adapters. Architecture. All these terms mean essentially the same. They're all about the same ports. All those seems we introduced by extracting into faces and adapters are plug ins, which come from the bounder off a system in large systems. The graph of dependencies is very large, though you should strive to keep the graph s flatter as you can, even if you keep the graph flat. You also can face the problem off controlling the lifetime of dependencies. This leads to an interesting question. Who is responsible for keeping the control over the dependencies instance, see ation in their lifetime and then swore is obvious. Any application starts from the main method. Developers often refer to Maine as not to a physical entry point, but as to an infrastructural point where all the relationships between dependencies should be set up. The idea off setting up all the dependencies in a single place in Maine actually conforms to the single choice principle that was discussed in the OCP section. Maine is the single place which knows everything about the penalties in their relationships . It doesn't necessarily mean that all the dependencies will be inst enshi ated in Maine. Some of them may be instance she hated in Maine. Indeed, the other will be automatically created in the run time, according to the set up made in the main partition. In this lecture, we figured out that the main is the infrastructural point where we set up all the dependencies. Now we need to understand how to set up them in practice. In the next lecture, we will look more closely purity. I and I see containers. They're related to two major techniques which allow to set up the dependencies and inject them properly 42. 10 Pure DI and IoC Containers: this lecture is titled Pure D I and I've see containers. Hopefully, now you understand the possible difficulties you may face applying the dependency injection techniques. Basically, there are two ways of dealing with dependency injection. The 1st 1 is to manually create all the dependencies and dependencies off dependencies and inject them explicitly by calling the new operator passing in the constructor. All the required dependencies Mark Semen, referred to these manual approach as to the so called poor man's die in 2014 Mark seemingly retired this term, replacing it by a new term pure die. The reason was that poor man's D I sounded slightly derogatory or a t least unattractive. It also didn't communicate the message that die without a D. A container is in many cases better than the eye within IRC container. On the contrary, it sounded like it's not as good. That was a citation from the Mark Seamans Block, Bost. I'll show you an example of pure die from a booking application or written by Mark Semen. You can see here in the main lots of code. This is ah known trivial example, which demonstrates how difficult it can be to set up and track all the dependencies manually by relying on a pure D I. That's why we have full fledged IRC containers. Let's get back to slides the second way of dealing with the eyes to rely on an IOC container. So what is an IRC container or a D I container? In other words, I see container is a framework which helps to apply dependency. Injection. This is the main feature of Fannie ice container. I see container injects dependencies automatically off course containers provide the ability to set them up by configuring those dependencies. So when the clients code asks a container to resolve a particular dependency, a container knows how to create that dependence. It knows how to create the dependencies off that dependencies soldier coercively creates Alden accessory dependence is until it creates. They requested one. On the slide, you can see a diagram of type dependencies. Imagine that we make a call to Nizer Container to resolve the main of your model. In other words, we want from a nurse a container to get an instance off the main of your motile class. The main of your middle class depends on the I customer into face. He takes this interface in it's Constructor. So to create the main view model, the IOC container will look further To find out how to resolve the I customer interface, the container will find the customer class which implements that customer interface, so the container will try to create the customer quest. In order to create the customer class, the container has to pass to its constructor that I customer repository since the customer class depends on this interface to resolve the I customer repository, IOC will continue to dig deeper and find the implementer of that interface. It will find that I customer interface can be resolved by the customer repository. But to create the customer repository the container and need to resolve the I. D be Gateway seems the customer repository depends on it and finally dies. The container will create the DB gateway and after that container will create customer repository than customer and then the main of your model. So this is how our sea containers a recursive lee resolved dependencies. This diagram doesn't show the IOC container itself. If we put here, there's a container class. It will depend on all these types. It has to know about all the dependencies. It is the job of the container, its responsibility. In the next lecture, I want to quickly demonstrate you how to build a naive implementation off a simple IOC container to clarify the basic mechanism of how they work. 43. 11 Building a Simple IoC Container: Let's implement a very simple I see container. At first, I will define a map between types. This map will contain a 1 to 1 relationships between dependencies. Here it is off course. We need to expose a public method which allows to clients to register dependencies. This is a generic method which takes two types and add them to our map. There is nothing else to explain. Let's create a public method for resolving dependencies. This method is also generic. The T parameter is the type which a client wants to be resolved. This method calls another method which will be private and implement all the logic off the container. Here we get the corresponding type from the map. If we didn't find it, we throw an exception. Notice that we have a type. This is not an instance off a type. It is it's descriptor. I see containers used a reflection heavily. Without reflection. It is impossible to analyze type dependencies and create them properly, having a type we can request. It's constructors. We implement a very simple IOC container. So for the sake of simplicity, I just get the first constructor off a type having descriptor off a type we can request its parameters. If there are no parameters, we just create an instance off a dependency and return it. Otherwise, we need to resolve them. Recursive Lee. So we need to do the following this cold recursive Lee tries to resolve all the constructors parameters. In the end, we want to create an instance off a dependency, so we will call the constructor passing the parameters. Here we go. Trust me, This is a very simple RC container. Nothing more, nothing less. Let's try to use it. Let's say we want to resolve the main view model. I showed you on the diagram in the previous lecture. Before resolving the main you model, we have to set up the IOC container. So we're registered. Dependence is one by one, Main view model is mapped to itself into faces are mapped to corresponding implementer Z. After that, we can resolve the main view model grade. I said a break point and leads to buck the program to ensure that everything works fine. Yes, you can see where is the brake point. And if I hover my mouse pointer over the main view model instance. I see that it was created successfully. Everything works fine. So that was the essence off any. I see containers. In the next lecture, I'll show you an application which is built with NRC container to demonstrate how real world scenarios may look like. 44. 12 Demo of a Real World App Built with an IoC Container: here are implemented a simple application which allows to manage the least off students. The solution consists off several projects. The students manager is a WP F application which contains views, and I see container bootstrapping. If you want more granularity, you can keep the bootstrapping face in a separate assembly. Indian framework is the framework which supports the MVV n pattern and in this case provides a simple eyes, a container. Let's look at the application were closely this application support simple crowd operations . This is a WP F application and it is implemented with them V V M Pattern. This better implies three parts motile view and via mobile views are represented by example files. So views represent the why each of you has a corresponding view model named accordingly. For example, the main view has the corresponding main of your model. The elements are bound to properties and methods off a corresponding view model. This is achieved via special mechanism in WP F called data binding. For example, if we user clicks add button on the main view, that call will be handled by the ad student method, which belongs to the main view model. Replication is built with help off a small framework, which I also wrote by myself in order to demonstrate how frameworks provide. Those seems for blackens notice that the main view model requires three arguments to be passed via constructor. The first dependency is the interface, which allows to perform crowd operations over students. The database, in this case is represented by an XML file. For the sake of simplicity, I haven't aggregator allows to pass messages between any components off a system. Again, these details are not very important to our discussion. The last dependency represents a scene provided by the framework it allows to open and close new views from within view models. When you build an oblivion based application, you have to connect views and remodel. Somehow one major way is to Instead she ate a view and then of you model and another one is the opposite. At first creative you model and then locate, and instead she ate a corresponding view. Our framework supports both models. Let's look now at the framework and how our application is getting bootstrap. This framework. It is the framework who allows to automatically wire up your models, connecting them to views for providing this feature. A framer has to know which assemblies to scan through searching for a corresponding of your model. The search is based on the naming convention. If a main view was created, then a framework will look for a man of your model in the assemblies. Added to this leased by the application which relies on this framework. Here is the chunk off gold, which scans through assemblies and searches for a view model and now the most relevant part regarding our topic. The bootstrap ER base is a big seem which is exposed us an abstract glass which has to be implemented in the main off. The application which wants to rely on the framework this seem, allows framework toe automatically resolve dependencies e g. Create and insert implementer Zoff interfaces. Select assemblies should be overridden by the client. It should return a full list off assemblies which contained dependencies. But they get instance, is an abstract method which will be used by the framework to resolve the dependencies. So a client should override this method using an IRC container it wants to use configure for on time and configure for design time should set up the icy container and they have to be written by a client. The main method of a client should call a start method which sets up the framework. This method sets up all the internal things off a framework. And then you also can notice that the method off resolving is assigned to a state of public field off the IOC class. This class represents a service locator. With this class, you can request to result for dependency from any place you want. This is need because there is a couple of places in the framework where these method is used. Otherwise, the framework wouldn't have access to the mechanism off the penalty. Resolving provide by client. Remember that you should call the container only from the infrastructural code. If you explicitly call the air seen clients code, you must likely hide the dependencies. Let's look at the client's side. Declined inherits from the boat stripper base. It uses the old and powerful RC container named Castell Windsor. The Windsor container is defined as a field. The select assemblies returns to assemblies, assemble off use and view models. The configure around time instance shades the container, but then it registers the first dependency by using the Windsors AP, I will say that if a container will be requested for resolving the I data provider of student, it should pass the Students XML provider as the implementation of the generic interface. Also, we say that creating the students XML provider a container should pass the students rap about XML String as an argument to the constructor. I've Integra, Gator and I window manager are registered afterwards. They're registered the same way except one detail which concerns their lifetime. The Lifestyle Singleton method ensures that the implementer Zoff these interfaces will be created once and after that, the same instance will be passed everywhere. I haven't aggregator or I window manager I requested. So they're singled us and they will leave throughout the lifetime off the application until the applications domain is unloaded. In the end, there is a call to the register of your models method. Look at it. This method adds to the container all the classes whose name ends on view model. This is how the architectural with plug ins and the rappers is implement to understand around time execution flow. I'll show you the following diagram application model is defined by the W pair framework. It defines a startup event. That application subscribes to it and the handler can be treated as the entry point or the main method. This handler creates the bootstrap ER, which inherits from the stripper base, defined in our small, um, Vivian framework. And it goes the start method. The start method calls the config around time leads to the process off setting up the icy container. The Castell Windsor in our application WP of provides the point where we said the first view which has to be opened. I just didn't show you. I said it to a special infrastructural of Yukol shell view. This view is a user control which costs other views. Shelve You uses a special auto wiring mechanism, off view models provided by the Indian framework. Since all the dependencies and all the assemblies are well known for the Indian framework, it is a little Cades. The shelve your model and created why there's a container. The show of your model automatically creates the main of your model of I I C, and the corresponding views created via special WBF mechanism off data templates. It's okay to use are seeing the shelve your model. Since this of your model is pure infrastructure, it is responsible only for switching the views on top off a shell view. At this point, the application is started and the main window is visible to the user. Now when the user clicks on, for example, on the at student Parton, the View model calls the I Window manager, which is a part of the Indian framework, passing to the type off a view model. The corresponding view off, which has to be opened in case off at student there would be passed the edit student of your model. And here the framer comes into play. It creates the requested view model. Why that I have seen then it locates the view type and creates it. After that, it connects view model to review by setting the data context off the view toe the view models instance. Finally, the framework calls the W pay for method show on the window to make it visible. Here's the execution flow. Notice how frameworks provide many ports for the clients gold, which says them by adapters implemented on the client side. The clients code defines the business logic Framer does its own job by providing all the required infrastructural features. Their sea container takes the responsibility to create dependencies and manage their lifetime. Each part does its own job. Very nice. If you want to change the persistence mechanism, no problem Just implemented I data provider and set up the I. C s u need and you're done. No problems. This demo shows how real world applications maybe structure you condone, Lou the source gold of this application and started this example on your own fuel three. To debunk the application and look out is built in depth before moving to conclusion. Let's sum up what we've learned to mark out some common smells off jp violation. 45. 13 Common Smells of DIP Violations: This lecture is titled Common Smells of the AP Violation. All the common smells of day P violation take their roots from the day p definition. The I P clearly states that high level policies should not depend on low level details, So the common smells are the following. A close explicitly creates one or more dependencies hiding them from a client. A class uses non deterministic dependence is like daytime or random. There are ways to the couple such dependencies, which often come from the dotnet framework itself. One way is to create a class which works with non deterministic dependencies and cover it by integration tests. And another option is to create some kind off adapter. I mean, create your own interface and implemented in a custom class, which uses non deterministic dependencies. Then you can use that custom interface in the production code and replaced by test doubles , which are under your control In unit tests, a class uses stated dependencies very often. They're Singleton's single con's make unit testing. Very difficult. Stated dependencies off a class are also hidden from a client, so if a state of dependency was not properly instance, created than a class will most likely behave itself incorrectly throwing exceptions. And so this forces clients to remember about hidden dependencies all the time. This is almost always a bad thing. The main idea off removing the D I. P smells is that you need to extract a layer off in direction on Make the Class, which, while is the D I p dependent on that layer off in direction. Another principle, which often helps, is the single responsibility principle. Adhering to the SRP often helps to avoid extracting off useless interfaces. In the next lecture, we will summarise what we learned in this section. 46. 14 Conclusion: This lecture is titled Conclusion. In the section you learned what is day be day be implies that high level policies should not depend on low level details. There there are two major types of dependence is stable and unstable or volatile. Unstable dependencies are those to which we won't apply the inversion of control. What inversion of control independence injection are and how these notions are related to the D. I P and to each other. Three techniques of dependency injection constructor injection, which should be used in 95% of cases, and property and method injection that adhering to the D. I P. Leads to a plug in architecture, which is commonly referred to as the ports and adapters architecture. This led us to a conclusion that there should be a single place which knows everything about application, dependencies and their relationships, and this place is made. We also learned that manual dependency injection may become tedious and that's why I see containers exist, which helps to simplify dependency injection. In difficult cases, you learn how to build a simple icy container, and you saw an example off a real world application which relies on an icy container and sets it up in Maine. And we also summarized what the common smells off the Diaby violation exists and how to fix them. This section is the last one in this volume, which covers the last principal off the solid acronym. In the next volume, we will discuss the matter principles and how they're related to solid principles. I'll be waiting for you in the next section. Thank you for watching. 47. 01 Outline: Hi. This is the last for fun of baking engineer spot. And in this section, we're going to learn where the principles are. We refer to the principles we're going to talk about in this section as to matter principles because they are the roots off all the other more concrete principles adhering to which we're actually trying to conform with the matter principles. We will start from the dryer. Don't repeat yourself principle. You learn the definition of the most common smells of violating the dry principle. After that, you learned the keys or keep it simple. Stupid principle. Here we're going to talk about simplicity and complexity, accidental and essential complexity and how to achieve simplicity. The next meta principle we're going to talk about is the young me or you ain't gonna need it principle. It is related to the needless complexity smell and concerns the anticipations off common features. We will look into practical problems which we face and what other consequences off implementing features we actually don't need. After that, we're going to talk about the sock or separation of concerns principle. This principle underlies incense. All the solid principles. Separation of concerns is very important for achieving well maintainable applications. You'll see the most common ways of violating the separation of concerns. Principle Command query separation principle makes easier to reason about. The code will discuss the low of Demeter, which is the principal off list knowledge. Separately, we will talk about the principle off least astonishment you. Then we will touch the topic of information hiding and encapsulation. By the way, I will use the word principle instead of matter principle in this section. Further, just for the sake of saving some time in the next lecture, you learn about the dry principle. Let's get started. 48. 02 DRY: this lecture is titled Dry Principle. A substantial number of box in software are caused by repetitive code. If you have 10 functions which do the same, and you need to change the behavior of such a function, you'll have to modify all 10 functions. So the definition off the dry principle was formulated in a famous book, The Pragmatic Programmer by Andy Hunt and Dave Thomas. And it sounds like this. Every piece off knowledge must have a single unambiguous representation in the system. This principle concerns all the different aspects off software it can be applied toe any programming code or database schemers or anything else, including documentation of the most common ways of violating the dry principle are the following magic strings or any other magic values, duplicate logic in multiple locations and repeated give than logic or multiple switch cases scattered throughout the code base? Let's look at examples. Look at this example. You don't get the response from a device, then we compare the results with 188. Such magic values tend to spread over a class which Inter operates with the device. This is how duplication appears. A side of the duplication who knows what 188 means toe understand the meaning of the code? We need to read the documentation. Wouldn't it be nice to define a constant with a meaningful name? This constant can now be used everywhere we need. It is now clear what 188 means. It means that there is no connection with the device. Here's another example. The similar situation here We see that magic values started to spread aside from the fact that it is absolutely impossible to understand what's going on here. And the dip location may lead to unfortunate consequences. For example, if one of the duplicated values is going to be changed, then you're going to change that values everywhere. It was used to fix the problem. We can apply the same technique defining constant values that become the single sources off change. I defined constant values only for duplicated values, but most likely I would do the same for all the other values. Now it's apparent that commands at first initialize a device than send a command, and after that, closed the device. Here's the same example. What's wrong here? We fixed the duplicated magic numbers, but what can be enhanced. In addition, we have the duplicated logic here, and it is not to speak that there can appear 10 new methods with the same pattern off sent commands. Look how we can reflect her. This coat I extracted a method which removes the duplicated logic by taking the responsibility off, wrapping actual commands by initialization and termination. The benefits might be not others, but in case off more than three methods, benefits would become of this. This is a simple example of duplicated logic. There is much more interesting case related to duplicated logic. The question is, Is that true? That duplicate logic is always a bad thing, and then, sir is quite interesting. Imagine that you develop three applications which belonged to the same domain. Logically, such applications would have significant similarities in the functionality they implement. This fact logically leads to a natural desire to create a shared library, which contains pieces off functionality. That is the same for all the three applications. As you remember, every piece of knowledge must have a single unambiguous representation in the system. So if you implement the same functional knowledge thrice wants for each application, then seemingly you violate the dry principal? Yep. Now let's consider the following case. From my practice, we had three applications which shared the logic of the following function. Here we have a class with three properties and the function which checks give the card is valid for some time. This function worked well for all the three applications, but one day one of the applications changed. The requirements is required to check first name and less name as well. Implementing another function for that particular application would be considered a violation of the drive principle. So a decision to introduce a bull flag was made. And here is the second version of the same function. Cool. We preserve the ability to use the same function all over the code base. Peace has settled down and we continued our work for some time. Everything was okay until one day when Boss said that there is another requirement from the third application. The third application now can allow ideas to be longer than 10 characters to preserve the ability to use the same functional over the code base who introduced a new Boland flag. Here is how the new version of that function looked like. Yeah, yeah, I know this function turned into riel Mass, and this is only the beginning. If you start to apply solid principles and all the best practices to avoid this mass, you'll often end up with a separate implementation for each application. Often not always. But often it's better not to share your logic between applications. It's better to grow that logic separately, at least until you get absolutely sure that you can merge the same implementations. Indeed, there are cases when we are 100% sure that particular business logic will never change. Or the probability off changes is extremely low. If semantic is different, don't merge the code, which looks like duplicated code. Let's look at another case when duplication is actually not a duplication at all. Here's an example, by the way, this example is also from my own practice. Questions are just named differently. You have two classes which were president, different devices. Both of them have the same data properties. A junior developer from our team decided that this clearly violates the dry principle, so he decided to extract the same data properties into based glass. He came out with the falling reflected version of this code. Here's the device glass, which contains the duplicated properties. Now all the devices will inherit from the glass and the dry principle is Matt. Unfortunately, that was a bad decision and there are several reasons. The first reason is that it's hard to believe that all the devices will share the same properties. I'm pretty sure that L S P is violated by this her factory. The second reason is that now we have a strong coupling between based class and inheritors . And actually, I don't see where the benefits of such inheritance friendly. It's a very rare case when inheritance off data is a good idea. You know, all languages, objects are comprised of public functions. The data should be hidden. The third reason is that the first intention was wrong. There was no any duplication. The fact that toe objects have the same data properties doesn't make them similar. What makes the object similar is their behavior. So there's no need to couple objects which have different semantic. Vladimir Horcoff even came out with the notion off utility inheritance. Vladimir Horcoff, there've uber off this video course even came out with the notion off utility inheritance, this example demonstrates exactly that evil technique. On the slide, you can see the reference to the block bossed about utility inheritance. Take a look at this code here have an enumeration off shapes and the Visualize ER class, which defines toe operations. There are only two operations just for the sake of simplicity. In the real world scenario, there would be many classes which used that in, um, orations and dozens off methods filled by switch cases. So which cases on the same in admiration, which are scattered all over the code base, is one of the worst nightmares. You may senior life when some kind of the behavior aspect changes regarding one of the enumeration of Alice. You have to find all the places in the system where switch cases are implemented and change the corresponding chunks of code. If you add a shape, you have to find all the places with switch cases and modify them, adding cases for that new shape. This is a true evil duplication. How to fix the problem. The open close principle is answer. You can define the base glass and turn the enumeration values into inheritors represented by classes. If something changes, you have a single place where you need to make that change. Now the client code can just rely on the base shape glass. No switch cases scattered all over the code base. Remember that repetition and logic calls for abstraction. Great. In the next lecture, we will study the kiss principle. 49. 03 KISS: this lecture is titled Kiss Principle. Have you heard the statement off Albert Einstein? Make everything as simple as possible, but not simpler. This statement is the essence of the kiss principle. Kiss means keep it simple, Stupid. The more a system complex, the more possibility that it can break. Therefore, simplicity should be a key goal in design and on assessor complexity should be avoided while young me you ain't gonna need it. Principle is about removing an assessor coat kiss is all about how to make the implementation as simple as we can. So the statement of this principle is a simple solution is better than a complex one even if the solution looks stupid, the principle is deeply philosophical indeed, just trying to come up with a true definition off the simplicity, how to define and measure the simplicity the straight forward definition would be the following simply cities the state of quality of being simple. Don't you find such a definition not were helpful? I do. What does it mean to be simple? Seemingly that the only way we can treat the simplicity in software is that something which is easy to understand or explain, Can be considered simple. In contrast to something complicated. It's very hard and sometimes even impossible to come up with a simple solution that solves a difficult problem. The complexity off implementation tends to grow along with growing number off requirements , so the feeling off simplicity is relative. The main technique we used to struggle with complexity is the decomposition, and by the way, the composition is the aspect, which is strongly related toe almost all the solid principles. Adhering to the SRP, we apply the composition to the coupled objects or modules, confirming with the gossipy not always but often involves the composition as well, especially when we need to create a new type toe isolate source of change into face segregation. Principle is all about the composition. Dependency in the version is all about making the system world too composed. The list of substitution principle is mostly about how to avoid bet decomposition so of the soul. Principles are aimed at achieving solutions as simple as possible. On the other hand, abusing solid principles always lead toe on accessory complexity. This is the true manifestation of the unity and struggle off opposites law. It resembles me, a herb called value. Aaron Valerie in has sedative qualities, So when you take the Lear in Aceh medicine, you expect to become calmer at the same time. It's a very well known fact that if you take too much off while you're in, it will cause the feeling off anxiety. The fact will be the opposite. The problem off simplicity relative nous leads us to two related notions. Accidental and essential complexity. I said earlier that complex systems are actually complex and you can do nothing about that . You can't implement the software of bank system and expect that it will be a simple as a solitaire. The complexity imposed by the domain itself is called the essential complexity. The essential complexity cannot be reduced by any means. The only way how essential complexity reduces is when the domain rules change in the direction of simplicity. Unfortunately, you barely can enforce such changes. Accidental complexity is the complexity off our solutions, which are intended to solve the problems off the domain we are responsible for. The accidental complexity is the developers. The design of the software optimization are all related to accidental complexity. Kiss is fundamental philosophical principle, so we can mark out the following rules, which of course, are not dogmas. I prefer composition over inheritance were possible. Stick with if Ellison's, which gave statements until you see that you need to introduce polymorphism, avoid bringing to optimization in 90% of cases. Slower solutions work enough fast Exceptions from this rule is when you know for sure that you are working on a very complex software, one of the main aspect of wishes. The performance when the performance is absolutely critical. Smaller glasses and smaller methods are batter. The best method is a one liner, Google. For the technique, which is called extractive you drop, which is about methods re factoring. Don't rush to extract utility classes for private methods which are used from a single place within the class. Leave it s cities until there are other parts of code. Will require that method as well. Don't write perimeter arised. General methods prefer methods which solve a specific problem. Divide and conquer. This is a principal aimed at solving complex problems. Divide the problem into smaller problems and solve them one by one. Strive to avoid comments. Comments mean that you failed trying to express the intent in programming language, right brother types, And don't be afraid to throw them away. Keep the number of fantasies which solve a problem roughly from 5 to 7 humans. Mind is not good at keeping in memory. Modern seven things simultaneously, Constantly working. Simplifying your code base. Uncle Bob Martin even suggest a rule that before making a check in, you should always ask yourself whether the code base is better than it was before you checked it in. This is the rule off a Boy Scout. Optimization is the main excuse for writing complex code, but strive to keep the amount of such gold closer to five or 10% of the code base, not more. Optimize only if you're absolutely sure that there is a performance problem. Don't measure the performance by your I rely on special tools for tracking the performance . Remember that there are two values off software. The 1st 1 is that software should work correctly, and the 2nd 1 is that the software should be designed well, and the 2nd 1 is much harder to achieve them. The 1st 1 in most cases. The next principal we're going to talk about is the young principle, which stands for u N Gonna needed This principle is similar to the kiss principle. In the next lecture, you find out what is the difference between these two principles and what Yogi means in practice? 50. 04 YAGNI: this lecture is titled Yardeni Principle. The Power people are always looking for ways to make all around them as much powerful. It's possible developers are also people, and they also tend to make all the program code as general as it can be. For example, when a software developer has a task to create a simple library for generating simple income outcome reports, he will allow the whole general purpose library for generating any possible financial reports. I need to parse one key value pair from a custom buying a reformer. What am I doing? Correct. I'm writing the whole damn sparser with handling all the possible cases. Yeah, Agni means you ain't gonna need it is all about avoiding over engineering, he Agnese strongly related to what we discussed earlier in the course. Do you remember the smell called Needless Complexity? Yeah, Detail says that we should avoid this smell. Do you remember our talk about anticipation of upcoming changes? Anticipating upcoming changes, developers start to introduce points of extension. The problem is that it might happen that all those points of extension will never be used. Points of extension have their cost. They're not free. They make systems more complex and therefore harder to understand. Yeah, Guineas. Deeply philosophical principle. There is no well defined criterion, which allows to measure the young neatness of the system. If you look at Wikipedia, you'll see that Young is a principal off extreme programming, or XP. In short, that states programmers should not add functionality until deemed necessary. As a type of federal software development, extreme programming advocates frequent releases insured development cycles, which is intended to improve productivity and introduced checkpoints at which new customer requirements can be adopted. XP, co founder on Jeffries, has written. Always implement things when you actually need them. Never. When you just for see that you need them, you have knees. The principle behind the XP practice off do the simplest thing that could possibly work. Another interesting concept, which is also strongly related to Young Me is called Worst is Better. Also known its New Jersey style regarding software development. Worse is better implies a model of software design and implementation, which has the following characteristics. Simply sitting, the design must be simple, both an implementation and interface. It's more important for the implementation to be simple than the interface. Simplicity is the most important consideration in the design correctness. The design should be correct in all observable aspects, but it is slightly better to be simple than correct. Consistency they design must not be overly inconsistent. Consistency can be sacrificed for simplicity in some cases, but it's better to drop those parts of the design that deal with less common circumstances than to introduce either complexity or inconsistency and implementation completeness. The design must cover as many important situations as is practical. All reasonably expected cases should be covered. Completeness can be sacrificed in favour off any other quality. In fact, completeness must be sacrificed whenever implementation simplicities. Joe pard ized consistency can be sacrificed to achieve completeness if simplicities retained, especially worthless is consistency off interface. There is a problem with all the matter principles. The waste we can follow them and apply on practice are vague. The only thing we can do is to discuss the young name or details. But in the end, our discussion will also contain such hard to measure things like complexity of software. For example, consider the following sentence from a block off. Martin followed. This is a good sentence, which makes clear the meaning off. Yeah, Agni, but it's still not so easy to apply in practice. Here's the sentence. If you do something for a future need that doesn't actually increase the complexity of the software, then there is no reason to invoke your acne. But the complexity of the software, the question arises. How the hell am I going to estimate the complex nous before looking at a couple of examples of playing? The principle also want to stay that you shouldn't adhere to any principles blindly. For example, if you blindly adhere to the young me, you'll end up with these organized cold and will face sooner or later the necessity to perform a massively work. So you have to heavily rely on several other practices, such as continues for factoring, continues automated unit testing and continues integration to avoid negative consequences. The Agni depends on supporting practices, and this is stated in the original definition. In extreme programming. Let's consider two cases when we can apply. Yeah, Agni, I'll call the first case of high level one. In the second case, I'll call a low level. Imagine the situation a team is working on the payment system, which Inter operates with many devices, such as going dispensers, Bilic, sappers and so on. There can be many models off any type of those devices. Working on a current version, you need to implement a driver for Inter operating with models e off a bill dispenser. At the same time, a project manager expects that in four months they will need to support the Y model off a bill dispenser. It's a temptation to implement that expected model in parallel with the Z model, to avoid task switching in the future. And by the way, it would be great to say to Boston the future. Hey, we'll write it down it when the time to implement the white model comes. Deciding to implement such presumptive features is a classic violation off the Agni principle. Do you realize the possible financial wasted in the case that motile will never be needed to be implemented? The cost of Butte is comprised off all the efforts spent on analyzing programming and testing this now useless feature. Okay, imagine that the project manager was right about that feature. Do you think that there is no cost of such a decision? The thing is that implementing that expected feature you still Time, which could be spent on other really needed features. This is a cost off delay, since other features will be delayed. The delay will be equal to the time spent on implementing that expected feature. And this is not to say that you initially could be wrong, and that feature could never be needed. And this is no then, and other cost of implementing features were anticipate being in demand in the future by using a crystal ball for fortune telling. Is the coast off Clery? Very often, additional code makes the system hard to understand, maintain and modify. So if you also need to implement a really needed feature, which depends on that cold related to devices, you likely spend more time to implement it. And this is not Then there is a very unfortunate scenario when the necessity off a feature is correctly forecasted. But the implementation of the future is wrong. When the times comes and you realize that a feature is implemented, not us expect by clients. You'll face yourself in a situation when you have a wrong feature, sometimes completely wrong, and you have to make a hard decision whether to throw away the current implementation and er implement the feature completely from the ground or to invest resources into the repairing of the existing wrong implementation. This is a very hard dilemma. It's hard to estimate whether you should rewrite the feature or to repair the existing one . Martin father came up with a great skin, which demonstrates all the potential problems related to young violation. The example we discussed is the high level case and you, Agnese much simpler to apply on this level, though, of course, even at this level, sometimes we make mistakes. Another case is low level and it concerns every day choices we make in the process of coding. For example, imagine that right now you're writing a function within a class which needs to parse a number from a custom string retrieved from a plastic card. You basically have two choices. One is to just implement a separate function which passes that string within that class you're working on right now. The second choice and this is the way which was by default very often is to implement a passing function and extract the utility class which contains the passing function This sounds logical. Seems we may anticipate that our colleagues might also want to use the feature off parsing from other parts of the code base. I don't want to answer this question in relation to this particular case. I want to answer the question. Generally, there is a simple algorithm which helps to make a right decision in the coding process and in such situations. First, ask yourself if the function or a future is needed to be implemented right now. Events were is yes, then implemented, you have The answer is no. Ask yourself another question. How many efforts will it take to implement that function or a feature in the future? In the case, it will be required. If the answer is, it will definitely be very simple. Then keep all the things as they are. Don't introduce anything additional. If the answer is, it will take enormous amount of time to write many things to tweak the design to make it enough supple to introduce that feature. Then consider to perform summer factions, which allow you to avoid massively writings in the future. Remember that neither gile practices nor any matter principles imposed the idea to avoid planning. On the contrary, you should always carefully plan what you'll need in the future. And what resources and efforts will it take from you to meet new requirements again? It doesn't mean that you have to perform a big up from design, but it owes. Doesn't mean that you have to forget about plenty. The goal we want to achieve applying ya Agni is to save some time. Please don't apply. Young me to re factory. You need to perform a factory to enable Yanni. I hope now you better understand how to achieve the Holy Grail with the algorithm I laid out in this lecture. Be ready to fail. Applying the Agni principle, it will take some time to get enough experience and invent. Your perseverance will pay off in the next lecture. We will take a look at the separation of concerns principle. 51. 05 SoC: This lecture is titled Separation of Concerns. Separation of Concerns or a Sock and Short is a principle which were actually discussed in the section off Single responsibility principle SRP in soccer strongly related. Basically, soccer is a principle, which means that we have to separate different concerns into different modules. Adhering to sock allows to build modular systems. The difference between soccer and SRP is that soccer is mostly applied at the highest level . The value of separation of concerns is simplifying development and maintenance of computer programs. When concerns are well separated, individual sections can be reused as well as developed and updated independently. A special value is the ability to later improve or modify one section of code without having to know the details off other sections and without having to make a responding changes to those sections. Most of the time, you can treat SRP and sock as the same concepts, and you can use them interchangeably. Here's the list of concerns we must often face in enterprise software development. You are business logic, presentation, logic and database. Imagine a room where all the things are scattered all over the floor will be simple. To find a particular book there. Wouldn't it be easier to keep all the things separate books on the shelf, toys in the boxes and so on? The same we can say about programming and separation of concerns. If you enter tangle you. I was business logic. Then it will be harder for you to maintain all the mass, find anything you need, their change, anything you need to change and so on. There is a thing which can ruin our best intentions regarding separation of concerns. This nasty thing is called licking abstractions with separate concerns. By playing the constant off encapsulation Onley by encapsulation, we can protect objects and hide their internals. Unfortunately, abstraction stand to leak, especially in complex AP eyes. There is a great number of popular cases off licking abstractions. One of my favorite example. One of your model or, in other words, presentation logic knows something specific to you. I here is an example when a view model exposes a property of type collar, this is a classic example when presentation logic is incorrectly implemented from the sock point of view. To fix this example, we need to remove the property and expose another one which just returns a bowline you are on its side should decide what color to peak. This is not a concern off a presentational layer. Another good example. When the main logic operates with unique identifiers stored in a database. In such of the case, a concern of persistence is mixed with the domain logic. Domain logic should be agnostic regarding any persistence mechanisms, actually there in turns off examples of flicking abstractions. Keep in mind that layers, which represent different concerns, should be isolated from each other in such a way that none of them should know about any intrinsic details of each other on the other side. I must admit that there can be exceptions from this rule from the perspective of Domine Dreamin designer Didi Dean shirt writing start procedures, which implement any kind of business logic. For example, they perform validation and mutation of data is considered a violation of separation of concerns. Principal At the same time, unfortunately, running directly, surgical procedures are way much faster in certain scenarios than performing operations through an object. Relational mapper such as entity framework, treat such cases as exceptions. In the next lecture, you'll learn the sick US or command query separation principle 52. 06 CQS: This lecture is titled Command Query Separation Command. Query Separation is a principal off imperative programming. It was devised by a but admire as part of his pioneering work on the Eiffel programming language. It states that every method should either be a command that performs in action or a query that returns data to the cooler, but not both. In other words, asking a question should not change the answer. Generally, we can divide functions into two major types. Functions which perform commands and functions, which perform a query and return a result. Often beginners mix squares and commands. As a result, they create functions which perform a command and return a result off acquire. At the same time. This is almost always a bad thing. Consider an example. What color is asking here? Was Logan attempt successful? Maybe true means that a user has already been locked on. It's hard to tell looking at the function signature. The thing is that it's impossible to express the meaning off a boudin result by the functions name. The problem is not in the bad name of the function, but the problem is that a command is not separated from a query. The command logic and queer logic are mixed in the same function. So sick. US is one of the core principles which helped to design better AP eyes concerning this example. It would be better to roll out a function which implements a command and one or more functions which implement queries for example, like this by the names and signatures off these functions. It's clear what they mean and what they do. In other words, these functions are honest that they don't imply something hidden and they don't lie to a caller. In the next lecture, we will look at the law off dean meter. 53. 07 Law of Demeter: this lecture is titled Law Off de Meter. If we look at Wikipedia, we will see that the law off the meter, Lord in short or principal off list knowledge is a design guideline for developing software , particularly object oriented programs. In his general form, the Lord is a specific case off loose coupling. Okay, sounds great. But what does it really mean? General formulation of the low is each unit should have only limited knowledge about other units. Onley units closely related to the current unit or each unit should only talk to its friends. Don't talk to strangers. Great Sounds clear, but still not enough practical. The formal object form of the law can be summarized. This a method often object may only called methods off the object itself. An argument off the method, any object created within the method and any direct properties or fields of the object. Oh, at last, the practical meaning becomes clear. Moreover, all these guidelines in the end came to the following simple statement. Don't talk to strangers. Another simple formula of this law is used. Only one doc. Okay, then let's go to see their a practical example, which was suggested long ago By David Bach. It's a great illustration of the problem. Consider the following case. Let's pretend that we should motile the business relationships between a paper boy and the customer who wants to buy magazines. A paper boy rings the doorbell, the customer opens it. A paperboy somehow has to be paid and then hand over a magazine to the customer. Let's look at the code. Example. Which models? The case here is a simple customer class, which has first and last names, and it also has a wallet off type wallet. Here you can see the wallet class. It is extremely simple. It just stores the decimal value, which determines the amount of money in the wallet. The client off the wallet. AP. I can add money to the wallet, can withdraw money and check the current amount of money. Looks good and simple. It's just violence should feed our needs. The last thing is to implement the logic off a paper, but let's look inside. The paperboard class exposes a single method Deliver magazine, which takes the cost of the magazine and the customer to which a paperboy has to deliver. The magazine looks great. Let's look at the implementation paper. Boi just takes the wallet off a customer and then checks the amount of money if there is enough money the paper boy just takes, they needed some. Otherwise a paper boy just goes away. Great. Well, I would say, What do you think? Is it really great? If you think a little bit deeper, then you may come out with the idea that there is something strange in the fact that the paper boy takes the wallet off a customer in order to be paid a paper boy has access to customers World. What a nonsense. Would you be so kind to give your wallet toe unknown paperboys? I doubt so in this case, the violation of the law of D need a reservist. The paper boy operates with a water through a customer. The first dot here in the code is when a paperboy takes the world. Then there is a second daughter When he checks the amount of money in the world the same case when a paperboy withdraw some money to describe the problem or seriously, I should say that the main problem with this design is that the paper boys being exposed to more information than he needs to be. All the problems are the consequences of this fact. So now these three classes are tightly coupled. If we change the world class, when I have to make changes to both off the other classes, by the way, if a wallet is now that the paper boy will throw the lower reference exception, so it might be that in the real world, code based the paper boy will have to deal with it, introducing now checks and the second sequence cluttering the code. So how to fix the problem in order to fix the problem? Weaken Just motile the real world scenario. When the paper boy delivers a magazine, he just asks for a payment. Let's look at the improved design. Now. The customer class exposes the public method named Get Payment. While the underlying wallet object is now contained in a private field. No one except the customer has access to its wallet. The paper boy now is forced toe. Ask the customer to get payment. Paperboy no doesn't have the rights. And, by the way, the responsibility, as in the previous design, to fumble in the customer's wallet so the improved design is better in three ways. It better models the real world scenario. The Paper Boy code is now asking the customer for a payment. The paper boy doesn't have direct access to the wallet. Second, the role that class can now change. And the paper boys completely isolated from the change and the third were now free to change the implementation of the get payment method. Okay, let's switch back to slides. To sum up, I want to say that the rule about the number of dots sometimes can be deceitful. The thing is that the law off the meter is not about the number of dots. This law is about reducing the coupling and proving the encapsulation. When we are talking about data structures like data structures, which are exposed by the Excel document, it's perfectly fine when it's a P. I allows you dig the structure of the document like this Excel document that she not cell and so on. The same can be applied to fluent AP eyes. When each goal returns an object so you can build method chains, so it's always don't treat rules as dogmas and try to understand the underlying meaning of the room. Instead of applying rules blindly in the next lecture, we're going to learn the principal off least astonishment. 54. 08 PoLA: this lecture is titled Principal Off Least Astonishment and other basic Principle, on top of which a great number of Father Prince will stand is the principal off least astonishment. This principle states that a component off a system should behave in a manner consistent with how users off that component are likely expected to behave. The following principles and techniques are based on the principle off list astonishment. And, of course, they help to conform with this principle. Full safe. A p I command query separation in mutability designed by contract and now prevention and many others. Look at the following example. We have a reporting class with two methods brings report a and print report. Be and this code snippet works fine. But if a client changes the sequence of this calls like this a database connection error of yours. The thing is that a database connection opens at the beginning of the bring to Reppert a method and closes at the end of the print Reppert be method. This is a simple example, which has a strong smell of temporal coupling where the root causes the side effect which is hidden from the client making the very astonishing from the client's point off view. Humorously, we can conclude that the metric which reflects the factor off astonishment often FBI is the number off shouted WTF is permitted. Put simply, the principal off list astonishment means a design should both great expectations and fulfill those expectations. It should do pretty much what people expected to do. Another example of an eight b I, which astonishes its clients, is the guy over the standard Java stack. Standard stack implementation in Java exposed Bush and pop methods, and in addition, it exposes the ad method inherited from the vector class God's sake. What the ed math it is supposed to do where the item is going to be added. It's absolutely astonishing. I was almost grand when I faced the day by for the first time. Here's an example from the sea shop. A user would expect from the at least that it allows toe add items. Unfortunately, even the Sea shops type system is not ideal in this case. They're not supported. Exceptional the throne. In the next lecture, you learn what is the information hiding and encapsulation, and what is the difference between them 55. 09 Encapsulation: This lecture is titled Information Hiding and Encapsulation. If we look at Wikipedia, we will see the following definition off the information Hiding in computer science Information Hiding is the principle of segregation off the design decisions in a computer program that are most likely to change, thus protecting other parts off the program from extensive modification. If the design decision has changed, the protection involves providing a stable interface which protects the remainder of the program from the implementation. The details that are most like to change written another way. Information hiding is the ability to prevent certain aspects of a class or software component from being accessible to its clients. Using either programming language fissures like private variables were an explicit exporting policy. I agree with this definition, and after learning the solid principles, it's absolutely clear that information hiding underlies all the solid principles. We always strive to hide that information, which is irrelevant for clients. When a client sees what it doesn't need, it makes more difficult to understand such an a p I. One of the most popular question you may hear on interviews is explain the difference between information hiding and encapsulation, a great number of people confused these notions. There is a popular opinion that these terms are the same. I don't agree with this statement that information hiding is the Samos encapsulation. And here is why. First of all, try to look back and answer to the following question. Do you build your applications on top of reusable components? I'm sure on 100% that you answered. Yes, I do. Of course you do. If you program on job O C. Sharp than your applications, at least stand on top off a whole damn framework. And the following question is, do you find yourself reading the source code off that reusable components? If it's available on a regular basis and the answer is most likely, you don't from time to time. We need to read the source code of BCL, for example. But that's a rare case. This is because those components are encapsulated. They allowed to use them without digging their internals. We don't need toe. Understand the kitchen off reusable components to use them. This is what encapsulation is. Encapsulation allows to reuse components without understanding of their internal implementation. Look at the example of a poorly encapsulated class here a tease. It might seem that this is a silicon example, but I've seen a lot off such gold basis. Of course, this is the worst case, but even one AP remember implemented badly can lead to serious unfortunate consequences. What's wrong with this? A. P I look at the pace seller and method. Why does it return a string value? Is it the code off response? Is it a customer I D return? Who the hell might know what can be encapsulated by string value? He takes the mountain represented by stream. What is expected here? A decimal or walk? Maybe an integer look further, but they get customer method returns Avoid to understand how this method returns, a customer a client of the safety has to know about the customer received event and the last one remove customer method. It returns an integer again. Anything can represented by an integer value. In such a case, I've seen once how a C programmer used integers to return bulletins its ones and zeros in C shop. Yes, I have seen even such a scary trash look at how this code might look like. Here's the base salary, which returns void and accept decimal. Everything is understandable. Now it's a command which accepts the money value in decimal. Another option is to return a result moment, which is out of the scope of this course. If you're interested in building robust AP eyes regarding errors with the using result moment considered to take my course A B and C shop, the best practices of design and implementation on you. To me, another method get customer now returns a customer. Everything is quite clear. Another option is to return and maybe off customer maybe is also so called Mona, which is out of the scope of this course. And if you're interested in building robots, tape guys regarding now's with using the maybe moment considered to take my course a PNC shop, the best practices of design and implementation on you dim it for the removed customer can either return void or a result. We use a result moment to explicitly state in a signature that the operation they fail if it returns avoid it means that the operation is successful always. This is an example of a good clear, a p I. The intention off encapsulation is to protect the in variance by making invalid states impossible command Quitter. Separation principle is one of the most important principles related to encapsulation. And then I want to joke that you should always remember that you should write code so that the reader of your code might be a psychopathic mass murder. Who knows your home address? Sleep well, my dear student. 56. 10 API: What is a P I, in essence, a p I is a set off functionality. Broadly speaking, it can be shipped as a whole library. Or it can just be a class. Every programmer produces a prize in one form or another. Good programming is modular. What inherently means that those modular boundaries are AP eyes by themselves. Good AP eyes tend to get reused. They can become a great asset. On the contrary, bad a prize become liabilities. They're a nice CP eyes. There are nasty AP eyes, but there are no perfect FBI's. Definitely the perfect A pie is something on a realistic. If you develop a class for internal usage within a company, you develop a private A buy for the other developers inside your company, this kind off environment in which the cold leaves mark semen calls zoo if you develop a class for the public. It is a public FBI, which can be potentially used by millions of developer sold over the world, that this kind of environment in which the code leaves mark semen calls wilderness. These two major cases are different, but how much they're different. We will consider a little bit after the introduction. By the way, you can read a great article about rangers and zookeepers by Mark Semen following the link I have attached. Firstly, it would be very nice to define characteristics off a good a p I. We will mark out the following characteristics. Simplicity, expressiveness and compromises, extensible ity and consistency. Now let's dig deeper into characteristics off AP eyes. The first characteristic simplicity can be described through the well known rule concerning a pies development you can always add but never remove. This means that if there are many users off your a p I, you can't remove functionality they already use. That's why developing your a P I. It's always preferable to defer questionable functions rather than include them into the current release off course. The previous statement is also about AP Ivor Shani, but we consider it in the context off finding the balance between power and simplicity. So here we face a compromise between power and simplicity. When power or, in other words, abilities expressed in functionality off on a p I gross, it's simplicity degrades. The balance is hidden somewhere in the golden mean so one of the most interesting questions here is how to estimate the simplicity, often a P I. Unfortunately, there are no algorithmic ways to calculate any meaningful coefficients off simplicity. Often FBI. The only way to understand whether an FBI is simple or not is to estimate the time spent on understanding by its users. This method allows to build a learning curve, often FBI, if the A P I simplicity off which you're trying to analyze, is relatively small se. If it's not a huge framework, then you can give it to a couple of your colleagues and watch. How many time will they take to understand your A P I and how many times they will require comments or any documentation off the FBI? These one simple step will show whether the FBI is simple enough, comparing to your requirements for simplicity or not. So, firstly, you can set a time limit on understanding Europe. I then ask your colleagues to try to use a prize functionality and then compare your premise. With riel results going this way, you'll be able to take a decision to make your a pie simpler or to stop at the current point. Things getting more complex when a P I is expressed in terms off a certain domain model. In this case, you have to find those who are familiar with the domain model and those who are not. Why both? Because programmers are human resources and they can leave a company at any moment. These may lead to the situation when a newcomer will take the responsibility to work with your A p I. So you have to understand how many time will it take to understand your A P I. In both cases, these thoughts lead to the next characteristic off a good A P I. Good AP eyes are expensive because in order to make them simple, it's an accessory to spend much more time than just ship all assays. Unfortunately, not only simplicity suffers from under investment, mistakes have a tendency to accumulate and the design begins to rot. Consequently, it leads to a big ball of mud instead of clarity, and in the end, it leads to box resource is which can be allocated to repair development are always limited . So obviously we can't polish eight guys for a very long time. That's why there are always compromises between power and simplicity by the way. In spite of striving to create a super powerful FBI, it is almost impossible to parade universally, guys, it means that a P I developers have to implement first things first. To understand the main scenarios, it is an accessory to analyze abilities, advantages and flaws which will be faced by the user in all different ways off implementing a P I extent. Stability is the next major characteristic. This characteristic reflects the capabilities to increase the power, often FBI without degree writings. There are a couple of news is regarding this characteristic. We can look at extends ability from the perspective, off adding new functionality and preserving the backward compatibility. The design should strive to be capable off adding new functionality. The main object aren't principle in this case is the open close principle, which means that an object should be opened for extension and closed for modification. I would say that mostly this principle is applicable to the zoo. AP Eyes e g bright with the guys as to public eight guys is that we at first should not rollout features which could contradict with the functionality which may be introduced in the future. If you are in doubts. It's better to not introduce an FBI member than to introduce it. When we're talking about public AP eyes, we shoot at first, preserve the backward compatibility, changing an existent AP I so it will break any existent clients is the greatest scene. Unfortunately, this scene cannot be avoided sometimes, but you should strive to break clients code as rarely as possible. An FBI has to be logical and consistent. The consistency, often FBI, means that decisions apply to the design of the tape. EI are strongly opinionated. There always will be different choices available with their advantages and disadvantages. But a P I designers should take aside and stick with it along all the way. Let's look at a bad example off for consistency. The Beach Peaster Library exposes the following methods. Apparently, there's an inconsistent naming off methods. It looks like developers were in doubt and hesitated about which style off naming they should stick with. Along the way. The best option in this particular case was to use underscores everywhere. A worst way was to use everywhere. The conjoined naming and the worst possible way is to use everywhere, different naming styles, the worst possible way is exactly what BHP string AP I designers have chosen. Now developers should bear in mind two different naming styles and remember when to use which it This is really insane. Okay, we have discussed the characteristics of faith guys. Now let's briefly talk about public and private guys. The marked out principles are more important for building public AP eyes publicly, guys put greater responsibility on youth and privately be eyes. That's why you have to strive to make better that characteristics as much as you can. The cost of bad decisions may be extremely high. What I just have told doesn't mean that private FBI's developers don't need to take into account those characteristics. I'm a strong believer in that private AP eyes should be developed, bearing in mind all that characteristics. The repercussions off low quality private AP I designing might be horrible. The thing is that layers are built on top of other layers as well as applications often built on top off other applications. So introducing breaking changes into private AP eyes might have a very bad impact on dependent modules and entire applications. The Corolla re of this fact is that zookeepers must strive to become rangers anyway. Thus all the techniques we will discuss in this course are applicable to developing both private and public AP eyes more on the topic. You can read following the links attached to this lecture. Okay, let's talk a little bit about a P I development principles. There are some development principles which help us to create a P eyes with great or at least satisfactory characteristics. Let's look at them more closely. AP eyes should be as simple as possible, but no simpler. This is the principle firstly spoken by Albert Einstein. This is a general principle which is applicable to many things in our life, in the context off a prize development. This principle implies that simple things should be simple and at the same time, difficult things should be achievable in practice. It also means that when you are in doubt about introducing a certain member, just leave it out. Remember again that you can always add but never remove. This rule is more relevant for public a prize, but don't forget that introducing breaking changes in private FBI's is also have a scene, a good AP. I should allow to do a lot without learning a lot in practice, it means that you should strive to build a P eyes, which are simple to use in other, to accomplish simple tasks. And on the top of these simple scenarios, more difficult tasks should be possible to accomplish. Did you notice the first principle resonates with the 2nd 1? Actually, all the principles are inter tangled. They all have something in common. AP Eyes should be based on use cases as a practical Corolla re we can say here is that it means two things. The 1st 1 is that in order to design an AP, I just imagine that you're a client of the tape. I I write some code, which uses that just yet inexistent a p I. How the clients cold should look like do like the cold you have written. The second thing is that you have to start to make a sketch off a neighbor as soon as possible. Don't gather turns off requirements, just make a simple sketch and ask, Are the developers what do they think about your design? So the first thing you should do is to write several cold samples for the main use cases. Ask your colleagues to implement that main use cases if they experienced difficulties. It's a bad sign. Provide a low barrier for using an A P I. In practice, it means that you always should provide the simplest constructors with default values for parameters should throw exceptions with messages which explain what to do to fix. The problem should not require from clients to explicitly create more than one type for accomplishing main use. Cases should not require from plans to perform a wide initialization, often object build self explanatory AP eyes. I would express this thought. In other words, let a pie clients to rely on Intel a sense A by clients should understand the a pie by just using the intelligence. So an a p I has to be understandable intuitively. In spite of the previous point, you should provide a decent documentation in the case off private AP eyes. This is especially important for a prize which contained the main notions what inherently makes them hard to understand, especially for those who are only the beginning off learning the domain concepts. In the end, I would say that your baby I should appeal to the most powerful emotion. Which one do you think? Love? Not exactly. Appeal to the laziness. No one wants to learn a book. A hand in thickness about using your FBI. No one, even you. 57. 11 SOLID VS YAGNI: this lecture is titled Solid versus Young. If you watch the course carefully, you might notice that trying to fix a design problem, we always ended up with more classes and functions. In other words, it might seem that we ended up with more complex design. Blind application off solid principles can lead us to the needless complexity. Smile very often. Needless complexity is the direct result of violating the Yardeni principle. Greg Young long ago came out with the following statement. Developers have a tendency to attempt to solve specific problems with general solutions. Gold plating always leads to coupling and complexity and software. Greg Yann suggested to make goat specific instead of making it general. The single responsibility principle Natural conforms with the Greg Young suggestion to make gold specific. SRP leads to specific classes with concrete responsibilities. It addresses a very specific problem. The Kalay shin off principles appear when we reach a situation when we need to make code more general, what we should do that the real question is what should be generalized. The answer to this question gives their reused abstraction principle. The wrap principle essentially means that if you have an abstraction in our case, an interface or an abstract class and it is not reused or, in other words, implemented by more than one implementer. Then you probably violate the reused abstraction principle. So the real value of an abstraction is that it eliminates the irrelevant and amplifies the essential according Toa Uncle Bob. So to come at here to solve principles avoiding yardeni violation at the same time, start with a concrete implementation off a specific behaviour, observe the emerging commonalities and apply the rule of three, which states that if you find yourself in a situation when you want to repeat the same called third time, you need to introduce an abstraction and encapsulated the common behavior in it. This is the only way how you can achieve the balance between solid nous and you, Agnes at the architectural level. In the next lecture, we will concretize this topic a little bit and talk about OCP versus Yeah, Agni 58. 12 OCP VS YAGNI: In the previous lecture, you learned the relationships between solid principles in general and Yanni principle. In this lecture, you'll see a concrete example off solid versus Yardeni in the form off OCP versus the Agony . Let's get back to the classic form off UCP violation we analyzed in the recipe section. We have the fine device method here, which implements its. Which case statement Inside Switch Gay statement is a construction off a procedural programming in nature? Does this method violate the OCP? From the perspective of the Myers gossipy definition, recipe is not violated here, since adding new device model doesn't lead to any changes in the signature off the fire device method. But we mostly interested in the Martin's definition. In modern days, and from Martin's point off view, the OCP is clearly violated to fix the problem. In the OCP, Sectional introduced an abstract based class and several inheritors, which represented the devices models. So we introduced several new types instead of initial one. Yeah, Agni at the same time means that we don't need to introduce any abstractions until we really need them. So what to do with this situation? Which principle should wait here gossipy Orry Ogni, A colleague of mine, Vladimir Horcoff, gives a great answer to this question. His answer is, it depends. It depends on what we talked about previously. Whether we're talking about public AP, I or not, the answer is different in these cases. So in the case off a private AP, I young is more important than OCP. If we own the code based entirely and develop it within a private group of people, we shouldn't introduce any abstractions. Until we see the third repetitive Cho Chung is going to appear, then we need to apply OCP to prevent excessive code application. In the case of public AP, I we need to sacrifice your agony and apply OCP immediately because the future costs honor Factoring towards the object oriented design will be enormous will introduce breaking changes. Clients do not like breaking changes. So in this case, OCP is more important than Yanni. In the next lecture, we're going to clarify the difference between SRP and I speak 59. 13 SRP and ISP: this lecture is titled as R P and Eyes Speed. Very often, developers get confused by the difference between SRP and I speak. For example, developers say that if they apply this R P, then there is no need to apply ice speed. Ever since all the glasses have a single responsibility, they think that I speeds apply to fix this RP violation. However, this opinion is far from being the truth. S R B implies that a class should have only one. The reason to change I speak at the same time tells us that clients should not depend on things they do not need more concretely and going straight to the point, their different views on the same idea, SRP is more focused on the designer side. Point off view, while I speak is more focused on the client side point of view. Consider the following example here have a data storage which implements both reading and writing operations. It would be odd to separate these operations into separate classes, so we don't violate this. Are they here at the same time? If we have 10 clients which depend on the on the reading functionality and another 10 clients which depend on loan writing functionality than it might be meaningful to introduce two interfaces I reader and I writer for hiding things from clients they do not. I need to see so we can apply the ice p here. Okay. In the next lecture, we will talk about architecture and design. 60. 14 Architecture and Design: this lecture is titled Architecture and Design. Have you ever thought What is architecture? What does it mean? And what is the difference between architecture and design? Developers often used these terms interchangeably. It's very important to feel the difference. So let's start with architecture. Every serious software has an architectural. Even if the architecture is chaotic, it would mean that chaos is the architecture off that chaotic system. Software architecture is a very vague term, which is very often treated as the highest level of abstraction off a system. What kind of data storage is present? How do modules interact with each other? What recovery systems are in place and so on? Somewhere in 2013 there was a post by Martin father who analyzed the problem of defining the notion off architecture. He quoted Ralph Johnson, who said that there is no such a notion, ist the highest level of abstraction of a system users, developers, product holders, they all look at the system from different angles and see the architecture differently. It's more correct to say that the architecture is comprised off significant components, and what makes a component significant is one expert. Developers say that particular components are significant, so the roll off the notion off the architecture is social. It is a formal and very often informal agreement on how to view the system from the highest level. There's also another bed definition off architecture, and it's important to talk about it. Here it is. Architecture is the decisions that you wish you could get right early in a project. Because of this definition, developers tend to think that choosing a particular DBM ass, they make an architectural decision. In some cases, it's true, and in other cases it's not. For example, if we isolated to be amassed by using interfaces at the corresponding boundary off our software system and we could replace that d be a mess, we make it irrelevant. And most likely we will not treat that. D be a mass has a significant component. Actually, the BMS and you I are tools. When we say that a particular DBM answer particular you high technology belongs to the architecture. An analogy comes to mind that when we build a house, we treat hammers, jigsaws and other tools as the architecture of the house. That would sound nonsensical. Of course, this is not an absolutely valid analogy, since hammers do not have such a significant influence on the on the result, as database management systems do. But we must understand that we should strive, if possible, to make tools irrelevant from the domain perspective. We should strive to defer architectural decisions as far as possible, since decisions made on early stages very often in the end turn out to be not optimal at best. The definition off a software design doesn't warrant such deep observations. Software design is about designing the individual modules or components. What are the responsibilities? Functions off module X off glass? Why, what can it do and what not what design patterns can be used. Software design emphasises on module component and quest level. We also have such notions as architecture and design panners. Architectural patterns are standard forms off relationships between components that deemed significant architecture patterns in general include two tier client and server basically and server scenario, three tier client sir, and database most often software or ended architecture, the Web service model, event driven and so on. Designed parents are those patterns we talked about throughout the course. From time to time, they can be split into behavioral, structural and creation all patterns. I hope now you understand better. What is architecture and design? Let's rant about searching for a balance a little bit in the next lecture. 61. 15 Conclusion: in this section, you learned that every piece of knowledge must have a single unambiguous representation in the system, and this is the definition of the drive principle. The most common ways of the dry principal violation are magic stream or values, duplicate logic in multiple locations and repeated even logic or multiple switch cases scattered throughout the code base. You learn that this implies that simplicity should be a key goal in design and on assessor complexity should be avoided. The main technique we used to struggle with complexity is the decomposition. The complexity imposed by the domain itself is called the essential complexity. Accidental complexity is the complexity off our solutions, which are intended to solve the problems of the domain. Yeah, but he is all about avoiding over engineering. There is no well defined criterion, which allows to measure the young newness of the system. Yeah, he's a principal off extreme programming that states that a programmer should not add functionality until deemed an accessory. S European soccer are strongly related. Basically, sock is a principle which means that we have to separate different concerns into different modules. Adhering to sock allows to build modular systems here is the list of concerns we must often face in enterprise software development. You I business logic, presentation, logic and data Maze Command query, separation or seek us is a principle that states that every method should either be a command that performs in action or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer. A general formulation of the law of Demeter is the following. Each union should have only limited knowledge about other units. Onley units closely related to the current unit or each union should only talk to its friends or don't talk to strangers that brings a pull off list. Astonishment underlies a great number of other principles and techniques. This principle states that a component off a system should behave in a manner consistent with how users off that component are likely to expected to behave. You learned that information hiding and encapsulation are different concepts. Encapsulation is intended to protect the in variance information. Hiding is one of the ways we achieve proper encapsulation. You also learned that you can achieve bounds between complexity and simplicity, applying their reused abstraction principle that OCP bits Yardeni in case of public AP I and vice versa in case of private A P I. Yeah, agony beats OCP. You learn that a therapy and ice pr similar in their intention, but different from the semantic point of view. SRP and I speak and both be applied on the same class. For example, they do not contradict with each other. You learn that architecture and design are different notions. Architecture is the agreement between group of people, usually expert programmers, regarding the importance off system components. While software design is a more low level concept and concerns the implementation details in the end, how classes and interfaces interact and so And he also learned that of course, you need to practice to become wise regarding building maintainable software systems. Congratulations. This is the end of the course. That was a long journey. I hope you enjoyed it. I learned a lot and became a better developer. And thank you for watching