Erstellt von Alex Orpwood
vor mehr als 7 Jahre
|
||
Frage | Antworten |
SOLID - Single Responsibility Example | BOL/DAL structure, Internation number (seperating rules (Reg Exes) from rules engine) |
SOLID - Open for extention, closed for mod | Orkney pricing claculation using strategy pattern |
SOLID - Liskov principle - Example | Base message can be replaced by sub type Messages (SMS, MMS, Email, Voice). Square/rectangle example |
SOLID Interface Segation - Example | TBC |
SOLID - Dependency inversion Example | Internation number (seperating rules (Reg Exes) from rules engine) |
DRY Example | Refactor EMX: Int Numbers, Security |
IoC definition | IoC means that objects do not create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside service (for example, xml file or single app service). 2 implementations of IoC I use are DI and ServiceLocator. |
DI definition | DI means the IoC principle of getting dependent object is done without using concrete objects but abstractions (interfaces). This makes all components chain testable, cause higher level component doesn't depend on lower level component, only from interface. Mocks implements these interfaces. |
Inversion of Control vs Dependency Injection | IoC is a generic term meaning rather than having the application call the methods in a framework, the framework calls implementations provided by the application. DI is a form of IoC, where implementations are passed into an object through constructors/setters/service look-ups, which the object will 'depend' on in order to behave correctly. IoC without using DI, for example would be the Template pattern because the implementation can only be changed through sub-classing. |
DRY | Removing duplication ensures that every concept in the system has a single authoritative representation in the code. A change to a single business concept results in a single change to the code. DRY increases maintainability by isolating change (risk) to only those parts of the system that must change |
SOLID - Single responsibility principle | The single responsibility principle states that a class should have one, and only one, reason to change. There is a corrolary here. An axis of change is only an axis of change if the changes actually occurr. It is not wise to apply the SRP, or any other principle for that matter, if there is no symptom. |
SOLID - Open/close principle | The open/closed principle states that "software entities (classes, modules, functions, and so on) should be open for extension, but closed for modification" Although you might modify the code in a class to fix a defect, you should extend a class if you want to add any new behavior to it. This helps to keep the code maintainable and testable because existing behavior should not change, and any new behavior exists in new classes. |
SOLID - Liskov substitution principle | The Liskov substitution principle in object-oriented programming states that in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S without altering any of the desirable properties, such as correctness, of that program. AKA - Design by contract Uncle Bob - Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it. I.e., a sub class should override the parent's class in a way that does not break the functionality from a client's point of view. |
SOLID - Interface segregation principle | The principle states that interfaces that are very large should be split into smaller and more specific ones so that client classes only need to know about the methods that they use: no client class should be forced to depend on methods it does not use |
SOLID - Dependency inversion principle | High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. This is achieved by designing components whose external dependencies are expressed in terms of an interface for which an implementation must be provided by the consumer of the component. In other words, the defined interfaces express what is needed by the component, not how you use the component (e.g. "INeedSomething", not "IDoSomething"). States that Depend on Abstraction not on concretions This principle allows for decoupling. |
The Four Pillars of OOP | Encapsulation Inheritance Polymorphism - One variable can point to different types of objects - Objects can behave differently depending on their type - Factory pattern uses polymorphism Abstract classes cannot be instantiated - Can contain abstract members, and virtual methods, Abstract methods don't have an implementation, and a derived class must override it. |
Interface | Contains non implementation details - defines only a signature of methods, events and properties A type can implement multiple interfaces |
Why design patterns | Creates a shared language Avoids reinventing already solved problems Provides starting point Speed team productivity Improves system/app design |
Design patterns - Criticisms | Unnecessary duplication - work around programming language limitations / missing features |
Adaptor pattern definition | Is used to wrap a needed class with one that implements a required interface. By writing client classes so they depend on adaptors, we future proof these classes, ensuring they can work with as yet unwritten implementation libraries. Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. |
Bridge Pattern definition | Decouple an abstraction from its implementation so the two can vary independently- (GoF) (Abstraction are coupled by definition) Abstraction->Abstraction->Implementation Example on Plural Sight: Manuscript printing, using a formatter in a bridge pattern. Common usage: - User Interface - Shape - DrawingAPI - Persistence - Object to persist - Persistence Type The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes. The bridge pattern is useful when both the class and what it does vary often. The class itself can be thought of as the implementation and what the class can do as the abstraction. The bridge pattern can also be thought of as two layers of abstraction. |
Bridge vs Strategy | The UML class diagram for the Strategy pattern is the same as the diagram for the Bridge pattern. However, these two design patterns aren't the same in their intent. While the Strategy pattern is meant for behavior, the Bridge pattern is meant for structure. The coupling between the context and the strategies is tighter than the coupling between the abstraction and the implementation in the Bridge pattern. The Bridge and Strategy pattern are the same, only the intent is different. The Bridge pattern is a structural pattern (HOW DO YOU BUILD A SOFTWARE COMPONENT?). The Strategy pattern is a dynamic pattern (HOW DO YOU WANT RUN A BEHAVIOUR IN SOFTWARE?). The syntax is similar but the goal are different: Strategy: you have more ways for doing an operation; with strategy you can choice the algorithm at run-time and you can modify a single Strategy without a lot of side-effects at compile-time; Bridge: you can split the hierarchy of interface and class join him with an abstract reference |
Builder pattern | Director(logic)-Builder(defines steps/data) <-Concrete Builder->Product Director - Uses the Concrete Builder - Knows how to build - Client code calls directly - Calls the Concrete Builder steps Builder - Abstract interface or class - Defines steps - Holds instance of productivity Concrete Builder - Should be multiple of these - Provides an implementation for interface - A recipe or set of ingredients - Data to be used by director - (Implementation of steps) Product - What you are building - Not a different type but different data |
Chain of responsibility | Sender->Receiver 1->Receiver 2->Receiver 3 - Message goes to Sender, who's only job is to pass it to Receiver 1 - Receiver 1 see if it is capable of handling it. If it can't, then move message to Receiver 2. - Receiver 2 see if it is capable of handling it. If it can't, then move message to Receiver 3. If it can send response back to Sender. Sender has no knowlege of Receiver 2 or 3. Only Receiver 1. Sender is only aware of first receiver. Each receiver is only aware of the next one. Receivers process message or send it down the chain. Sender does not know who received the message. First receiver to handle the message terminates the chain. Order of receiver list matters Use when: -More than one message handler for a message -The appropriate handler is not explicitly known by the sender -The set of handlers can be dynamically defined. |
The Command Pattern | Represent an action as an object Decouple clients that execute the command from the details and dependencies of the command logic Can queue commands Can be used for logging, validation and undo Call Command method with no arguments (strategy pattern is similar but you pass parameters in) |
Composite Pattern | Compose objects into tree structure to represent part-whole hierarchies (part-whole -> composed of parts). Real world example - Email groups Tree structure where lead and collection implement the same interface When to use: - Groups or collections. Allows you to have mixed groups (consisting of groups and individuals) - Can you add an interface? - Trees - Need to distribute something over the items |
Decorator pattern (wrapper pattern) | Wrap a class with a new class, that doesn't affect the functionality of the existing class, but extends it Add functionality to existing object dynamically Alternative to sub classes Flexible design Support open closed principle Used in - Legacy systems - Add functionality to controls - Sealed classes How does it work: - It wraps objects |
Event aggregtor | Useful for coordinating notifications in complex systems - Reduces coupling between object firing event and the object responding to the event - Reduces coupling, improves maintainability and testability - Can be overkill for simple systems - Simplifies event registration by providing a singles centralized store - Reduces coupling between publishers and subscribers - Reduce friction for introducing new events - Reduce memory management issues related to eventing |
Façade | Provide simple, purpose built interface to a larger more complex body of code or interfaces. - Make a complex body of code simpler to consume and use - Expose a set of complex object interaction with a single interface - Wrap a poorly designed API in a better designed one |
Factory Pattern (a creational pattern) | Unsure which concrete implementation of an interface I want to return. Creation should be separate from representation of an object Store object to create outside of the program (e.g. in a database or config file) Factoy Method Pattern - Add a interface to their factory itself that share an interface - Defers objects creation to multiple factories that share an interface - Derived classes implement or override the factory method of the base. Factroies in .Net commonly make use of reflection Pros - Eliminates reference to concrete classes - Factories can be inherited to provide more specialised object creation - Rules for object initialization is centralised Cons - May need to create a factory just to get a concrete class - The inheritance hierarchy get deeper with coupling between concrete factories |
Abstract Factory | Factories create different types of concrete objects (products) - A factory represents a 'family' of objects that it can create - Factories may have more that one factory method Simple example from Azure Service Bus POC: public static class MessageDALFactory { public static IMessageDAL GetDAL() { string typeName = ConfigurationManager.AppSettings["InflightDataPersistor"]; Type dalType = Type.GetType(typeName); object dalInstance = Activator.CreateInstance(dalType); IMessageDAL dal = dalInstance as IMessageDAL; return dal; } } |
Flyweight pattern | Reduce storage costs for large number of objects -Share across multiple contexts -Retain object granularity and flexibility Example - Ceramic tile application with millions of tiles |
Interpreter pattern | The interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence for a client. |
Iterator | Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. The iterator pattern defines interfaces for the aggregate and the iterator, each of which must be implemented for each collection that is to support the pattern. When to use: - You need to traverse a collection - You want to abstract the collection iteration logic (so you follow SRP and DRY) - You do not wish to break encapsulation and expose your collections' internal organisation/design globally. |
Lazy Loading | Interrupt the objects loading process for the moment, leaving a marker in the object structure so that is the data is needed it can be loaded only when it used. Use when Fetching an object requires an extra call for the data, and the data you're fetching isnt used when the main object is used Avoid using it unless or until you need it - us it as a tuning mechanism Need to balance amount of data fetched with the number of data requests being made Lazy<T> - allows us to set the initialisation via a lambda expression (deferred call), defaults to thread safe Examples: - Lazy Initialisation - Value Holder ValueHolder uses IValueHolder via Strategy Pattern to load a value when accessed - (ValueHolder and IValueLoader are reusable) - Virtual Proxy - can be hard to compare a proxy of the object to the actual object - Ghosts - is a real object in a partial state. Initially only know about is ID. When any property is accessed the ghost class loads all of its state from the persistence. Beware of N+1 issues Can increase complexity |
Mediator | Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. Components Colleagues - Individual components that needs to communicate with each other - Implements the same base type - Have knowledge of the mediator Mediator - Centralized component that manages communication between the colleague components - Implement an abstract that is used by the colleague components Advantages - Hides all coordination between colleagues - Decoupled colleagues - Mediator's one-to-mant relationship with colleagues is preferred to colleagues relating in a many-to-many fashion Disadvantage - The mediator can become very large and very complicated as more colleagues are handled. |
Memento | Example usage: Implementing undo/redo The memento pattern describes a way to capture objects' internal state without violating encapsulation, or single responsibility principle. GOF: 'Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later' Components Originator Represent the object whose state is being tracked Caretaker Performs operation on the originator, but need to be able to undo the operations. |
MVP | Provide clear separation between - Data to show - The business logic of the app - Display of data Ensure each collaborator in the pattern has a single responsibility, and can test each collaborator - Model - View - Presenter |
Null object pattern (also know as stub, active nothing, active null) | Rid code of null check where possible - Provide a non-functional object in place of a null reference - Allows methods to be called on Null objects, unlike a null reference |
Singleton | A class that should have exactly one instance Commonly, singletons should only be created when they are first needed (e.g. lazy construction). The class should not require parameters as part of its construction. Consequences - Introduce tight coupling among collaborating classes - Notoriously hard to test (commonly regarded as an anti pattern) - Using an IOC container it is straightforward to avoid the coupling and testability issues. Single Responsibility - Management of object lifetime is a separate responsibility - Adding this responsibility to a class with other responsibilities violates the Single Responsibility Principle - Using an IOC container, a separate class can be responsible for managing object life times. |
Observer pattern | When to use: - One object is dependent on the changes on another patter - When changing one object requires a change to many others - When changes to an object should allow notification to others without any knowledge of them Traditional approach consequences - Multiple subjects for each observer - Triggering the update, when multiple properties are involved - Disposed objects & observers can hold references to each other - Mapping subjects to their observers - Unexpected updates - Observing different properties separately Real world examples - GUI controls - Data binding - Network events - File watcher - MVC patter Pitfalls to avoid - Unexpected threads - Multiple threads - Memory leaks |
Strategy Pattern | Encapsulate a family of related algorithms - Let the algorithm vary and evolve from the class using it - Allow a class to maintain a single purpose - Allows us to decouple algorithms implementation from a class Applicability - Switch statements are a red flag - Add a new calculation will cause a class file to be modified Create a class for each calculation (strategy) Use a common interface for each strategy Consequences - Strategies may not use member of the containing class - Test may now be written for individual concrete strategies - Strateges can be mocked - Add a new strategy does not change the context class Uses - Delegates in c#3.5 + - Service classes passed to constructors for ASP.Net MVC controllers Variations - Function or delegates in .Net - Property injection - Pass strategy on method call |
Unit of work | Track changes in persistent objects - Efficient data access - Manage concurrency problems - Manage transactions - Make a set of changes across a range of objects, and persist the changes back to the DB in one go UoW used in the following to manage transactions: - ADO.Net using Data Tables, Data Sets - Entity framework - Object context maps entities to tables - NHibernate - Linq2SQL Beware of lifetime issues - Check garbage collection - Singletons are deadly Advantages: - Keeps business login free of data access code - Keeps business logic free from tracking changes - Allow business logic to work with logical transactions |
Visitor pattern | Represent an operation to be performed on the elements of an object structure. Visitors lets you define a new operation without changing the class of the elements on which it operates (GOF). Give an object tree/structure new functionality without changing its structure. |
Service Locator | Inversion of control containers - Ninject - Castle Windsor - Implementation of an IOC container uses one of the following methods: - Service Locator - Dependency Injection - Factory Pattern Abstract the application from the services it uses Play the middleman Change the service without a recompile Identify a service through configuration Benefits: - Solid principles: Single responsible, open/closed, Liskov substitution (services can be reduced to their interface), Interface Segregation, dependency inversion Consequences - Global - any client can access - Availability - service may not be loaded. Service is not guaranteed to be their - Does not handle life cycle of service |
State Pattern - heanhiour pattern | Change the behaviour object depending on its states, e.g.: - Bug tracking system, only allows you to delete a ticket for specific statuses of tickets (e.g. only when closed, but not when its active). Intentions: - Change behaviour of the object with each state - Encapsulate the logic of each state in a single object - Allow for dynamic state discovery - Make unit testing easier The states are moved into individual classes. Classes dedicated to one state. Benefits - Separation of concerns - Localization of state-specific behaviour - Transition between states is explicit and clear - Reuse of of tate objects - Simplify the program - Easier maintainability |
Template method | Model a process of algorithm of several steps Allow variation of the details of each step, while enforcing the structure and order of the steps themselves Intent: - Encapsulate and enforce the work flow or process that is not a variable. - Allow subclasses to alter specific behaviour via concrete implementation - Redefine one or more steps of an algorithm without altering its structure The workflow is variant. Subclasses may redefine certain steps, but not change the algorithms structure. How its used: - Clients call children of base implementation - Child types customise individual step behaviour - Effective way to achieve open/closed principle Consequences - Algorithm steps must be known and relativity inflexible at the time the pattern is applied. - Relies on inheritance, rather than composition, which can be a limitation. - Single inheritance makes it hard to merge two child algorthims into one |
Hollywood Principle | Don't call use, we'll call you High level (base class) components should not depend on low level components (sub classes). Clients should depend on the base class , not the other way around. |
Repository Pattern | Separation of business code from data access code - Separation of concerns - Testability Encapsulates data - Data appears to live inside an in-memory collection - Use an interface so you quickly change the repository (e.g. for testing) E.g. Entity framework repositories Applicability - SQL Database - Web service - File system Consequences - Increase level of abstraction - More classes, less duplicated code - Maintainability, flexibility, testability - Further away from the data - Shielded from infrastructure - Harder to optimize |
Rules Pattern | Try to solve: A class of method has complex and growing business logic - Additional changes of the same nature are likely Intent: - Separate individual rules from rules processing logic - Allows new rules to be added without the need for changes in the rest of the system Can use Rules Engines System.Workflow (.Net 3+) |
Cyclomatic complexity | the number of paths through an area of code |
The Prototype Pattern | Specify the kinds of objects to create using a prototypical instance and create a new objects by copying (cloning) this prototype. Helps solves the following - Problem 1 - Construction is Expensive - Problem 2 - State is important - Problem 3 - Hiding the constructor Examples - JavaScript is a prototypical library. Based on concept of prototypes instead of inheritance and classes. When creating an object, you are creating a copy of a base protoype object. - C# IClonable, MemberwiseClone |
Proxy (surrogate) | Provides a surrogate or place holder for another object to control access to it. You need a place holder for an actual object that is expensive to create. Types - Remote proxy - acts as a local representative of a remote object, and abstracts away the details of communicating with the remote object - A virtual proxy - creates expensive object on demand. A common example is an Image Proxy that shows a place holder while the image is being loaded or rendered. - A protection proxy can be used to control access to an object, based on authorization rules How it gets used: - Clients work with proxy as if were the actual object - Proxy controls access to actual object, delegate calls to it as needed Used to: - Improve performance and load time of an application - Simplify interactions with remote objects - Defer expensive calls until needed - implement lazy loading of objects from persistence |
MVVM | Separates concerns : - View - View's state and behaviour - Data Improves - Unit testing & UI testing - Maintenance - Extensibility - Enables designer/developer workflow - Enables data binding Consequences Pro - Reduce code-behind - Model doesn't need to change to support view - Designers design, coders code - Reduces development time - Multi-target Con - Create more files - Simple tasks can be complicated - Lack of standardization |
Möchten Sie mit GoConqr kostenlos Ihre eigenen Karteikarten erstellen? Mehr erfahren.