├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md ├── assets └── images │ ├── console-menu.png │ ├── design-patterns-types.png │ └── twitter.png └── src ├── AdditionalPatterns ├── EventAggregator │ └── StoreManagement │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Components │ │ ├── EventAggregator.cs │ │ ├── Publishers │ │ │ ├── OrderPublisher.cs │ │ │ └── WarehousePublisher.cs │ │ ├── Subscribers │ │ │ ├── BusinessTrackingSubscriber.cs │ │ │ └── OrderSubscriber.cs │ │ └── Unsubscriber.cs │ │ ├── Contracts │ │ ├── ICustomObserver.cs │ │ ├── IEvent.cs │ │ ├── IEventAggregator.cs │ │ └── IPublisher.cs │ │ ├── Events │ │ ├── OrderCreatedEvent.cs │ │ └── WarehouseReceivedNewSuppliesEvent.cs │ │ ├── Executor.cs │ │ └── StoreManagement.csproj ├── FluentInterface │ └── FluentInterfaceLibrary │ │ ├── BlobStorageExample │ │ ├── BlobStorageExecutor.cs │ │ ├── BlobStorageManager.cs │ │ └── Contracts │ │ │ ├── IBlobStorageAction.cs │ │ │ ├── IBlobStorageSelector.cs │ │ │ ├── IRead.cs │ │ │ └── IWrite.cs │ │ ├── Executor.cs │ │ ├── FluentInterfaceLibrary.csproj │ │ └── LinqExample │ │ └── LinqExecutor.cs ├── Interpreter │ └── InterpreterLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── DateExample │ │ ├── Context.cs │ │ ├── DateExecutor.cs │ │ └── Expressions │ │ │ ├── Common │ │ │ └── IExpression.cs │ │ │ └── Terminal │ │ │ ├── DayExpression.cs │ │ │ ├── MonthExpression.cs │ │ │ ├── SeparatorExpression.cs │ │ │ └── YearExpression.cs │ │ ├── Executor.cs │ │ ├── InterpreterLibrary.csproj │ │ └── SandwichExample │ │ ├── Context.cs │ │ ├── Expressions │ │ ├── Common │ │ │ └── IExpression.cs │ │ ├── NonTerminal │ │ │ ├── CondimentList.cs │ │ │ ├── IngredientList.cs │ │ │ └── Sandwich.cs │ │ └── Terminal │ │ │ ├── Breads │ │ │ ├── Common │ │ │ │ └── IBread.cs │ │ │ ├── WheatBread.cs │ │ │ └── WhiteBread.cs │ │ │ ├── Condiments │ │ │ ├── Common │ │ │ │ └── ICondiment.cs │ │ │ ├── KetchupCondiment.cs │ │ │ ├── MayoCondiment.cs │ │ │ └── MustardCondiment.cs │ │ │ └── Ingredients │ │ │ ├── ChickenIngredient.cs │ │ │ ├── Common │ │ │ └── IIngredient.cs │ │ │ ├── LettuceIngredient.cs │ │ │ └── TomatoIngredient.cs │ │ └── SandwichExecutor.cs ├── LazyLoad │ └── LazyLoadLibrary │ │ ├── Assets │ │ ├── pattern-structure-1.png │ │ └── pattern-structure-2.png │ │ ├── Executor.cs │ │ ├── GhostsExample │ │ ├── CollegeFactory.cs │ │ ├── DomainObject.cs │ │ ├── GhostCollege.cs │ │ ├── GhostsExecutor.cs │ │ └── LoadStatus.cs │ │ ├── LazyInitializationExample │ │ ├── DotNetLazyCollege.cs │ │ ├── LazyCollege.cs │ │ └── LazyInitializationExecutor.cs │ │ ├── LazyLoadLibrary.csproj │ │ ├── Library.cs │ │ ├── ValueHolderExample │ │ ├── CollegeFactory.cs │ │ ├── IValueLoader.cs │ │ ├── LibraryLoader.cs │ │ ├── ValueHolder.cs │ │ ├── ValueHolderCollege.cs │ │ └── ValueHolderExecutor.cs │ │ └── VirtualProxyExample │ │ ├── College.cs │ │ ├── CollegeFactory.cs │ │ ├── ProxyCollege.cs │ │ └── VirtualProxyExecutor.cs ├── NullObject │ └── NullObjectLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Executor.cs │ │ ├── NullObjectLibrary.csproj │ │ └── SmartphoneApplicationExample │ │ ├── ApplicationRepository.cs │ │ ├── Applications │ │ ├── Common │ │ │ └── Application.cs │ │ ├── Gmail.cs │ │ ├── NullApplication.cs │ │ ├── SubwaySurfers.cs │ │ └── Youtube.cs │ │ └── SmartphoneApplicationExecutor.cs ├── Repository │ └── OrderManagement │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Controllers │ │ ├── CustomerController.cs │ │ └── OrderController.cs │ │ ├── Domain │ │ ├── Customer.cs │ │ ├── Entity.cs │ │ └── Order.cs │ │ ├── Executor.cs │ │ ├── Infrastructure │ │ ├── OrderManagementContext.cs │ │ └── Repositories │ │ │ ├── Contracts │ │ │ ├── ICustomerRepository.cs │ │ │ ├── IOrderRepository.cs │ │ │ ├── IRepository.cs │ │ │ └── IUnitOfWork.cs │ │ │ ├── CustomerRepository.cs │ │ │ ├── OrderRepository.cs │ │ │ ├── Repository.cs │ │ │ └── UnitOfWork.cs │ │ └── OrderManagement.csproj ├── Rules │ └── RulesLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Common │ │ └── Customer.cs │ │ ├── Executor.cs │ │ ├── MotivatingExample │ │ ├── DiscountCalculator.cs │ │ └── MotivatingExecutor.cs │ │ ├── RulesExample │ │ ├── DiscountCalculator.cs │ │ ├── Rules │ │ │ ├── BirthdayDiscountRule.cs │ │ │ ├── Common │ │ │ │ └── IDiscountRule.cs │ │ │ ├── FirstPurchaseRule.cs │ │ │ ├── LoyalCustomerRule.cs │ │ │ ├── SeniorRule.cs │ │ │ └── VeteranRule.cs │ │ └── RulesExecutor.cs │ │ └── RulesLibrary.csproj ├── ServiceLocator │ └── OrderProcessing │ │ ├── Assets │ │ ├── pattern-structure-1.png │ │ └── pattern-structure-2.png │ │ ├── Executor.cs │ │ ├── IServiceLocator.cs │ │ ├── Logger.cs │ │ ├── NotificationManager.cs │ │ ├── Order.cs │ │ ├── OrderManager.cs │ │ ├── OrderProcessing.csproj │ │ ├── PaymentProcessor.cs │ │ └── ServiceLocator.cs ├── Specification │ └── ProductSpecification │ │ ├── Assets │ │ ├── pattern-structure-1.png │ │ └── pattern-structure-2.png │ │ ├── Domain │ │ ├── Entity.cs │ │ ├── Product.cs │ │ └── ProductCategory.cs │ │ ├── Executor.cs │ │ ├── Infrastructure │ │ └── ProductRepository.cs │ │ ├── ProductSpecification.csproj │ │ └── Specifications │ │ ├── CheapProductSpecification.cs │ │ ├── Common │ │ ├── AndSpecification.cs │ │ ├── OrSpecification.cs │ │ ├── ParameterReplacer.cs │ │ └── Specification.cs │ │ ├── ProductCategorySpecification.cs │ │ ├── RecentlyLaunchedProductSpecification.cs │ │ └── TopRatedProductSpecification.cs └── UnitOfWork │ └── UnitOfWorkLibrary │ ├── Assets │ ├── pattern-structure-1.png │ └── pattern-structure-2.png │ ├── Domain │ ├── Customer.cs │ ├── Entity.cs │ └── Order.cs │ ├── Example1 │ ├── Controllers │ │ ├── CustomerController1.cs │ │ └── OrderController1.cs │ ├── Example1Executor.cs │ └── Infrastructure │ │ ├── IUnitOfWork1.cs │ │ ├── OrderManagementContext1.cs │ │ ├── Repositories │ │ ├── Contracts │ │ │ └── IRepository1.cs │ │ └── Repository1.cs │ │ └── UnitOfWork1.cs │ ├── Example2 │ ├── Controllers │ │ ├── CustomerController2.cs │ │ └── OrderController2.cs │ ├── Example2Executor.cs │ └── Infrastructure │ │ ├── IUnitOfWork2.cs │ │ ├── OrderManagementContext2.cs │ │ └── Repositories │ │ ├── Contracts │ │ ├── ICustomerRepository.cs │ │ ├── IOrderRepository.cs │ │ └── IRepository2.cs │ │ ├── CustomerRepository.cs │ │ ├── OrderRepository.cs │ │ └── Repository2.cs │ ├── Executor.cs │ └── UnitOfWorkLibrary.csproj ├── BehavioralPatterns ├── ChainOfResponsibility │ └── ChainOfResponsibilityLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── ChainOfResponsibilityLibrary.csproj │ │ ├── Executor.cs │ │ ├── LoggingExample │ │ ├── Common │ │ │ ├── LogLevel.cs │ │ │ └── Logger.cs │ │ ├── Loggers │ │ │ ├── ConsoleLogger.cs │ │ │ ├── FileLogger.cs │ │ │ └── PriorityLogger.cs │ │ └── LoggingExecutor.cs │ │ ├── PokerExample │ │ ├── Categorizers │ │ │ ├── Common │ │ │ │ └── HandCategorizer.cs │ │ │ ├── FlushCategorizer.cs │ │ │ ├── FourOfAKindCategorizer.cs │ │ │ ├── FullHouseCategorizer.cs │ │ │ ├── HighCardCategorizer.cs │ │ │ ├── PairCategorizer.cs │ │ │ ├── RoyalFlushCategorizer.cs │ │ │ ├── StraightCategorizer.cs │ │ │ ├── StraightFlushCategorizer.cs │ │ │ ├── ThreeOfAKindCategorizer.cs │ │ │ └── TwoPairCategorizer.cs │ │ ├── HandCategorizerChain.cs │ │ ├── Models │ │ │ ├── Card.cs │ │ │ ├── Deck.cs │ │ │ ├── Enums │ │ │ │ ├── HandRanking.cs │ │ │ │ ├── Suit.cs │ │ │ │ └── Value.cs │ │ │ └── Hand.cs │ │ └── PokerExecutor.cs │ │ └── PurchaseApprovalExample │ │ ├── Common │ │ ├── Approver.cs │ │ └── Purchase.cs │ │ ├── Handlers │ │ ├── Director.cs │ │ ├── ExecutiveMeeting.cs │ │ ├── Manager.cs │ │ ├── President.cs │ │ └── VicePresident.cs │ │ └── PurchaseApprovalExecutor.cs ├── Command │ └── CommandLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── CommandLibrary.csproj │ │ ├── EmailExample │ │ ├── Commands │ │ │ ├── Common │ │ │ │ └── ICommand.cs │ │ │ ├── DeleteCommand.cs │ │ │ ├── ForwardCommand.cs │ │ │ └── ReadCommand.cs │ │ ├── Email.cs │ │ ├── EmailExecutor.cs │ │ └── Toolbar.cs │ │ ├── Executor.cs │ │ ├── ShoppingCartExample │ │ ├── CommandManager.cs │ │ ├── Commands │ │ │ ├── AddToCartCommand.cs │ │ │ ├── ChangeCartQuantityCommand.cs │ │ │ ├── Common │ │ │ │ └── ICommand.cs │ │ │ ├── EmptyCartCommand.cs │ │ │ └── RemoveFromCartCommand.cs │ │ ├── Models │ │ │ ├── ChangeCartQuantityOperation.cs │ │ │ └── Product.cs │ │ ├── Repositories │ │ │ ├── Common │ │ │ │ ├── IProductRepository.cs │ │ │ │ └── IShoppingCartRepository.cs │ │ │ ├── ProductRepository.cs │ │ │ └── ShoppingCartRepository.cs │ │ └── ShoppingCartExecutor.cs │ │ └── StockExample │ │ ├── Broker.cs │ │ ├── Commands │ │ ├── BuyStockCommand.cs │ │ ├── Common │ │ │ └── IOrderCommand.cs │ │ └── SellStockCommand.cs │ │ ├── Stock.cs │ │ └── StockExecutor.cs ├── Iterator │ └── IteratorLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── ConceptualExample │ │ ├── Collections │ │ │ ├── Common │ │ │ │ └── IterableCollection.cs │ │ │ └── WordsCollection.cs │ │ ├── ConceptualExecutor.cs │ │ └── Iterators │ │ │ ├── AlphabeticalOrderIterator.cs │ │ │ └── Common │ │ │ └── Iterator.cs │ │ ├── Executor.cs │ │ ├── IteratorLibrary.csproj │ │ └── MusicFestivalsExample │ │ ├── Collections │ │ ├── Common │ │ │ └── IIterableCollection.cs │ │ └── FestivalCollection.cs │ │ ├── Iterators │ │ ├── Common │ │ │ └── IIterator.cs │ │ └── FestivalIterator.cs │ │ ├── MusicFestival.cs │ │ └── MusicFestivalsExecutor.cs ├── Mediator │ └── MediatorLibrary │ │ ├── AirTrafficControlExample │ │ ├── AirTrafficControlExecutor.cs │ │ ├── Components │ │ │ ├── AirbusA320.cs │ │ │ ├── Boeing737.cs │ │ │ ├── Boeing777.cs │ │ │ └── Common │ │ │ │ └── Aircraft.cs │ │ └── Mediators │ │ │ ├── Common │ │ │ └── IAirTrafficControl.cs │ │ │ └── FrankfurtAirTrafficControl.cs │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Executor.cs │ │ ├── GroupChatExample │ │ ├── Components │ │ │ ├── Common │ │ │ │ └── User.cs │ │ │ └── ViberUser.cs │ │ ├── GroupChatExecutor.cs │ │ └── Mediators │ │ │ ├── Common │ │ │ └── IGroupChatMediator.cs │ │ │ └── ViberGroupChatMediator.cs │ │ └── MediatorLibrary.csproj ├── Memento │ └── MementoLibrary │ │ ├── Assets │ │ ├── pattern-structure-1.png │ │ ├── pattern-structure-2.png │ │ └── pattern-structure-3.png │ │ ├── ConceptualExample │ │ ├── Caretaker.cs │ │ ├── ConceptualExecutor.cs │ │ ├── ConcreteMemento.cs │ │ ├── IMemento.cs │ │ └── Originator.cs │ │ ├── Executor.cs │ │ ├── FoodSupplierExample │ │ ├── FoodSupplier.cs │ │ ├── FoodSupplierExecutor.cs │ │ ├── FoodSupplierMemento.cs │ │ ├── IMemento.cs │ │ └── SupplierRegistry.cs │ │ └── MementoLibrary.csproj ├── Observer │ └── ObserverLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Executor.cs │ │ ├── NewspaperExample │ │ ├── NewspaperExecutor.cs │ │ ├── Publishers │ │ │ ├── Common │ │ │ │ └── Newspaper.cs │ │ │ └── DailyMail.cs │ │ └── Subscribers │ │ │ ├── Common │ │ │ └── IUser.cs │ │ │ └── User.cs │ │ ├── ObserverLibrary.csproj │ │ └── StockExample │ │ ├── Examples │ │ ├── EventAndDelegate │ │ │ ├── EventAndDelegateExecutor.cs │ │ │ ├── Publishers │ │ │ │ └── StockTicker.cs │ │ │ ├── StockChangeEventArgs.cs │ │ │ └── Subscribers │ │ │ │ ├── GoogleSubscriber.cs │ │ │ │ └── MicrosoftSubscriber.cs │ │ ├── IObserver │ │ │ ├── ObserverExecutor.cs │ │ │ ├── Publishers │ │ │ │ └── StockTicker.cs │ │ │ └── Subscribers │ │ │ │ ├── DisposableSubscriber.cs │ │ │ │ ├── GoogleSubscriber.cs │ │ │ │ └── MicrosoftSubscriber.cs │ │ ├── Motivating │ │ │ └── MotivatingExecutor.cs │ │ ├── Stock.cs │ │ ├── StockRepository.cs │ │ └── Traditional │ │ │ ├── Publishers │ │ │ ├── Common │ │ │ │ └── Publisher.cs │ │ │ └── StockTicker.cs │ │ │ ├── Subscribers │ │ │ ├── Common │ │ │ │ └── Subscriber.cs │ │ │ ├── GoogleSubscriber.cs │ │ │ └── MicrosoftSubscriber.cs │ │ │ └── TraditionalExecutor.cs │ │ └── StockExecutor.cs ├── State │ └── StateLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── ConceptualExample │ │ ├── ConceptualExecutor.cs │ │ ├── Context.cs │ │ └── States │ │ │ ├── Common │ │ │ └── State.cs │ │ │ ├── ConcreteStateA.cs │ │ │ └── ConcreteStateB.cs │ │ ├── Executor.cs │ │ ├── PackageExample │ │ ├── Package.cs │ │ ├── PackageExecutor.cs │ │ └── States │ │ │ ├── Common │ │ │ └── PackageState.cs │ │ │ ├── DeliveredState.cs │ │ │ ├── OrderedState.cs │ │ │ └── ReceivedState.cs │ │ ├── StateLibrary.csproj │ │ └── SteakCookingExample │ │ ├── States │ │ ├── Common │ │ │ └── Doneness.cs │ │ ├── Medium.cs │ │ ├── MediumRare.cs │ │ ├── Overcooked.cs │ │ ├── Rare.cs │ │ ├── Uncooked.cs │ │ └── WellDone.cs │ │ ├── Steak.cs │ │ └── SteakCookingExecutor.cs ├── Strategy │ └── StrategyLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Executor.cs │ │ ├── ShippingExample │ │ ├── Address.cs │ │ ├── Order.cs │ │ ├── ShippingCostCalculationService.cs │ │ ├── ShippingExecutor.cs │ │ └── ShippingProviders │ │ │ ├── Common │ │ │ └── IShippingProvider.cs │ │ │ ├── FedEx.cs │ │ │ ├── RoyalMail.cs │ │ │ └── UnitedParcelService.cs │ │ ├── SortingExample │ │ ├── Person.cs │ │ ├── SortablePersons.cs │ │ ├── SortingExecutor.cs │ │ └── Strategies │ │ │ ├── Common │ │ │ └── ISortStrategy.cs │ │ │ ├── SortByFirstName.cs │ │ │ ├── SortByLastName.cs │ │ │ └── SortByYearOfBirth.cs │ │ └── StrategyLibrary.csproj ├── TemplateMethod │ └── TemplateMethodLibrary │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── BreadExample │ │ ├── Bread.cs │ │ ├── BreadExecutor.cs │ │ ├── WhiteBread.cs │ │ └── WholeWheatBread.cs │ │ ├── ConceptualExample │ │ ├── AbstractClass.cs │ │ ├── Client.cs │ │ ├── ConceptualExecutor.cs │ │ ├── ConcreteClass1.cs │ │ └── ConcreteClass2.cs │ │ ├── Executor.cs │ │ └── TemplateMethodLibrary.csproj └── Visitor │ └── VisitorLibrary │ ├── Assets │ └── pattern-structure.png │ ├── CompanyExample │ ├── Company.cs │ ├── CompanyExecutor.cs │ ├── Elements │ │ ├── Common │ │ │ ├── Employee.cs │ │ │ └── IEmployeeEvaluation.cs │ │ ├── Developer.cs │ │ ├── ProductOwner.cs │ │ └── ProjectManager.cs │ └── Visitors │ │ ├── Common │ │ └── IPerformanceReview.cs │ │ ├── IncomeRegulation.cs │ │ └── VacationRegulation.cs │ ├── Executor.cs │ ├── PersonDynamicProgrammingExample │ ├── Elements │ │ ├── BankSavingsAccount.cs │ │ ├── Common │ │ │ └── IAsset.cs │ │ ├── Loan.cs │ │ └── RealEstate.cs │ ├── Person.cs │ ├── PersonDynamicProgrammingExecutor.cs │ └── Visitors │ │ ├── Common │ │ └── AssetVisitor.cs │ │ ├── MonthlyIncomeVisitor.cs │ │ └── NetWorthVisitor.cs │ ├── PersonExample │ ├── Elements │ │ ├── BankSavingsAccount.cs │ │ ├── Common │ │ │ └── IAsset.cs │ │ ├── Loan.cs │ │ └── RealEstate.cs │ ├── Person.cs │ ├── PersonExecutor.cs │ └── Visitors │ │ ├── Common │ │ └── IVisitor.cs │ │ ├── MonthlyIncomeVisitor.cs │ │ └── NetWorthVisitor.cs │ └── VisitorLibrary.csproj ├── BuildingBlocks ├── BuildingBlocks.csproj ├── ConsoleExtension.cs └── PatternExecutor.cs ├── CreationalPatterns ├── AbstractFactory │ ├── MealSimpleFactory │ │ ├── Executor.cs │ │ ├── Factories │ │ │ └── MealFactory.cs │ │ ├── MealSimpleFactory.csproj │ │ └── Meals │ │ │ ├── Common │ │ │ └── IMeal.cs │ │ │ ├── GreenSalad.cs │ │ │ ├── Hamburger.cs │ │ │ └── NullMeal.cs │ └── RestaurantAbstractFactory │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Common │ │ ├── Factories │ │ │ └── IRestaurantFactory.cs │ │ └── Products │ │ │ ├── IAppetizer.cs │ │ │ ├── IDessert.cs │ │ │ ├── IMainCourse.cs │ │ │ └── IMeal.cs │ │ ├── Executor.cs │ │ ├── FastFood │ │ ├── FastFoodRestaurantFactory.cs │ │ └── Products │ │ │ ├── FastFoodAppetizer.cs │ │ │ ├── FastFoodDessert.cs │ │ │ └── FastFoodMainCourse.cs │ │ ├── RestaurantAbstractFactory.csproj │ │ └── Vegetarian │ │ ├── Products │ │ ├── VegetarianAppetizer.cs │ │ ├── VegetarianDessert.cs │ │ └── VegetarianMainCourse.cs │ │ └── VegetarianRestaurantFactory.cs ├── Builder │ └── CustomSandwichBuilder │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Builders │ │ ├── CheapSandwichBuilder.cs │ │ ├── Common │ │ │ └── SandwichBuilder.cs │ │ └── PremiumSandwichBuilder.cs │ │ ├── CustomSandwichBuilder.csproj │ │ ├── Directors │ │ └── SandwichDirector.cs │ │ ├── Executor.cs │ │ └── Products │ │ ├── Enums │ │ ├── BreadType.cs │ │ ├── CheeseType.cs │ │ └── MeatType.cs │ │ └── Sandwich.cs ├── FactoryMethod │ └── RestaurantManagement │ │ ├── Assets │ │ └── pattern-structure.png │ │ ├── Common │ │ ├── IMeal.cs │ │ └── Restaurant.cs │ │ ├── Executor.cs │ │ ├── FastFood │ │ ├── FastFoodRestaurant.cs │ │ └── Hamburger.cs │ │ ├── RestaurantManagement.csproj │ │ └── Vegetarian │ │ ├── GreenSalad.cs │ │ └── VegetarianRestaurant.cs ├── Prototype │ └── PrototypeLibrary │ │ ├── Assets │ │ ├── pattern-structure-with-registry.png │ │ └── pattern-structure.png │ │ ├── ColorRegistryExample │ │ ├── Color.cs │ │ ├── ColorRegistry.cs │ │ ├── ColorRegistryExecutor.cs │ │ └── Common │ │ │ └── IColorPrototype.cs │ │ ├── ComplexUnstableObjectExample │ │ ├── ComplexUnstableObject.cs │ │ └── ComplexUnstableObjectExecutor.cs │ │ ├── DeepCloneExample │ │ ├── DeepCloneExecutor.cs │ │ ├── Extensions │ │ │ └── SystemExtension.cs │ │ └── Models │ │ │ ├── MobilePhone.cs │ │ │ └── OperatingSystem.cs │ │ ├── Executor.cs │ │ ├── LogicPuzzleExample │ │ ├── LogicPuzzle.cs │ │ └── LogicPuzzleExecutor.cs │ │ ├── PrototypeLibrary.csproj │ │ └── WebPageScraperExample │ │ ├── ICustomCloneable.cs │ │ ├── WebPageScraper.cs │ │ └── WebPageScraperExecutor.cs └── Singleton │ └── Greeter │ ├── Assets │ └── pattern-structure.png │ ├── Executor.cs │ ├── Greeter.csproj │ └── Types │ ├── Common │ └── BaseGreeter.cs │ ├── DotNetLazyGreeter.cs │ ├── DoubleCheckGreeter.cs │ ├── LocklessFullyLazyGreeter.cs │ ├── LocklessGreeter.cs │ ├── SimpleGreeter.cs │ └── SimpleThreadSafetyGreeter.cs ├── DesignPatternsLibrary.sln ├── DesignPatternsLibrary ├── DesignPatternsLibrary.csproj ├── PatternExecutorsRegistry.cs ├── Program.cs └── Properties │ └── launchSettings.json └── StructuralPatterns ├── Adapter └── AdapterLibrary │ ├── AdapterLibrary.csproj │ ├── Assets │ ├── pattern-structure-class-adapter.png │ └── pattern-structure-object-adapter.png │ ├── BillingSystemExample │ ├── BillingSystemExecutor.cs │ ├── Employee.cs │ ├── HRSystem.cs │ ├── HRSystemAdapter.cs │ ├── ISalaryProcessor.cs │ └── ThirdPartyBillingSystem.cs │ ├── Executor.cs │ └── MovieBroadcasterExample │ ├── BroadcastAdapter.cs │ ├── IBroadcaster.cs │ ├── Movie.cs │ ├── MovieBroadcasterExecutor.cs │ ├── MovieRegistry.cs │ └── ThirdPartyBroadcaster.cs ├── Bridge └── BridgeLibrary │ ├── Assets │ └── pattern-structure.png │ ├── BridgeLibrary.csproj │ ├── DevicesAndRemotesExample │ ├── Abstractions │ │ ├── AdvancedRemoteControl.cs │ │ ├── Common │ │ │ └── RemoteControl.cs │ │ └── UniversalRemoteControl.cs │ ├── DevicesAndRemotesExecutor.cs │ └── Implementations │ │ ├── Common │ │ └── Device.cs │ │ ├── Radio.cs │ │ └── SmartTV.cs │ ├── DocumentsAndFormattersExample │ ├── Documents │ │ ├── Book.cs │ │ ├── Common │ │ │ └── Document.cs │ │ ├── FAQ.cs │ │ └── TermPaper.cs │ ├── DocumentsAndFormattersExecutor.cs │ └── Formatters │ │ ├── BackwardsFormatter.cs │ │ ├── Common │ │ └── IFormatter.cs │ │ ├── FancyFormatter.cs │ │ └── StandardFormatter.cs │ ├── Executor.cs │ └── MovieLicenseExample │ ├── Models │ ├── Enums │ │ ├── Discount.cs │ │ ├── LicenseType.cs │ │ └── SpecialOffer.cs │ └── MovieLicense.cs │ └── MovieLicenseExecutor.cs ├── Composite └── CompositeLibrary │ ├── Assets │ └── pattern-structure.png │ ├── CompositeLibrary.csproj │ ├── Executor.cs │ ├── FileSystemExample │ ├── Common │ │ └── FileSystemEntry.cs │ ├── File.cs │ ├── FileSystemExecutor.cs │ └── Folder.cs │ ├── GiftExample │ ├── Common │ │ ├── Gift.cs │ │ └── IGiftOperations.cs │ ├── CompositeGift.cs │ ├── GiftExecutor.cs │ └── SimpleGift.cs │ └── ShareholdersExample │ ├── After │ ├── AfterExecutor.cs │ ├── Common │ │ └── Shareholder.cs │ ├── Corporation.cs │ └── Person.cs │ ├── Before │ ├── BeforeExecutor.cs │ ├── Corporation.cs │ └── Person.cs │ └── ShareholdersExecutor.cs ├── Decorator └── DecoratorLibrary │ ├── Assets │ └── pattern-structure.png │ ├── DataStorageExample │ ├── Components │ │ ├── Common │ │ │ └── IDataSource.cs │ │ └── File.cs │ ├── DataStorageExecutor.cs │ └── Decorators │ │ ├── Common │ │ └── DataSourceDecorator.cs │ │ ├── CompressionDecorator.cs │ │ └── EncryptionDecorator.cs │ ├── DecoratorLibrary.csproj │ ├── Executor.cs │ └── PancakeExample │ ├── Components │ ├── BigPancake.cs │ ├── Common │ │ └── Pancake.cs │ └── SmallPancake.cs │ ├── Decorators │ ├── Common │ │ └── PancakeDecorator.cs │ ├── MapleSyrup.cs │ ├── MixedBerries.cs │ ├── Nutella.cs │ └── WhippedCream.cs │ └── PancakeExecutor.cs ├── Facade └── FacadeLibrary │ ├── Assets │ └── pattern-structure.png │ ├── Executor.cs │ ├── FacadeLibrary.csproj │ ├── MortgageExample │ ├── Facade │ │ └── Mortgage.cs │ ├── MortgageExecutor.cs │ └── Subsystem │ │ ├── Bank.cs │ │ ├── Credit.cs │ │ ├── Customer.cs │ │ ├── CustomerService.cs │ │ └── Loan.cs │ └── WeatherServiceExample │ ├── After │ ├── AfterExecutor.cs │ └── TemperatureFacade │ │ ├── LocalTemperature.cs │ │ └── TemperatureLookupService.cs │ ├── Before │ └── BeforeExecutor.cs │ ├── Service │ ├── Coordinates.cs │ ├── GeoLookupService.cs │ ├── TemperatureConverter.cs │ └── WeatherService.cs │ └── WeatherServiceExecutor.cs ├── Flyweight └── FlyweightLibrary │ ├── Assets │ └── pattern-structure.png │ ├── DotNetStringExample │ └── DotNetStringExecutor.cs │ ├── Executor.cs │ ├── FlyweightLibrary.csproj │ └── ForestExample │ ├── Forest.cs │ ├── ForestExecutor.cs │ ├── Tree.cs │ ├── TreeFactory.cs │ └── TreeType.cs └── Proxy └── ProxyLibrary ├── Assets └── pattern-structure.png ├── CachingProxyExample ├── CachingProxyExecutor.cs ├── Common │ ├── IYoutubeOperations.cs │ ├── Video.cs │ └── VideoMetadata.cs ├── Manager │ └── YoutubeManager.cs ├── Proxy │ └── CachedYoutube.cs └── ThirdParty │ ├── ContentStorage.cs │ ├── MetadataStorage.cs │ └── Youtube.cs ├── Executor.cs ├── LoggingProxyExample ├── Client.cs ├── ISubject.cs ├── LoggingProxyExecutor.cs ├── Proxy.cs └── RealSubject.cs ├── ProtectionProxyExample ├── Employee.cs ├── ISharedFolder.cs ├── ProtectionProxyExecutor.cs ├── Role.cs ├── SharedFolder.cs └── SharedFolderProxy.cs └── ProxyLibrary.csproj /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md 26 | !**/.gitignore 27 | !.git/HEAD 28 | !.git/config 29 | !.git/packed-refs 30 | !.git/refs/heads/** -------------------------------------------------------------------------------- /assets/images/console-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/assets/images/console-menu.png -------------------------------------------------------------------------------- /assets/images/design-patterns-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/assets/images/design-patterns-types.png -------------------------------------------------------------------------------- /assets/images/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/assets/images/twitter.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/EventAggregator/StoreManagement/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Components/Publishers/OrderPublisher.cs: -------------------------------------------------------------------------------- 1 | using StoreManagement.Contracts; 2 | using StoreManagement.Events; 3 | 4 | namespace StoreManagement.Components.Publishers; 5 | 6 | public class OrderPublisher : IPublisher 7 | { 8 | private readonly IEventAggregator _eventAggregator; 9 | 10 | public OrderPublisher(IEventAggregator eventAggregator) 11 | { 12 | _eventAggregator = eventAggregator; 13 | } 14 | 15 | public void Publish(string payload) => 16 | _eventAggregator.Publish(new OrderCreatedEvent(payload)); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Components/Publishers/WarehousePublisher.cs: -------------------------------------------------------------------------------- 1 | using StoreManagement.Contracts; 2 | using StoreManagement.Events; 3 | 4 | namespace StoreManagement.Components.Publishers; 5 | 6 | public class WarehousePublisher : IPublisher 7 | { 8 | private readonly IEventAggregator _eventAggregator; 9 | 10 | public WarehousePublisher(IEventAggregator eventAggregator) 11 | { 12 | _eventAggregator = eventAggregator; 13 | } 14 | 15 | public void Publish(string payload) => 16 | _eventAggregator.Publish(new WarehouseReceivedNewSuppliesEvent(payload)); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Contracts/ICustomObserver.cs: -------------------------------------------------------------------------------- 1 | namespace StoreManagement.Contracts; 2 | 3 | public interface ICustomObserver : IObserver 4 | where T : IEvent 5 | { 6 | void Unsubscribe(); 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Contracts/IEvent.cs: -------------------------------------------------------------------------------- 1 | namespace StoreManagement.Contracts; 2 | 3 | public interface IEvent 4 | { 5 | public string Description { get; } 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Contracts/IEventAggregator.cs: -------------------------------------------------------------------------------- 1 | namespace StoreManagement.Contracts; 2 | 3 | public interface IEventAggregator : IObservable 4 | { 5 | void Publish(IEvent message); 6 | 7 | IDisposable Subscribe(ICustomObserver observer); 8 | 9 | IDisposable Subscribe(ICustomObserver observer) 10 | where T : IEvent; 11 | } 12 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Contracts/IPublisher.cs: -------------------------------------------------------------------------------- 1 | namespace StoreManagement.Contracts; 2 | 3 | public interface IPublisher 4 | { 5 | void Publish(string payload); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Events/OrderCreatedEvent.cs: -------------------------------------------------------------------------------- 1 | using StoreManagement.Contracts; 2 | 3 | namespace StoreManagement.Events; 4 | 5 | public class OrderCreatedEvent : IEvent 6 | { 7 | public OrderCreatedEvent(string description) 8 | { 9 | Description = description; 10 | } 11 | 12 | public string Description { get; } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/Events/WarehouseReceivedNewSuppliesEvent.cs: -------------------------------------------------------------------------------- 1 | using StoreManagement.Contracts; 2 | 3 | namespace StoreManagement.Events; 4 | 5 | public class WarehouseReceivedNewSuppliesEvent : IEvent 6 | { 7 | public WarehouseReceivedNewSuppliesEvent(string description) 8 | { 9 | Description = description; 10 | } 11 | 12 | public string Description { get; } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/EventAggregator/StoreManagement/StoreManagement.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/FluentInterface/FluentInterfaceLibrary/BlobStorageExample/BlobStorageExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace FluentInterfaceLibrary.BlobStorageExample; 4 | 5 | public static class BlobStorageExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Blob Storage example"); 10 | 11 | BlobStorageManager 12 | .Connect("DefaultEndpointsProtocol=https;AccountName=myAccountName;AccountKey=") 13 | .OnBlob("container", "blob") 14 | .Download("blobStorageManual.pdf") 15 | .ToFolder(@"D:\DesignPatternsLibrary\Downloads"); 16 | } 17 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/FluentInterface/FluentInterfaceLibrary/BlobStorageExample/Contracts/IBlobStorageAction.cs: -------------------------------------------------------------------------------- 1 | namespace FluentInterfaceLibrary.BlobStorageExample.Contracts; 2 | 3 | // Interfaces IWrite and IRead are used as a prevention mechanism for invalid method combinations. 4 | public interface IBlobStorageAction 5 | { 6 | IWrite Download(string fileName); 7 | IRead Upload(string fileName); 8 | void Preview(string fileName); 9 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/FluentInterface/FluentInterfaceLibrary/BlobStorageExample/Contracts/IBlobStorageSelector.cs: -------------------------------------------------------------------------------- 1 | namespace FluentInterfaceLibrary.BlobStorageExample.Contracts; 2 | 3 | public interface IBlobStorageSelector 4 | { 5 | IBlobStorageAction OnBlob(string containerName, string blobName); 6 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/FluentInterface/FluentInterfaceLibrary/BlobStorageExample/Contracts/IRead.cs: -------------------------------------------------------------------------------- 1 | namespace FluentInterfaceLibrary.BlobStorageExample.Contracts; 2 | 3 | public interface IRead 4 | { 5 | void FromFile(string filePath); 6 | void FromStream(Stream stream); 7 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/FluentInterface/FluentInterfaceLibrary/BlobStorageExample/Contracts/IWrite.cs: -------------------------------------------------------------------------------- 1 | namespace FluentInterfaceLibrary.BlobStorageExample.Contracts; 2 | 3 | public interface IWrite 4 | { 5 | void ToFolder(string folderPath); 6 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/FluentInterface/FluentInterfaceLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using FluentInterfaceLibrary.BlobStorageExample; 3 | using FluentInterfaceLibrary.LinqExample; 4 | 5 | namespace FluentInterfaceLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Fluent Interface - Creational Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | BlobStorageExecutor.Execute(); 14 | LinqExecutor.Execute(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/FluentInterface/FluentInterfaceLibrary/FluentInterfaceLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/Interpreter/InterpreterLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/DateExample/Context.cs: -------------------------------------------------------------------------------- 1 | namespace InterpreterLibrary.DateExample; 2 | 3 | public class Context 4 | { 5 | public Context(DateTime date, string expression) 6 | { 7 | Date = date; 8 | Expression = expression; 9 | } 10 | 11 | public DateTime Date { get; set; } 12 | public string Expression { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/DateExample/Expressions/Common/IExpression.cs: -------------------------------------------------------------------------------- 1 | namespace InterpreterLibrary.DateExample.Expressions.Common; 2 | 3 | public interface IExpression 4 | { 5 | void Evaluate(Context context); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/DateExample/Expressions/Terminal/DayExpression.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.DateExample.Expressions.Common; 2 | 3 | namespace InterpreterLibrary.DateExample.Expressions.Terminal; 4 | 5 | public class DayExpression : IExpression 6 | { 7 | public void Evaluate(Context context) 8 | { 9 | string expression = context.Expression; 10 | context.Expression = expression.Replace("DD", context.Date.Day.ToString()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/DateExample/Expressions/Terminal/MonthExpression.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.DateExample.Expressions.Common; 2 | 3 | namespace InterpreterLibrary.DateExample.Expressions.Terminal; 4 | 5 | public class MonthExpression : IExpression 6 | { 7 | public void Evaluate(Context context) 8 | { 9 | string expression = context.Expression; 10 | context.Expression = expression.Replace("MM", context.Date.Month.ToString()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/DateExample/Expressions/Terminal/SeparatorExpression.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.DateExample.Expressions.Common; 2 | 3 | namespace InterpreterLibrary.DateExample.Expressions.Terminal; 4 | 5 | public class SeparatorExpression : IExpression 6 | { 7 | public void Evaluate(Context context) 8 | { 9 | string expression = context.Expression; 10 | context.Expression = expression.Replace(" ", "-"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/DateExample/Expressions/Terminal/YearExpression.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.DateExample.Expressions.Common; 2 | 3 | namespace InterpreterLibrary.DateExample.Expressions.Terminal; 4 | 5 | public class YearExpression : IExpression 6 | { 7 | public void Evaluate(Context context) 8 | { 9 | string expression = context.Expression; 10 | context.Expression = expression.Replace("YYYY", context.Date.Year.ToString()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using InterpreterLibrary.DateExample; 3 | using InterpreterLibrary.SandwichExample; 4 | 5 | namespace InterpreterLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Interpreter - Behavioral Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | DateExecutor.Execute(); 14 | SandwichExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/InterpreterLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Context.cs: -------------------------------------------------------------------------------- 1 | namespace InterpreterLibrary.SandwichExample; 2 | 3 | public class Context 4 | { 5 | public string Output { get; set; } = string.Empty; 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Common/IExpression.cs: -------------------------------------------------------------------------------- 1 | namespace InterpreterLibrary.SandwichExample.Expressions.Common; 2 | 3 | public interface IExpression 4 | { 5 | void Interpret(Context context); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/NonTerminal/CondimentList.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Condiments.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.NonTerminal; 4 | 5 | public class CondimentList 6 | { 7 | private readonly IEnumerable _condiments; 8 | 9 | public CondimentList(IEnumerable condiments) 10 | { 11 | _condiments = condiments; 12 | } 13 | 14 | public void Interpret(Context context) 15 | { 16 | foreach (var condiment in _condiments) 17 | { 18 | condiment.Interpret(context); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Breads/Common/IBread.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Breads.Common; 4 | 5 | public interface IBread : IExpression 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Breads/WheatBread.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Breads.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Breads; 4 | 5 | public class WheatBread : IBread 6 | { 7 | public void Interpret(Context context) => 8 | context.Output += " Wheat-Bread "; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Breads/WhiteBread.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Breads.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Breads; 4 | 5 | public class WhiteBread : IBread 6 | { 7 | public void Interpret(Context context) => 8 | context.Output += " White-Bread "; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Condiments/Common/ICondiment.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Condiments.Common; 4 | 5 | public interface ICondiment : IExpression 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Condiments/KetchupCondiment.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Condiments.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Condiments; 4 | 5 | public class KetchupCondiment : ICondiment 6 | { 7 | public void Interpret(Context context) => 8 | context.Output += " Ketchup "; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Condiments/MayoCondiment.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Condiments.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Condiments; 4 | 5 | public class MayoCondiment : ICondiment 6 | { 7 | public void Interpret(Context context) => 8 | context.Output += " Mayo "; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Condiments/MustardCondiment.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Condiments.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Condiments; 4 | 5 | public class MustardCondiment : ICondiment 6 | { 7 | public void Interpret(Context context) => 8 | context.Output += " Mustard "; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Ingredients/ChickenIngredient.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Ingredients.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Ingredients; 4 | 5 | public class ChickenIngredient : IIngredient 6 | { 7 | public void Interpret(Context context) => 8 | context.Output += " Chicken "; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Ingredients/Common/IIngredient.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Ingredients.Common; 4 | 5 | public interface IIngredient : IExpression 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Ingredients/LettuceIngredient.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Ingredients.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Ingredients; 4 | 5 | public class LettuceIngredient : IIngredient 6 | { 7 | public void Interpret(Context context) => 8 | context.Output += " Lettuce "; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Interpreter/InterpreterLibrary/SandwichExample/Expressions/Terminal/Ingredients/TomatoIngredient.cs: -------------------------------------------------------------------------------- 1 | using InterpreterLibrary.SandwichExample.Expressions.Terminal.Ingredients.Common; 2 | 3 | namespace InterpreterLibrary.SandwichExample.Expressions.Terminal.Ingredients; 4 | 5 | public class TomatoIngredient : IIngredient 6 | { 7 | public void Interpret(Context context) => 8 | context.Output += " Tomato "; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/Assets/pattern-structure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/Assets/pattern-structure-1.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/Assets/pattern-structure-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/Assets/pattern-structure-2.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using LazyLoadLibrary.GhostsExample; 3 | using LazyLoadLibrary.LazyInitializationExample; 4 | using LazyLoadLibrary.ValueHolderExample; 5 | using LazyLoadLibrary.VirtualProxyExample; 6 | 7 | namespace LazyLoadLibrary; 8 | 9 | public class Executor : PatternExecutor 10 | { 11 | public override string Name => "Lazy Load - Data Access Pattern"; 12 | 13 | public override void Execute() 14 | { 15 | GhostsExecutor.Execute(); 16 | LazyInitializationExecutor.Execute(); 17 | ValueHolderExecutor.Execute(); 18 | VirtualProxyExecutor.Execute(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/GhostsExample/CollegeFactory.cs: -------------------------------------------------------------------------------- 1 | namespace LazyLoadLibrary.GhostsExample; 2 | 3 | public class CollegeFactory 4 | { 5 | public GhostCollege CreateFromId(int id) => new(id); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/GhostsExample/LoadStatus.cs: -------------------------------------------------------------------------------- 1 | namespace LazyLoadLibrary.GhostsExample; 2 | 3 | public enum LoadStatus 4 | { 5 | Unloaded, 6 | Loading, 7 | Loaded, 8 | } 9 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/LazyInitializationExample/LazyInitializationExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace LazyLoadLibrary.LazyInitializationExample; 4 | 5 | public static class LazyInitializationExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Lazy initialization example"); 10 | 11 | var college = new LazyCollege(); 12 | Console.WriteLine("Give me more details about the college!"); 13 | college.ShowDetails(); 14 | 15 | var dotNetCollege = new DotNetLazyCollege(); 16 | Console.WriteLine("\nGive me more details about the college!"); 17 | dotNetCollege.ShowDetails(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/LazyLoadLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/Library.cs: -------------------------------------------------------------------------------- 1 | namespace LazyLoadLibrary; 2 | 3 | public class Library 4 | { 5 | public Library() 6 | { 7 | Console.WriteLine("Loading library..."); 8 | 9 | Name = "Library"; 10 | EstablishmentDate = new DateTime(2012, 5, 25); 11 | Address = "3537 Wood Street, Saginaw"; 12 | NumberOfBooks = 10000; 13 | } 14 | 15 | public string Name { get; } 16 | public DateTime EstablishmentDate { get; } 17 | public string Address { get; } 18 | public int NumberOfBooks { get; } 19 | } 20 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/ValueHolderExample/CollegeFactory.cs: -------------------------------------------------------------------------------- 1 | namespace LazyLoadLibrary.ValueHolderExample; 2 | 3 | public class CollegeFactory 4 | { 5 | public ValueHolderCollege CreateFromId(int id) => new(id); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/ValueHolderExample/IValueLoader.cs: -------------------------------------------------------------------------------- 1 | namespace LazyLoadLibrary.ValueHolderExample; 2 | 3 | public interface IValueLoader 4 | { 5 | T Load(); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/ValueHolderExample/LibraryLoader.cs: -------------------------------------------------------------------------------- 1 | namespace LazyLoadLibrary.ValueHolderExample; 2 | 3 | public class LibraryLoader : IValueLoader 4 | { 5 | public Library Load() => new(); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/ValueHolderExample/ValueHolderExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace LazyLoadLibrary.ValueHolderExample; 4 | 5 | public static class ValueHolderExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Value holder example"); 10 | 11 | var collegeFactory = new CollegeFactory(); 12 | var college = collegeFactory.CreateFromId(1); 13 | 14 | Console.WriteLine("Give me more details about the college!"); 15 | college.ShowDetails(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/VirtualProxyExample/College.cs: -------------------------------------------------------------------------------- 1 | namespace LazyLoadLibrary.VirtualProxyExample; 2 | 3 | public class College 4 | { 5 | public int Id { get; init; } 6 | 7 | public virtual Library? Library { get; set; } 8 | 9 | public void ShowDetails() => 10 | Console.WriteLine( 11 | $"College library with {Library!.NumberOfBooks} books " + 12 | $"was established on {Library.EstablishmentDate.ToShortDateString()}."); 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/VirtualProxyExample/CollegeFactory.cs: -------------------------------------------------------------------------------- 1 | namespace LazyLoadLibrary.VirtualProxyExample; 2 | 3 | public class CollegeFactory 4 | { 5 | public College CreateFromId(int id) => new ProxyCollege(id); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/LazyLoad/LazyLoadLibrary/VirtualProxyExample/VirtualProxyExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace LazyLoadLibrary.VirtualProxyExample; 4 | 5 | public static class VirtualProxyExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Virtual proxy example"); 10 | 11 | var collegeFactory = new CollegeFactory(); 12 | var college = collegeFactory.CreateFromId(1); 13 | 14 | // College library shouldn't have been constructed before calling ShowDetails method. 15 | Console.WriteLine("Give me more details about the college!"); 16 | college.ShowDetails(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/NullObject/NullObjectLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/NullObject/NullObjectLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/NullObject/NullObjectLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using NullObjectLibrary.SmartphoneApplicationExample; 3 | 4 | namespace NullObjectLibrary; 5 | 6 | public class Executor : PatternExecutor 7 | { 8 | public override string Name => "Null Object - Behavioral Pattern"; 9 | 10 | public override void Execute() => 11 | SmartphoneApplicationExecutor.Execute(); 12 | } 13 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/NullObject/NullObjectLibrary/NullObjectLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/NullObject/NullObjectLibrary/SmartphoneApplicationExample/Applications/Common/Application.cs: -------------------------------------------------------------------------------- 1 | namespace NullObjectLibrary.SmartphoneApplicationExample.Applications.Common; 2 | 3 | public abstract class Application 4 | { 5 | protected Application(Guid processId) 6 | { 7 | ProcessId = processId; 8 | } 9 | 10 | public static NullApplication Default { get; } = new(); 11 | 12 | public abstract string Name { get; } 13 | public Guid ProcessId { get; } 14 | 15 | public virtual void Open() => 16 | Console.WriteLine($"{Name} opened."); 17 | 18 | public virtual void Close() => 19 | Console.WriteLine($"{Name} closed."); 20 | } 21 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/NullObject/NullObjectLibrary/SmartphoneApplicationExample/Applications/Gmail.cs: -------------------------------------------------------------------------------- 1 | using NullObjectLibrary.SmartphoneApplicationExample.Applications.Common; 2 | 3 | namespace NullObjectLibrary.SmartphoneApplicationExample.Applications; 4 | 5 | public class Gmail : Application 6 | { 7 | public Gmail(Guid processId) 8 | : base(processId) 9 | { 10 | } 11 | 12 | public override string Name => "Gmail"; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/NullObject/NullObjectLibrary/SmartphoneApplicationExample/Applications/NullApplication.cs: -------------------------------------------------------------------------------- 1 | using NullObjectLibrary.SmartphoneApplicationExample.Applications.Common; 2 | 3 | namespace NullObjectLibrary.SmartphoneApplicationExample.Applications; 4 | 5 | public class NullApplication : Application 6 | { 7 | public NullApplication() 8 | : base(Guid.Empty) 9 | { 10 | } 11 | 12 | public override string Name => string.Empty; 13 | 14 | public override void Open() 15 | { 16 | } 17 | 18 | public override void Close() 19 | { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/NullObject/NullObjectLibrary/SmartphoneApplicationExample/Applications/SubwaySurfers.cs: -------------------------------------------------------------------------------- 1 | using NullObjectLibrary.SmartphoneApplicationExample.Applications.Common; 2 | 3 | namespace NullObjectLibrary.SmartphoneApplicationExample.Applications; 4 | 5 | public class SubwaySurfers : Application 6 | { 7 | public SubwaySurfers(Guid processId) 8 | : base(processId) 9 | { 10 | } 11 | 12 | public override string Name => "Subway Surfers"; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/NullObject/NullObjectLibrary/SmartphoneApplicationExample/Applications/Youtube.cs: -------------------------------------------------------------------------------- 1 | using NullObjectLibrary.SmartphoneApplicationExample.Applications.Common; 2 | 3 | namespace NullObjectLibrary.SmartphoneApplicationExample.Applications; 4 | 5 | public class Youtube : Application 6 | { 7 | public Youtube(Guid processId) 8 | : base(processId) 9 | { 10 | } 11 | 12 | public override string Name => "Youtube"; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/Repository/OrderManagement/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Controllers/CustomerController.cs: -------------------------------------------------------------------------------- 1 | using OrderManagement.Domain; 2 | using OrderManagement.Infrastructure.Repositories.Contracts; 3 | 4 | namespace OrderManagement.Controllers; 5 | 6 | public class CustomerController 7 | { 8 | private readonly ICustomerRepository _customerRepository; 9 | 10 | public CustomerController(ICustomerRepository customerRepository) 11 | { 12 | _customerRepository = customerRepository; 13 | } 14 | 15 | public IEnumerable GetAll() => 16 | _customerRepository.GetAll(); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Domain/Customer.cs: -------------------------------------------------------------------------------- 1 | namespace OrderManagement.Domain; 2 | 3 | public class Customer : Entity 4 | { 5 | public string FirstName { get; set; } = string.Empty; 6 | public string LastName { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Domain/Entity.cs: -------------------------------------------------------------------------------- 1 | namespace OrderManagement.Domain; 2 | 3 | public abstract class Entity 4 | { 5 | public int Id { get; set; } 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Domain/Order.cs: -------------------------------------------------------------------------------- 1 | namespace OrderManagement.Domain; 2 | 3 | public class Order : Entity 4 | { 5 | public string Description { get; set; } = string.Empty; 6 | public string DeliveryAddress { get; set; } = string.Empty; 7 | public decimal Price { get; set; } 8 | } 9 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Infrastructure/OrderManagementContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using OrderManagement.Domain; 3 | 4 | namespace OrderManagement.Infrastructure; 5 | 6 | public class OrderManagementContext : DbContext 7 | { 8 | public DbSet Customers => Set(); 9 | public DbSet Orders => Set(); 10 | 11 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => 12 | optionsBuilder.UseSqlite("Data Source=storage.db"); 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Infrastructure/Repositories/Contracts/ICustomerRepository.cs: -------------------------------------------------------------------------------- 1 | using OrderManagement.Domain; 2 | 3 | namespace OrderManagement.Infrastructure.Repositories.Contracts; 4 | 5 | public interface ICustomerRepository : IRepository 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Infrastructure/Repositories/Contracts/IOrderRepository.cs: -------------------------------------------------------------------------------- 1 | using OrderManagement.Domain; 2 | 3 | namespace OrderManagement.Infrastructure.Repositories.Contracts; 4 | 5 | public interface IOrderRepository : IRepository 6 | { 7 | Order? GetTheMostExpensive(); 8 | } 9 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Infrastructure/Repositories/Contracts/IRepository.cs: -------------------------------------------------------------------------------- 1 | using OrderManagement.Domain; 2 | using System.Linq.Expressions; 3 | 4 | namespace OrderManagement.Infrastructure.Repositories.Contracts; 5 | 6 | public interface IRepository 7 | where T : Entity 8 | { 9 | T Add(T entity); 10 | IEnumerable GetAll(); 11 | IEnumerable Get(Expression> predicate); 12 | T GetById(int id); 13 | void Delete(T entity); 14 | } 15 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Infrastructure/Repositories/Contracts/IUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | namespace OrderManagement.Infrastructure.Repositories.Contracts; 2 | 3 | public interface IUnitOfWork 4 | { 5 | void Commit(); 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Infrastructure/Repositories/CustomerRepository.cs: -------------------------------------------------------------------------------- 1 | using OrderManagement.Domain; 2 | using OrderManagement.Infrastructure.Repositories.Contracts; 3 | 4 | namespace OrderManagement.Infrastructure.Repositories; 5 | 6 | /// 7 | /// In real-life examples different repositories might point to different data sources. 8 | /// 9 | public class CustomerRepository : Repository, ICustomerRepository 10 | { 11 | public CustomerRepository(OrderManagementContext context) 12 | : base(context) 13 | { 14 | } 15 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Infrastructure/Repositories/OrderRepository.cs: -------------------------------------------------------------------------------- 1 | using OrderManagement.Domain; 2 | using OrderManagement.Infrastructure.Repositories.Contracts; 3 | 4 | namespace OrderManagement.Infrastructure.Repositories; 5 | 6 | public class OrderRepository : Repository, IOrderRepository 7 | { 8 | public OrderRepository(OrderManagementContext context) 9 | : base(context) 10 | { 11 | } 12 | 13 | public Order? GetTheMostExpensive() => 14 | _context.Orders 15 | .OrderByDescending(order => order.Price) 16 | .FirstOrDefault(); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/Infrastructure/Repositories/UnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using OrderManagement.Infrastructure.Repositories.Contracts; 2 | 3 | namespace OrderManagement.Infrastructure.Repositories; 4 | 5 | public class UnitOfWork : IUnitOfWork 6 | { 7 | private readonly OrderManagementContext _context; 8 | 9 | public UnitOfWork(OrderManagementContext context) 10 | { 11 | _context = context; 12 | } 13 | 14 | public void Commit() => _context.SaveChanges(); 15 | } 16 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Repository/OrderManagement/OrderManagement.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/Rules/RulesLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/Common/Customer.cs: -------------------------------------------------------------------------------- 1 | namespace RulesLibrary.Common; 2 | 3 | public class Customer 4 | { 5 | public Customer(DateTime dateOfBirth, bool isVeteran, DateTime? dateOfFirstPurchase = null) 6 | { 7 | DateOfBirth = dateOfBirth; 8 | IsVeteran = isVeteran; 9 | DateOfFirstPurchase = dateOfFirstPurchase; 10 | } 11 | public DateTime DateOfBirth { get; } 12 | public DateTime? DateOfFirstPurchase { get; } 13 | public bool IsVeteran { get; } 14 | } 15 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using RulesLibrary.MotivatingExample; 3 | using RulesLibrary.RulesExample; 4 | 5 | namespace RulesLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Rules - Behavioral Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | MotivatingExecutor.Execute(); 14 | RulesExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/RulesExample/Rules/BirthdayDiscountRule.cs: -------------------------------------------------------------------------------- 1 | using RulesLibrary.Common; 2 | using RulesLibrary.RulesExample.Rules.Common; 3 | 4 | namespace RulesLibrary.RulesExample.Rules; 5 | 6 | public class BirthdayDiscountRule : IDiscountRule 7 | { 8 | public decimal CalculateDiscount(Customer customer) 9 | { 10 | if (customer.DateOfBirth.Month == DateTime.Today.Month && 11 | customer.DateOfBirth.Day == DateTime.Today.Day) 12 | { 13 | return 0.10m; 14 | } 15 | 16 | return 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/RulesExample/Rules/Common/IDiscountRule.cs: -------------------------------------------------------------------------------- 1 | using RulesLibrary.Common; 2 | 3 | namespace RulesLibrary.RulesExample.Rules.Common; 4 | 5 | public interface IDiscountRule 6 | { 7 | decimal CalculateDiscount(Customer customer); 8 | } 9 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/RulesExample/Rules/FirstPurchaseRule.cs: -------------------------------------------------------------------------------- 1 | using RulesLibrary.Common; 2 | using RulesLibrary.RulesExample.Rules.Common; 3 | 4 | namespace RulesLibrary.RulesExample.Rules; 5 | 6 | public class FirstPurchaseRule : IDiscountRule 7 | { 8 | public decimal CalculateDiscount(Customer customer) 9 | { 10 | if (!customer.DateOfFirstPurchase.HasValue) 11 | { 12 | return 0.15m; 13 | } 14 | 15 | return 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/RulesExample/Rules/SeniorRule.cs: -------------------------------------------------------------------------------- 1 | using RulesLibrary.Common; 2 | using RulesLibrary.RulesExample.Rules.Common; 3 | 4 | namespace RulesLibrary.RulesExample.Rules; 5 | 6 | public class SeniorRule : IDiscountRule 7 | { 8 | public decimal CalculateDiscount(Customer customer) 9 | { 10 | if (customer.DateOfBirth < DateTime.Now.AddYears(-65)) 11 | { 12 | return 0.05m; 13 | } 14 | 15 | return 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/RulesExample/Rules/VeteranRule.cs: -------------------------------------------------------------------------------- 1 | using RulesLibrary.Common; 2 | using RulesLibrary.RulesExample.Rules.Common; 3 | 4 | namespace RulesLibrary.RulesExample.Rules; 5 | 6 | public class VeteranRule : IDiscountRule 7 | { 8 | public decimal CalculateDiscount(Customer customer) 9 | { 10 | if (customer.IsVeteran) 11 | { 12 | return 0.10m; 13 | } 14 | 15 | return 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Rules/RulesLibrary/RulesLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/Assets/pattern-structure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/ServiceLocator/OrderProcessing/Assets/pattern-structure-1.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/Assets/pattern-structure-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/ServiceLocator/OrderProcessing/Assets/pattern-structure-2.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace OrderProcessing; 4 | 5 | public class Executor : PatternExecutor 6 | { 7 | public override string Name => "Service Locator - Architectural Pattern"; 8 | 9 | public override void Execute() 10 | { 11 | IServiceLocator serviceLocator = new ServiceLocator(); 12 | serviceLocator.AddService(new Logger()); 13 | 14 | var order = new Order 15 | { 16 | ProductId = Guid.NewGuid(), 17 | UnitPrice = 50, 18 | Quantity = 2, 19 | }; 20 | 21 | var orderManager = new OrderManager(serviceLocator); 22 | orderManager.ProcessOrder(order); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/IServiceLocator.cs: -------------------------------------------------------------------------------- 1 | namespace OrderProcessing; 2 | 3 | public interface IServiceLocator 4 | { 5 | void AddService(T service) where T : notnull; 6 | void AddService(string serviceName, T service) where T : notnull; 7 | T GetService() where T : notnull; 8 | object GetService(string serviceName) where T : notnull; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/Logger.cs: -------------------------------------------------------------------------------- 1 | namespace OrderProcessing; 2 | 3 | public class Logger 4 | { 5 | public void Log(string message) => 6 | Console.WriteLine($"Logger: {message}"); 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/NotificationManager.cs: -------------------------------------------------------------------------------- 1 | namespace OrderProcessing; 2 | 3 | public class NotificationManager 4 | { 5 | public void NotifyCustomer(string message) => 6 | Console.WriteLine($"Notification manager: Sending '{message}' message to user."); 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/Order.cs: -------------------------------------------------------------------------------- 1 | namespace OrderProcessing; 2 | 3 | public class Order 4 | { 5 | public Guid ProductId { get; init; } 6 | public decimal UnitPrice { get; init; } 7 | public int Quantity { get; init; } 8 | } 9 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/OrderProcessing.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/ServiceLocator/OrderProcessing/PaymentProcessor.cs: -------------------------------------------------------------------------------- 1 | namespace OrderProcessing; 2 | 3 | public class PaymentProcessor 4 | { 5 | public bool ProcessPayment(decimal amount) 6 | { 7 | Console.WriteLine("Payment processor: Processing payment..."); 8 | return amount <= 100; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/Assets/pattern-structure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/Specification/ProductSpecification/Assets/pattern-structure-1.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/Assets/pattern-structure-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/Specification/ProductSpecification/Assets/pattern-structure-2.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/Domain/ProductCategory.cs: -------------------------------------------------------------------------------- 1 | namespace ProductSpecification.Domain; 2 | 3 | public enum ProductCategory 4 | { 5 | Books, 6 | Electronics, 7 | HomeAndKitchen, 8 | Handmade, 9 | SportsAndOutdoors, 10 | ToysAndGames, 11 | } 12 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/ProductSpecification.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/Specifications/CheapProductSpecification.cs: -------------------------------------------------------------------------------- 1 | using ProductSpecification.Domain; 2 | using ProductSpecification.Specifications.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace ProductSpecification.Specifications; 6 | 7 | /// 8 | /// Domain knowledge is contained within concrete specifications making it much easier to reuse. 9 | /// 10 | public class CheapProductSpecification : Specification 11 | { 12 | private const decimal PriceThreshold = 10; 13 | 14 | public override Expression> ToExpression() => 15 | product => product.Price < PriceThreshold; 16 | } 17 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/Specifications/Common/ParameterReplacer.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace ProductSpecification.Specifications.Common; 4 | 5 | internal class ParameterReplacer : ExpressionVisitor 6 | { 7 | private readonly ParameterExpression _parameter; 8 | 9 | internal ParameterReplacer(ParameterExpression parameter) 10 | { 11 | _parameter = parameter; 12 | } 13 | 14 | protected override Expression VisitParameter(ParameterExpression node) => 15 | base.VisitParameter(_parameter); 16 | } 17 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/Specifications/ProductCategorySpecification.cs: -------------------------------------------------------------------------------- 1 | using ProductSpecification.Domain; 2 | using ProductSpecification.Specifications.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace ProductSpecification.Specifications; 6 | 7 | public class ProductCategorySpecification : Specification 8 | { 9 | private readonly ProductCategory _category; 10 | 11 | public ProductCategorySpecification(ProductCategory category) 12 | { 13 | _category = category; 14 | } 15 | 16 | public override Expression> ToExpression() => 17 | product => product.Category == _category; 18 | } 19 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/Specifications/RecentlyLaunchedProductSpecification.cs: -------------------------------------------------------------------------------- 1 | using ProductSpecification.Domain; 2 | using ProductSpecification.Specifications.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace ProductSpecification.Specifications; 6 | 7 | public class RecentlyLaunchedProductSpecification : Specification 8 | { 9 | public override Expression> ToExpression() => 10 | // Products are considered as recently launched if they are launched in the last 7 days 11 | product => DateTime.Today.AddDays(-7) <= product.LaunchDate; 12 | } 13 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/Specification/ProductSpecification/Specifications/TopRatedProductSpecification.cs: -------------------------------------------------------------------------------- 1 | using ProductSpecification.Domain; 2 | using ProductSpecification.Specifications.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace ProductSpecification.Specifications; 6 | 7 | public class TopRatedProductSpecification : Specification 8 | { 9 | private const double TopRatingThreshold = 4.5; 10 | 11 | public override Expression> ToExpression() => 12 | product => product.Rating >= TopRatingThreshold; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Assets/pattern-structure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Assets/pattern-structure-1.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Assets/pattern-structure-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Assets/pattern-structure-2.png -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Domain/Customer.cs: -------------------------------------------------------------------------------- 1 | namespace UnitOfWorkLibrary.Domain; 2 | 3 | public class Customer : Entity 4 | { 5 | public string FirstName { get; set; } = string.Empty; 6 | public string LastName { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Domain/Entity.cs: -------------------------------------------------------------------------------- 1 | namespace UnitOfWorkLibrary.Domain; 2 | 3 | public abstract class Entity 4 | { 5 | public int Id { get; init; } 6 | } 7 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Domain/Order.cs: -------------------------------------------------------------------------------- 1 | namespace UnitOfWorkLibrary.Domain; 2 | 3 | public class Order : Entity 4 | { 5 | public string Description { get; set; } = string.Empty; 6 | public string DeliveryAddress { get; set; } = string.Empty; 7 | public decimal Price { get; set; } 8 | } 9 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example1/Controllers/CustomerController1.cs: -------------------------------------------------------------------------------- 1 | using UnitOfWorkLibrary.Domain; 2 | using UnitOfWorkLibrary.Example1.Infrastructure; 3 | 4 | namespace UnitOfWorkLibrary.Example1.Controllers; 5 | 6 | public class CustomerController1 7 | { 8 | private readonly IUnitOfWork1 _unitOfWork; 9 | 10 | public CustomerController1(IUnitOfWork1 unitOfWork) 11 | { 12 | _unitOfWork = unitOfWork; 13 | } 14 | 15 | public IEnumerable GetAll() => _unitOfWork.CustomerRepository.GetAll(); 16 | } 17 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example1/Infrastructure/IUnitOfWork1.cs: -------------------------------------------------------------------------------- 1 | using UnitOfWorkLibrary.Domain; 2 | using UnitOfWorkLibrary.Example1.Infrastructure.Repositories.Contracts; 3 | 4 | namespace UnitOfWorkLibrary.Example1.Infrastructure; 5 | 6 | public interface IUnitOfWork1 7 | { 8 | IRepository1 CustomerRepository { get; } 9 | IRepository1 OrderRepository { get; } 10 | 11 | void SaveChanges(); 12 | } 13 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example1/Infrastructure/OrderManagementContext1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using UnitOfWorkLibrary.Domain; 3 | 4 | namespace UnitOfWorkLibrary.Example1.Infrastructure; 5 | 6 | public class OrderManagementContext1 : DbContext 7 | { 8 | public DbSet Customers => Set(); 9 | public DbSet Orders => Set(); 10 | 11 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => 12 | optionsBuilder.UseSqlite("Data Source=storage1.db"); 13 | } 14 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example1/Infrastructure/Repositories/Contracts/IRepository1.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | using UnitOfWorkLibrary.Domain; 3 | 4 | namespace UnitOfWorkLibrary.Example1.Infrastructure.Repositories.Contracts; 5 | 6 | public interface IRepository1 7 | where T : Entity 8 | { 9 | T Add(T entity); 10 | 11 | IEnumerable GetAll(); 12 | 13 | IEnumerable Get(Expression> predicate); 14 | 15 | T GetById(int id); 16 | 17 | void Delete(T entity); 18 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example2/Controllers/CustomerController2.cs: -------------------------------------------------------------------------------- 1 | using UnitOfWorkLibrary.Domain; 2 | using UnitOfWorkLibrary.Example2.Infrastructure.Repositories.Contracts; 3 | 4 | namespace UnitOfWorkLibrary.Example2.Controllers; 5 | 6 | public class CustomerController2 7 | { 8 | private readonly ICustomerRepository _customerRepository; 9 | 10 | public CustomerController2(ICustomerRepository customerRepository) 11 | { 12 | _customerRepository = customerRepository; 13 | } 14 | 15 | public IEnumerable GetAll() => _customerRepository.GetAll(); 16 | } 17 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example2/Infrastructure/IUnitOfWork2.cs: -------------------------------------------------------------------------------- 1 | namespace UnitOfWorkLibrary.Example2.Infrastructure; 2 | 3 | public interface IUnitOfWork2 : IDisposable 4 | { 5 | Task SaveChangesAsync(CancellationToken cancellationToken = default); 6 | Task SaveChangesAndDispatchDomainEventsAsync(CancellationToken cancellationToken = default); 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example2/Infrastructure/Repositories/Contracts/ICustomerRepository.cs: -------------------------------------------------------------------------------- 1 | using UnitOfWorkLibrary.Domain; 2 | 3 | namespace UnitOfWorkLibrary.Example2.Infrastructure.Repositories.Contracts; 4 | 5 | public interface ICustomerRepository : IRepository2 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example2/Infrastructure/Repositories/Contracts/IOrderRepository.cs: -------------------------------------------------------------------------------- 1 | using UnitOfWorkLibrary.Domain; 2 | 3 | namespace UnitOfWorkLibrary.Example2.Infrastructure.Repositories.Contracts; 4 | 5 | public interface IOrderRepository : IRepository2 6 | { 7 | Order? GetTheMostExpensive(); 8 | } 9 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example2/Infrastructure/Repositories/Contracts/IRepository2.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | using UnitOfWorkLibrary.Domain; 3 | 4 | namespace UnitOfWorkLibrary.Example2.Infrastructure.Repositories.Contracts; 5 | 6 | public interface IRepository2 7 | where T : Entity 8 | { 9 | IUnitOfWork2 UnitOfWork { get; } 10 | T Add(T entity); 11 | IEnumerable GetAll(); 12 | IEnumerable Get(Expression> predicate); 13 | T GetById(int id); 14 | void Delete(T entity); 15 | } 16 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example2/Infrastructure/Repositories/CustomerRepository.cs: -------------------------------------------------------------------------------- 1 | using UnitOfWorkLibrary.Domain; 2 | using UnitOfWorkLibrary.Example2.Infrastructure.Repositories.Contracts; 3 | 4 | namespace UnitOfWorkLibrary.Example2.Infrastructure.Repositories; 5 | 6 | public class CustomerRepository : Repository2, ICustomerRepository 7 | { 8 | public CustomerRepository(OrderManagementContext2 context) 9 | : base(context) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Example2/Infrastructure/Repositories/OrderRepository.cs: -------------------------------------------------------------------------------- 1 | using UnitOfWorkLibrary.Domain; 2 | using UnitOfWorkLibrary.Example2.Infrastructure.Repositories.Contracts; 3 | 4 | namespace UnitOfWorkLibrary.Example2.Infrastructure.Repositories; 5 | 6 | public class OrderRepository : Repository2, IOrderRepository 7 | { 8 | public OrderRepository(OrderManagementContext2 context) 9 | : base(context) 10 | { 11 | } 12 | 13 | public Order? GetTheMostExpensive() => 14 | _context.Orders 15 | .OrderByDescending(order => order.Price) 16 | .FirstOrDefault(); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using UnitOfWorkLibrary.Example1; 3 | using UnitOfWorkLibrary.Example2; 4 | 5 | namespace UnitOfWorkLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Unit of Work - Data Access Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | Example1Executor.Execute(); 14 | Example2Executor.ExecuteAsync().Wait(); 15 | // The third example can be found within the code for the Repository pattern. 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdditionalPatterns/UnitOfWork/UnitOfWorkLibrary/UnitOfWorkLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/ChainOfResponsibilityLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using ChainOfResponsibilityLibrary.LoggingExample; 3 | using ChainOfResponsibilityLibrary.PokerExample; 4 | using ChainOfResponsibilityLibrary.PurchaseApprovalExample; 5 | 6 | namespace ChainOfResponsibilityLibrary; 7 | 8 | public class Executor : PatternExecutor 9 | { 10 | public override string Name => "Chain Of Responsibility - Behavioral Pattern"; 11 | 12 | public override void Execute() 13 | { 14 | LoggingExecutor.Execute(); 15 | PokerExecutor.Execute(); 16 | PurchaseApprovalExecutor.Execute(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/LoggingExample/Common/LogLevel.cs: -------------------------------------------------------------------------------- 1 | namespace ChainOfResponsibilityLibrary.LoggingExample.Common; 2 | 3 | public enum LogLevel 4 | { 5 | Info, 6 | Debug, 7 | Error, 8 | } -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/LoggingExample/Loggers/ConsoleLogger.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.LoggingExample.Common; 2 | 3 | namespace ChainOfResponsibilityLibrary.LoggingExample.Loggers; 4 | 5 | public class ConsoleLogger : Logger 6 | { 7 | public ConsoleLogger() 8 | : base(LogLevel.Info) 9 | { 10 | } 11 | 12 | protected override void Write(string message) => Console.WriteLine($"Console:: {message}"); 13 | } 14 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/LoggingExample/Loggers/FileLogger.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.LoggingExample.Common; 2 | 3 | namespace ChainOfResponsibilityLibrary.LoggingExample.Loggers; 4 | 5 | public class FileLogger : Logger 6 | { 7 | public FileLogger() 8 | : base(LogLevel.Debug) 9 | { 10 | } 11 | 12 | protected override void Write(string message) => Console.WriteLine($"File:: {message}"); 13 | } 14 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/LoggingExample/Loggers/PriorityLogger.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.LoggingExample.Common; 2 | 3 | namespace ChainOfResponsibilityLibrary.LoggingExample.Loggers; 4 | 5 | public class PriorityLogger : Logger 6 | { 7 | public PriorityLogger() 8 | : base(LogLevel.Error) 9 | { 10 | } 11 | 12 | protected override void Write(string message) => Console.WriteLine($"Priority monitoring logger:: {message}"); 13 | } 14 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Categorizers/FlushCategorizer.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PokerExample.Categorizers.Common; 2 | using ChainOfResponsibilityLibrary.PokerExample.Models; 3 | using ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 4 | 5 | namespace ChainOfResponsibilityLibrary.PokerExample.Categorizers; 6 | 7 | public class FlushCategorizer : HandCategorizer 8 | { 9 | public override HandRanking Categorize(Hand hand) 10 | { 11 | if (HasFlush(hand)) 12 | { 13 | return HandRanking.Flush; 14 | } 15 | 16 | return CheckNextCategorizer(hand); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Categorizers/FourOfAKindCategorizer.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PokerExample.Categorizers.Common; 2 | using ChainOfResponsibilityLibrary.PokerExample.Models; 3 | using ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 4 | 5 | namespace ChainOfResponsibilityLibrary.PokerExample.Categorizers; 6 | 7 | public class FourOfAKindCategorizer : HandCategorizer 8 | { 9 | public override HandRanking Categorize(Hand hand) 10 | { 11 | if (HasNOfKind(4, hand)) 12 | { 13 | return HandRanking.FourOfAKind; 14 | } 15 | 16 | return CheckNextCategorizer(hand); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Categorizers/HighCardCategorizer.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PokerExample.Categorizers.Common; 2 | using ChainOfResponsibilityLibrary.PokerExample.Models; 3 | using ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 4 | 5 | namespace ChainOfResponsibilityLibrary.PokerExample.Categorizers; 6 | 7 | public class HighCardCategorizer : HandCategorizer 8 | { 9 | public override HandRanking Categorize(Hand hand) => HandRanking.HighCard; 10 | } 11 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Categorizers/PairCategorizer.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PokerExample.Categorizers.Common; 2 | using ChainOfResponsibilityLibrary.PokerExample.Models; 3 | using ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 4 | 5 | namespace ChainOfResponsibilityLibrary.PokerExample.Categorizers; 6 | 7 | public class PairCategorizer : HandCategorizer 8 | { 9 | public override HandRanking Categorize(Hand hand) 10 | { 11 | if (HasNOfKind(2, hand)) 12 | { 13 | return HandRanking.Pair; 14 | } 15 | 16 | return CheckNextCategorizer(hand); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Categorizers/StraightCategorizer.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PokerExample.Categorizers.Common; 2 | using ChainOfResponsibilityLibrary.PokerExample.Models; 3 | using ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 4 | 5 | namespace ChainOfResponsibilityLibrary.PokerExample.Categorizers; 6 | 7 | public class StraightCategorizer : HandCategorizer 8 | { 9 | public override HandRanking Categorize(Hand hand) 10 | { 11 | if (HasStraight(hand)) 12 | { 13 | return HandRanking.Straight; 14 | } 15 | 16 | return CheckNextCategorizer(hand); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Categorizers/StraightFlushCategorizer.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PokerExample.Categorizers.Common; 2 | using ChainOfResponsibilityLibrary.PokerExample.Models; 3 | using ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 4 | 5 | namespace ChainOfResponsibilityLibrary.PokerExample.Categorizers; 6 | 7 | public class StraightFlushCategorizer : HandCategorizer 8 | { 9 | public override HandRanking Categorize(Hand hand) 10 | { 11 | if (HasFlush(hand) && HasStraight(hand)) 12 | { 13 | return HandRanking.StraightFlush; 14 | } 15 | 16 | return CheckNextCategorizer(hand); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Categorizers/ThreeOfAKindCategorizer.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PokerExample.Categorizers.Common; 2 | using ChainOfResponsibilityLibrary.PokerExample.Models; 3 | using ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 4 | 5 | namespace ChainOfResponsibilityLibrary.PokerExample.Categorizers; 6 | 7 | public class ThreeOfAKindCategorizer : HandCategorizer 8 | { 9 | public override HandRanking Categorize(Hand hand) 10 | { 11 | if (HasNOfKind(3, hand)) 12 | { 13 | return HandRanking.ThreeOfAKind; 14 | } 15 | 16 | return CheckNextCategorizer(hand); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Models/Enums/HandRanking.cs: -------------------------------------------------------------------------------- 1 | namespace ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 2 | 3 | public enum HandRanking 4 | { 5 | Unknown, 6 | HighCard, 7 | Pair, 8 | TwoPair, 9 | ThreeOfAKind, 10 | Straight, 11 | Flush, 12 | FullHouse, 13 | FourOfAKind, 14 | StraightFlush, 15 | RoyalFlush, 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Models/Enums/Suit.cs: -------------------------------------------------------------------------------- 1 | namespace ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 2 | 3 | public enum Suit 4 | { 5 | Diamond, 6 | Club, 7 | Heart, 8 | Spade, 9 | } 10 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PokerExample/Models/Enums/Value.cs: -------------------------------------------------------------------------------- 1 | namespace ChainOfResponsibilityLibrary.PokerExample.Models.Enums; 2 | 3 | public enum Value 4 | { 5 | Two, 6 | Three, 7 | Four, 8 | Five, 9 | Six, 10 | Seven, 11 | Eight, 12 | Nine, 13 | Ten, 14 | Jack, 15 | Queen, 16 | King, 17 | Ace, 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PurchaseApprovalExample/Common/Approver.cs: -------------------------------------------------------------------------------- 1 | namespace ChainOfResponsibilityLibrary.PurchaseApprovalExample.Common; 2 | 3 | public abstract class Approver 4 | { 5 | protected Approver? Next { get; private set; } 6 | 7 | public Approver RegisterNext(Approver next) 8 | { 9 | Next = next; 10 | return Next; 11 | } 12 | 13 | public abstract void Approve(Purchase purchase); 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PurchaseApprovalExample/Common/Purchase.cs: -------------------------------------------------------------------------------- 1 | namespace ChainOfResponsibilityLibrary.PurchaseApprovalExample.Common; 2 | 3 | public class Purchase 4 | { 5 | public int Number { get; set; } 6 | public decimal Cost { get; set; } 7 | public string Purpose { get; set; } = string.Empty; 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PurchaseApprovalExample/Handlers/Director.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PurchaseApprovalExample.Common; 2 | 3 | namespace ChainOfResponsibilityLibrary.PurchaseApprovalExample.Handlers; 4 | 5 | public class Director : Approver 6 | { 7 | public override void Approve(Purchase purchase) 8 | { 9 | if (purchase.Cost < 1000) 10 | { 11 | Console.WriteLine($"The director approved the purchase #{purchase.Number} which cost {purchase.Cost:C}"); 12 | return; 13 | } 14 | 15 | Next?.Approve(purchase); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PurchaseApprovalExample/Handlers/Manager.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PurchaseApprovalExample.Common; 2 | 3 | namespace ChainOfResponsibilityLibrary.PurchaseApprovalExample.Handlers; 4 | 5 | public class Manager : Approver 6 | { 7 | public override void Approve(Purchase purchase) 8 | { 9 | if (purchase.Cost < 500) 10 | { 11 | Console.WriteLine($"The manager approved the purchase #{purchase.Number} which cost {purchase.Cost:C}"); 12 | return; 13 | } 14 | 15 | Next?.Approve(purchase); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PurchaseApprovalExample/Handlers/President.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PurchaseApprovalExample.Common; 2 | 3 | namespace ChainOfResponsibilityLibrary.PurchaseApprovalExample.Handlers; 4 | 5 | public class President : Approver 6 | { 7 | public override void Approve(Purchase purchase) 8 | { 9 | if (purchase.Cost < 5000) 10 | { 11 | Console.WriteLine($"The president approved the purchase #{purchase.Number} which cost {purchase.Cost:C}"); 12 | return; 13 | } 14 | 15 | Next?.Approve(purchase); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/ChainOfResponsibility/ChainOfResponsibilityLibrary/PurchaseApprovalExample/Handlers/VicePresident.cs: -------------------------------------------------------------------------------- 1 | using ChainOfResponsibilityLibrary.PurchaseApprovalExample.Common; 2 | 3 | namespace ChainOfResponsibilityLibrary.PurchaseApprovalExample.Handlers; 4 | 5 | public class VicePresident : Approver 6 | { 7 | public override void Approve(Purchase purchase) 8 | { 9 | if (purchase.Cost < 2000) 10 | { 11 | Console.WriteLine($"The vice-president approved the purchase #{purchase.Number} which cost {purchase.Cost:C}"); 12 | return; 13 | } 14 | 15 | Next?.Approve(purchase); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Command/CommandLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/CommandLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/EmailExample/Commands/Common/ICommand.cs: -------------------------------------------------------------------------------- 1 | namespace CommandLibrary.EmailExample.Commands.Common; 2 | 3 | public interface ICommand 4 | { 5 | void Execute(); 6 | } 7 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/EmailExample/Commands/DeleteCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandLibrary.EmailExample.Commands.Common; 2 | 3 | namespace CommandLibrary.EmailExample.Commands; 4 | 5 | public class DeleteCommand : ICommand 6 | { 7 | private readonly Email _email; 8 | 9 | public DeleteCommand(Email email) 10 | { 11 | _email = email; 12 | } 13 | 14 | public void Execute() => _email.Delete(); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/EmailExample/Commands/ForwardCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandLibrary.EmailExample.Commands.Common; 2 | 3 | namespace CommandLibrary.EmailExample.Commands; 4 | 5 | public class ForwardCommand : ICommand 6 | { 7 | private readonly Email _email; 8 | 9 | public ForwardCommand(Email email) 10 | { 11 | _email = email; 12 | } 13 | 14 | public void Execute() => _email.Forward(); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/EmailExample/Commands/ReadCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandLibrary.EmailExample.Commands.Common; 2 | 3 | namespace CommandLibrary.EmailExample.Commands; 4 | 5 | public class ReadCommand : ICommand 6 | { 7 | private readonly Email _email; 8 | 9 | public ReadCommand(Email email) 10 | { 11 | _email = email; 12 | } 13 | 14 | public void Execute() => _email.Read(); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/EmailExample/Email.cs: -------------------------------------------------------------------------------- 1 | namespace CommandLibrary.EmailExample; 2 | 3 | public class Email 4 | { 5 | public void Delete() => Console.WriteLine("Email has been deleted."); 6 | 7 | public void Forward() => Console.WriteLine("Email has been forwarded."); 8 | 9 | public void Read() => Console.WriteLine("Email has been read."); 10 | } 11 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using CommandLibrary.EmailExample; 3 | using CommandLibrary.ShoppingCartExample; 4 | using CommandLibrary.StockExample; 5 | 6 | namespace CommandLibrary; 7 | 8 | public class Executor : PatternExecutor 9 | { 10 | public override string Name => "Command - Behavioral Pattern"; 11 | 12 | public override void Execute() 13 | { 14 | EmailExecutor.Execute(); 15 | ShoppingCartExecutor.Execute(); 16 | StockExecutor.Execute(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/ShoppingCartExample/Commands/Common/ICommand.cs: -------------------------------------------------------------------------------- 1 | namespace CommandLibrary.ShoppingCartExample.Commands.Common; 2 | 3 | public interface ICommand 4 | { 5 | bool CanExecute(); 6 | void Execute(); 7 | void Undo(); 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/ShoppingCartExample/Models/ChangeCartQuantityOperation.cs: -------------------------------------------------------------------------------- 1 | namespace CommandLibrary.ShoppingCartExample.Models; 2 | 3 | public enum ChangeCartQuantityOperation 4 | { 5 | Increase, 6 | Decrease, 7 | } 8 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/ShoppingCartExample/Models/Product.cs: -------------------------------------------------------------------------------- 1 | namespace CommandLibrary.ShoppingCartExample.Models; 2 | 3 | public class Product 4 | { 5 | public const int ProductPurchaseLimit = 10; 6 | 7 | public Product(string productId, string name, decimal price) 8 | { 9 | ProductId = productId; 10 | Name = name; 11 | Price = price; 12 | } 13 | 14 | public string ProductId { get; set; } 15 | public string Name { get; set; } 16 | public decimal Price { get; set; } 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/ShoppingCartExample/Repositories/Common/IProductRepository.cs: -------------------------------------------------------------------------------- 1 | using CommandLibrary.ShoppingCartExample.Models; 2 | 3 | namespace CommandLibrary.ShoppingCartExample.Repositories.Common; 4 | 5 | // Please be aware that some of the methods defined here shouldn't really be part of the repository. 6 | public interface IProductRepository 7 | { 8 | IEnumerable GetAll(); 9 | Product? GetById(string productId); 10 | int GetStock(string productId); 11 | void IncreaseStock(string productId, int amount); 12 | void DecreaseStock(string productId, int amount); 13 | } 14 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/ShoppingCartExample/Repositories/Common/IShoppingCartRepository.cs: -------------------------------------------------------------------------------- 1 | using CommandLibrary.ShoppingCartExample.Models; 2 | 3 | namespace CommandLibrary.ShoppingCartExample.Repositories.Common; 4 | 5 | // Please be aware that some of the methods defined here shouldn't really be part of the repository. 6 | public interface IShoppingCartRepository 7 | { 8 | IEnumerable<(Product Product, int Quantity)> GetAll(); 9 | (Product Product, int Quantity) GetById(string productId); 10 | bool IsEmpty(); 11 | void Add(Product product); 12 | void Remove(string productId); 13 | void IncreaseQuantity(string productId); 14 | void DecreaseQuantity(string productId); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/StockExample/Broker.cs: -------------------------------------------------------------------------------- 1 | using CommandLibrary.StockExample.Commands.Common; 2 | 3 | namespace CommandLibrary.StockExample; 4 | 5 | public class Broker 6 | { 7 | private readonly List _orders = new(); 8 | 9 | public void TakeOrder(IOrderCommand order) => _orders.Add(order); 10 | 11 | public void ProcessOrders() 12 | { 13 | foreach (var order in _orders) 14 | { 15 | order.Execute(); 16 | } 17 | 18 | _orders.Clear(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/StockExample/Commands/BuyStockCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandLibrary.StockExample.Commands.Common; 2 | 3 | namespace CommandLibrary.StockExample.Commands; 4 | 5 | public class BuyStockCommand : IOrderCommand 6 | { 7 | private readonly Stock _stock; 8 | 9 | public BuyStockCommand(Stock stock) 10 | { 11 | _stock = stock; 12 | } 13 | 14 | public void Execute() => _stock.Buy(); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/StockExample/Commands/Common/IOrderCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CommandLibrary.StockExample.Commands.Common; 2 | 3 | public interface IOrderCommand 4 | { 5 | void Execute(); 6 | } 7 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/StockExample/Commands/SellStockCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandLibrary.StockExample.Commands.Common; 2 | 3 | namespace CommandLibrary.StockExample.Commands; 4 | 5 | public class SellStockCommand : IOrderCommand 6 | { 7 | private readonly Stock _stock; 8 | 9 | public SellStockCommand(Stock stock) 10 | { 11 | _stock = stock; 12 | } 13 | 14 | public void Execute() => _stock.Sell(); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/StockExample/Stock.cs: -------------------------------------------------------------------------------- 1 | namespace CommandLibrary.StockExample; 2 | 3 | public class Stock 4 | { 5 | private readonly string _name; 6 | private readonly int _quantity; 7 | 8 | public Stock(string name, int quantity) 9 | { 10 | _name = name; 11 | _quantity = quantity; 12 | } 13 | 14 | public void Buy() => Console.WriteLine($"Stock [ Name: {_name}, Quantity: {_quantity} ] is bought."); 15 | 16 | public void Sell() => Console.WriteLine($"Stock [ Name: {_name}, Quantity: {_quantity} ] is sold."); 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Command/CommandLibrary/StockExample/StockExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using CommandLibrary.StockExample.Commands; 3 | 4 | namespace CommandLibrary.StockExample; 5 | 6 | public static class StockExecutor 7 | { 8 | public static void Execute() 9 | { 10 | ConsoleExtension.WriteSeparator("Stock example"); 11 | 12 | var stock = new Stock("Tesla", 5); 13 | 14 | var buyStock = new BuyStockCommand(stock); 15 | var sellStock = new SellStockCommand(stock); 16 | 17 | var broker = new Broker(); 18 | broker.TakeOrder(buyStock); 19 | broker.TakeOrder(sellStock); 20 | 21 | broker.ProcessOrders(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Iterator/IteratorLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Iterator/IteratorLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Iterator/IteratorLibrary/ConceptualExample/Collections/Common/IterableCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | 3 | namespace IteratorLibrary.ConceptualExample.Collections.Common; 4 | 5 | public abstract class IterableCollection : IEnumerable 6 | { 7 | public abstract IEnumerator GetEnumerator(); 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Iterator/IteratorLibrary/ConceptualExample/Iterators/Common/Iterator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | 3 | namespace IteratorLibrary.ConceptualExample.Iterators.Common; 4 | 5 | public abstract class Iterator : IEnumerator 6 | { 7 | object IEnumerator.Current => Current(); 8 | 9 | public abstract object Current(); 10 | public abstract bool MoveNext(); 11 | public abstract void Reset(); 12 | } 13 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Iterator/IteratorLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using IteratorLibrary.ConceptualExample; 3 | using IteratorLibrary.MusicFestivalsExample; 4 | 5 | namespace IteratorLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Iterator - Behavioral Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | ConceptualExecutor.Execute(); 14 | MusicFestivalsExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Iterator/IteratorLibrary/IteratorLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Iterator/IteratorLibrary/MusicFestivalsExample/Collections/Common/IIterableCollection.cs: -------------------------------------------------------------------------------- 1 | using IteratorLibrary.MusicFestivalsExample.Iterators.Common; 2 | 3 | namespace IteratorLibrary.MusicFestivalsExample.Collections.Common; 4 | 5 | public interface IIterableCollection 6 | { 7 | IIterator CreateIterator(); 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Iterator/IteratorLibrary/MusicFestivalsExample/Iterators/Common/IIterator.cs: -------------------------------------------------------------------------------- 1 | namespace IteratorLibrary.MusicFestivalsExample.Iterators.Common; 2 | 3 | public interface IIterator 4 | { 5 | int Step { get; set; } 6 | 7 | MusicFestival First(); 8 | MusicFestival Current(); 9 | bool MoveNext(); 10 | void Reset(); 11 | } 12 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Iterator/IteratorLibrary/MusicFestivalsExample/MusicFestival.cs: -------------------------------------------------------------------------------- 1 | namespace IteratorLibrary.MusicFestivalsExample; 2 | 3 | public class MusicFestival 4 | { 5 | public MusicFestival(string name, string country) 6 | { 7 | Name = name; 8 | Country = country; 9 | } 10 | 11 | public string Name { get; set; } 12 | public string Country { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/AirTrafficControlExample/Components/AirbusA320.cs: -------------------------------------------------------------------------------- 1 | using MediatorLibrary.AirTrafficControlExample.Components.Common; 2 | using MediatorLibrary.AirTrafficControlExample.Mediators.Common; 3 | 4 | namespace MediatorLibrary.AirTrafficControlExample.Components; 5 | 6 | public class AirbusA320 : Aircraft 7 | { 8 | public AirbusA320(string callSign, int currentAltitude, IAirTrafficControl atc) 9 | : base(callSign, currentAltitude, atc) 10 | { 11 | } 12 | 13 | public override int SeatingCapacity => 180; 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/AirTrafficControlExample/Components/Boeing737.cs: -------------------------------------------------------------------------------- 1 | using MediatorLibrary.AirTrafficControlExample.Components.Common; 2 | using MediatorLibrary.AirTrafficControlExample.Mediators.Common; 3 | 4 | namespace MediatorLibrary.AirTrafficControlExample.Components; 5 | 6 | public class Boeing737 : Aircraft 7 | { 8 | public Boeing737(string callSign, int currentAltitude, IAirTrafficControl atc) 9 | : base(callSign, currentAltitude, atc) 10 | { 11 | } 12 | 13 | public override int SeatingCapacity => 143; 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/AirTrafficControlExample/Components/Boeing777.cs: -------------------------------------------------------------------------------- 1 | using MediatorLibrary.AirTrafficControlExample.Components.Common; 2 | using MediatorLibrary.AirTrafficControlExample.Mediators.Common; 3 | 4 | namespace MediatorLibrary.AirTrafficControlExample.Components; 5 | 6 | public class Boeing777 : Aircraft 7 | { 8 | public Boeing777(string callSign, int currentAltitude, IAirTrafficControl atc) 9 | : base(callSign, currentAltitude, atc) 10 | { 11 | } 12 | 13 | public override int SeatingCapacity => 368; 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/AirTrafficControlExample/Mediators/Common/IAirTrafficControl.cs: -------------------------------------------------------------------------------- 1 | using MediatorLibrary.AirTrafficControlExample.Components.Common; 2 | 3 | namespace MediatorLibrary.AirTrafficControlExample.Mediators.Common; 4 | 5 | public interface IAirTrafficControl 6 | { 7 | void ReceiveAircraftLocation(Aircraft reportingAircraft); 8 | void RegisterAircraftUnderGuidance(Aircraft aircraft); 9 | } 10 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Mediator/MediatorLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using MediatorLibrary.AirTrafficControlExample; 3 | using MediatorLibrary.GroupChatExample; 4 | 5 | namespace MediatorLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Mediator - Behavioral Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | AirTrafficControlExecutor.Execute(); 14 | GroupChatExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/GroupChatExample/Components/Common/User.cs: -------------------------------------------------------------------------------- 1 | using MediatorLibrary.GroupChatExample.Mediators.Common; 2 | 3 | namespace MediatorLibrary.GroupChatExample.Components.Common; 4 | 5 | public abstract class User 6 | { 7 | protected IGroupChatMediator? _mediator; 8 | protected string _name; 9 | 10 | protected User(string name) 11 | { 12 | _name = name; 13 | } 14 | 15 | public string Name => _name; 16 | 17 | public void SetMediator(IGroupChatMediator mediator) => _mediator = mediator; 18 | 19 | public abstract void Send(string message); 20 | public abstract void Receive(string message); 21 | } 22 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/GroupChatExample/Mediators/Common/IGroupChatMediator.cs: -------------------------------------------------------------------------------- 1 | using MediatorLibrary.GroupChatExample.Components.Common; 2 | 3 | namespace MediatorLibrary.GroupChatExample.Mediators.Common; 4 | 5 | public interface IGroupChatMediator 6 | { 7 | void AddParticipant(User user); 8 | void SendMessage(string message, User sender); 9 | } 10 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Mediator/MediatorLibrary/MediatorLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Memento/MementoLibrary/Assets/pattern-structure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Memento/MementoLibrary/Assets/pattern-structure-1.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Memento/MementoLibrary/Assets/pattern-structure-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Memento/MementoLibrary/Assets/pattern-structure-2.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Memento/MementoLibrary/Assets/pattern-structure-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Memento/MementoLibrary/Assets/pattern-structure-3.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Memento/MementoLibrary/ConceptualExample/IMemento.cs: -------------------------------------------------------------------------------- 1 | namespace MementoLibrary.ConceptualExample; 2 | 3 | /// 4 | /// The Memento interface provides a way to retrieve the 5 | /// memento's metadata, such as creation date or name. 6 | /// However, it doesn't expose the Originator's state. 7 | /// 8 | public interface IMemento 9 | { 10 | DateTime GetCreationDate(); 11 | string GetName(); 12 | } 13 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Memento/MementoLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using MementoLibrary.ConceptualExample; 3 | using MementoLibrary.FoodSupplierExample; 4 | 5 | namespace MementoLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Memento - Behavioral Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | ConceptualExecutor.Execute(); 14 | FoodSupplierExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Memento/MementoLibrary/FoodSupplierExample/FoodSupplierMemento.cs: -------------------------------------------------------------------------------- 1 | namespace MementoLibrary.FoodSupplierExample; 2 | 3 | public class FoodSupplierMemento : IMemento 4 | { 5 | public FoodSupplierMemento(string name, string phoneNumber, string address) 6 | { 7 | Name = name; 8 | PhoneNumber = phoneNumber; 9 | Address = address; 10 | } 11 | 12 | public string Name { get; set; } 13 | public string PhoneNumber { get; set; } 14 | public string Address { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Memento/MementoLibrary/FoodSupplierExample/IMemento.cs: -------------------------------------------------------------------------------- 1 | namespace MementoLibrary.FoodSupplierExample; 2 | 3 | public interface IMemento 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Memento/MementoLibrary/MementoLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Observer/ObserverLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using ObserverLibrary.NewspaperExample; 3 | using ObserverLibrary.StockExample; 4 | 5 | namespace ObserverLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Observer - Behavioral Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | NewspaperExecutor.Execute(); 14 | StockExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/NewspaperExample/Publishers/DailyMail.cs: -------------------------------------------------------------------------------- 1 | using ObserverLibrary.NewspaperExample.Publishers.Common; 2 | 3 | namespace ObserverLibrary.NewspaperExample.Publishers; 4 | 5 | public class DailyMail : Newspaper 6 | { 7 | public DailyMail() 8 | : base("Daily Mail", 5) 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/NewspaperExample/Subscribers/Common/IUser.cs: -------------------------------------------------------------------------------- 1 | using ObserverLibrary.NewspaperExample.Publishers.Common; 2 | 3 | namespace ObserverLibrary.NewspaperExample.Subscribers.Common; 4 | 5 | public interface IUser 6 | { 7 | public string Username { get; set; } 8 | public string Name { get; set; } 9 | 10 | void ReportSubscriptionPriceChange(Newspaper newspaper); 11 | } 12 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/ObserverLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/StockExample/Examples/EventAndDelegate/Publishers/StockTicker.cs: -------------------------------------------------------------------------------- 1 | namespace ObserverLibrary.StockExample.Examples.EventAndDelegate.Publishers; 2 | 3 | public class StockTicker 4 | { 5 | private Stock _lastChangedStock = Stock.Default(); 6 | public event EventHandler? StockChange; 7 | 8 | public void ProcessNewStockChange(Stock stock) 9 | { 10 | _lastChangedStock = stock; 11 | OnStockChange(new StockChangeEventArgs(_lastChangedStock)); 12 | } 13 | 14 | private void OnStockChange(StockChangeEventArgs e) => 15 | StockChange?.Invoke(this, e); 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/StockExample/Examples/EventAndDelegate/StockChangeEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace ObserverLibrary.StockExample.Examples.EventAndDelegate; 2 | 3 | public class StockChangeEventArgs : EventArgs 4 | { 5 | public StockChangeEventArgs(Stock stock) 6 | { 7 | Stock = stock; 8 | } 9 | 10 | public Stock Stock { get; set; } 11 | } 12 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/StockExample/Examples/IObserver/Subscribers/GoogleSubscriber.cs: -------------------------------------------------------------------------------- 1 | namespace ObserverLibrary.StockExample.Examples.IObserver.Subscribers; 2 | 3 | public class GoogleSubscriber : IObserver 4 | { 5 | public void OnCompleted() => 6 | Console.WriteLine("Preparing daily report..."); 7 | 8 | public void OnError(Exception error) => 9 | Console.WriteLine("Error occurred in the stock ticker."); 10 | 11 | public void OnNext(Stock stock) 12 | { 13 | if (stock.Symbol == "GOOG") 14 | { 15 | Console.WriteLine($"Google's stock price has changed. The new price is: {stock.Price}"); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/StockExample/Examples/Stock.cs: -------------------------------------------------------------------------------- 1 | namespace ObserverLibrary.StockExample.Examples; 2 | 3 | public class Stock 4 | { 5 | public string Symbol { get; set; } = string.Empty; 6 | public decimal Price { get; set; } 7 | 8 | public static Stock Default() => 9 | new() { Symbol = "Default", Price = 0 }; 10 | } 11 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/StockExample/Examples/Traditional/Publishers/StockTicker.cs: -------------------------------------------------------------------------------- 1 | using ObserverLibrary.StockExample.Examples.Traditional.Publishers.Common; 2 | 3 | namespace ObserverLibrary.StockExample.Examples.Traditional.Publishers; 4 | 5 | public class StockTicker : Publisher 6 | { 7 | public Stock LastChangedStock { get; private set; } = Stock.Default(); 8 | 9 | public void ProcessNewStockChange(Stock stock) 10 | { 11 | LastChangedStock = stock; 12 | NotifySubscribers(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/StockExample/Examples/Traditional/Subscribers/Common/Subscriber.cs: -------------------------------------------------------------------------------- 1 | namespace ObserverLibrary.StockExample.Examples.Traditional.Subscribers.Common; 2 | 3 | public abstract class Subscriber 4 | { 5 | public abstract void Update(); 6 | } 7 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Observer/ObserverLibrary/StockExample/StockExecutor.cs: -------------------------------------------------------------------------------- 1 | using ObserverLibrary.StockExample.Examples.EventAndDelegate; 2 | using ObserverLibrary.StockExample.Examples.IObserver; 3 | using ObserverLibrary.StockExample.Examples.Motivating; 4 | using ObserverLibrary.StockExample.Examples.Traditional; 5 | 6 | namespace ObserverLibrary.StockExample; 7 | 8 | public static class StockExecutor 9 | { 10 | public static void Execute() 11 | { 12 | MotivatingExecutor.Execute(); 13 | TraditionalExecutor.Execute(); 14 | EventAndDelegateExecutor.Execute(); 15 | ObserverExecutor.Execute(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/State/StateLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/ConceptualExample/ConceptualExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using StateLibrary.ConceptualExample.States; 3 | 4 | namespace StateLibrary.ConceptualExample; 5 | 6 | public static class ConceptualExecutor 7 | { 8 | public static void Execute() 9 | { 10 | ConsoleExtension.WriteSeparator("Conceptual example"); 11 | 12 | var context = new Context(new ConcreteStateA()); 13 | context.Request1(); 14 | context.Request2(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/ConceptualExample/States/Common/State.cs: -------------------------------------------------------------------------------- 1 | namespace StateLibrary.ConceptualExample.States.Common; 2 | 3 | /// 4 | /// The base State class declares methods that all Concrete State classes should implement 5 | /// and also provides a backreference to the Context object, associated with the State. 6 | /// This backreference can be used by States to transition the Context to another State. 7 | /// 8 | public abstract class State 9 | { 10 | protected Context? _context; 11 | 12 | public void SetContext(Context context) => _context = context; 13 | 14 | public abstract void Handle1(); 15 | 16 | public abstract void Handle2(); 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/ConceptualExample/States/ConcreteStateB.cs: -------------------------------------------------------------------------------- 1 | using StateLibrary.ConceptualExample.States.Common; 2 | 3 | namespace StateLibrary.ConceptualExample.States; 4 | 5 | public class ConcreteStateB : State 6 | { 7 | public override void Handle1() => Console.Write("ConcreteStateB handles request1."); 8 | 9 | public override void Handle2() 10 | { 11 | if (_context == null) 12 | { 13 | return; 14 | } 15 | 16 | Console.WriteLine("ConcreteStateB handles request2."); 17 | Console.WriteLine("ConcreteStateB wants to change the state of the context."); 18 | 19 | _context.TransitionTo(new ConcreteStateA()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using StateLibrary.ConceptualExample; 3 | using StateLibrary.PackageExample; 4 | using StateLibrary.SteakCookingExample; 5 | 6 | namespace StateLibrary; 7 | 8 | public class Executor : PatternExecutor 9 | { 10 | public override string Name => "State - Behavioral Pattern"; 11 | 12 | public override void Execute() 13 | { 14 | ConceptualExecutor.Execute(); 15 | PackageExecutor.Execute(); 16 | SteakCookingExecutor.Execute(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/PackageExample/Package.cs: -------------------------------------------------------------------------------- 1 | using StateLibrary.PackageExample.States; 2 | using StateLibrary.PackageExample.States.Common; 3 | 4 | namespace StateLibrary.PackageExample; 5 | 6 | public class Package 7 | { 8 | private PackageState _state = new OrderedState(); 9 | 10 | public void Proceed() => _state.Proceed(this); 11 | 12 | public void Revert() => _state.Revert(this); 13 | 14 | public void PrintStatus() => _state.PrintStatus(); 15 | 16 | public void ChangeState(PackageState state) => _state = state; 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/PackageExample/PackageExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace StateLibrary.PackageExample; 4 | 5 | public static class PackageExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Package example"); 10 | 11 | var package = new Package(); 12 | package.PrintStatus(); 13 | 14 | package.Proceed(); 15 | package.PrintStatus(); 16 | 17 | package.Proceed(); 18 | package.PrintStatus(); 19 | 20 | package.Proceed(); 21 | package.PrintStatus(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/PackageExample/States/Common/PackageState.cs: -------------------------------------------------------------------------------- 1 | namespace StateLibrary.PackageExample.States.Common; 2 | 3 | public abstract class PackageState 4 | { 5 | public abstract void Proceed(Package package); 6 | public abstract void Revert(Package package); 7 | public abstract void PrintStatus(); 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/PackageExample/States/DeliveredState.cs: -------------------------------------------------------------------------------- 1 | using StateLibrary.PackageExample.States.Common; 2 | 3 | namespace StateLibrary.PackageExample.States; 4 | 5 | public class DeliveredState : PackageState 6 | { 7 | public override void Proceed(Package package) => 8 | package.ChangeState(new ReceivedState()); 9 | 10 | public override void Revert(Package package) => 11 | package.ChangeState(new OrderedState()); 12 | 13 | public override void PrintStatus() => 14 | Console.WriteLine("Package delivered to post office, not received yet."); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/PackageExample/States/OrderedState.cs: -------------------------------------------------------------------------------- 1 | using StateLibrary.PackageExample.States.Common; 2 | 3 | namespace StateLibrary.PackageExample.States; 4 | 5 | public class OrderedState : PackageState 6 | { 7 | public override void Proceed(Package package) => 8 | package.ChangeState(new DeliveredState()); 9 | 10 | public override void Revert(Package package) => 11 | Console.WriteLine("State can't be reverted. Package is in ordered state, which is its initial state."); 12 | 13 | public override void PrintStatus() => 14 | Console.WriteLine("Package ordered, not delivered to the office yet."); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/PackageExample/States/ReceivedState.cs: -------------------------------------------------------------------------------- 1 | using StateLibrary.PackageExample.States.Common; 2 | 3 | namespace StateLibrary.PackageExample.States; 4 | 5 | public class ReceivedState : PackageState 6 | { 7 | public override void Proceed(Package package) => 8 | Console.WriteLine("Package is already received by a client. There is nothing else left to do."); 9 | 10 | public override void Revert(Package package) => 11 | package.ChangeState(new DeliveredState()); 12 | 13 | public override void PrintStatus() => 14 | Console.WriteLine("Package received by a client."); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/StateLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/SteakCookingExample/States/Overcooked.cs: -------------------------------------------------------------------------------- 1 | using StateLibrary.SteakCookingExample.States.Common; 2 | 3 | namespace StateLibrary.SteakCookingExample.States; 4 | 5 | public class Overcooked : Doneness 6 | { 7 | public Overcooked(Doneness state) 8 | : base(state) 9 | { 10 | _lowerTemperature = 71; 11 | _upperTemperature = double.MaxValue; 12 | _isSafeToEat = false; 13 | } 14 | 15 | public override void CheckDoneness() 16 | { 17 | if (_currentTemperature < _lowerTemperature) 18 | { 19 | _steak.State = new WellDone(this); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/State/StateLibrary/SteakCookingExample/SteakCookingExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace StateLibrary.SteakCookingExample; 4 | 5 | public static class SteakCookingExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Steak cooking example"); 10 | 11 | var steak = new Steak("T-Bone", 48); 12 | 13 | steak.IncreaseTemperature(); 14 | steak.IncreaseTemperature(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Strategy/StrategyLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using StrategyLibrary.ShippingExample; 3 | using StrategyLibrary.SortingExample; 4 | 5 | namespace StrategyLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Strategy - Behavioral Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | ShippingExecutor.Execute(); 14 | SortingExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/ShippingExample/Address.cs: -------------------------------------------------------------------------------- 1 | namespace StrategyLibrary.ShippingExample; 2 | 3 | public class Address 4 | { 5 | public string ContactName { get; set; } = string.Empty; 6 | public string AddressLine1 { get; set; } = string.Empty; 7 | public string AddressLine2 { get; set; } = string.Empty; 8 | public string City { get; set; } = string.Empty; 9 | public string Region { get; set; } = string.Empty; 10 | public string Country { get; set; } = string.Empty; 11 | public string PostalCode { get; set; } = string.Empty; 12 | } 13 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/ShippingExample/Order.cs: -------------------------------------------------------------------------------- 1 | namespace StrategyLibrary.ShippingExample; 2 | 3 | public class Order 4 | { 5 | public Order(string description, Address origin, Address destination) 6 | { 7 | Description = description; 8 | Origin = origin; 9 | Destination = destination; 10 | } 11 | 12 | public string Description { get; } 13 | public Address Origin { get; } 14 | public Address Destination { get; } 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/ShippingExample/ShippingCostCalculationService.cs: -------------------------------------------------------------------------------- 1 | using StrategyLibrary.ShippingExample.ShippingProviders.Common; 2 | 3 | namespace StrategyLibrary.ShippingExample; 4 | 5 | public class ShippingCostCalculationService 6 | { 7 | private readonly IShippingProvider _shippingProvider; 8 | 9 | public ShippingCostCalculationService(IShippingProvider shippingCostStrategy) 10 | { 11 | _shippingProvider = shippingCostStrategy; 12 | } 13 | 14 | public decimal Calculate(Order order) => 15 | _shippingProvider.CalculateCost(order); 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/ShippingExample/ShippingProviders/Common/IShippingProvider.cs: -------------------------------------------------------------------------------- 1 | namespace StrategyLibrary.ShippingExample.ShippingProviders.Common; 2 | 3 | public interface IShippingProvider 4 | { 5 | decimal CalculateCost(Order order); 6 | } 7 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/ShippingExample/ShippingProviders/FedEx.cs: -------------------------------------------------------------------------------- 1 | using StrategyLibrary.ShippingExample.ShippingProviders.Common; 2 | 3 | namespace StrategyLibrary.ShippingExample.ShippingProviders; 4 | 5 | public class FedEx : IShippingProvider 6 | { 7 | public decimal CalculateCost(Order order) => 10; 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/ShippingExample/ShippingProviders/RoyalMail.cs: -------------------------------------------------------------------------------- 1 | using StrategyLibrary.ShippingExample.ShippingProviders.Common; 2 | 3 | namespace StrategyLibrary.ShippingExample.ShippingProviders; 4 | 5 | public class RoyalMail : IShippingProvider 6 | { 7 | public decimal CalculateCost(Order order) => 8.5m; 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/ShippingExample/ShippingProviders/UnitedParcelService.cs: -------------------------------------------------------------------------------- 1 | using StrategyLibrary.ShippingExample.ShippingProviders.Common; 2 | 3 | namespace StrategyLibrary.ShippingExample.ShippingProviders; 4 | 5 | public class UnitedParcelService : IShippingProvider 6 | { 7 | public decimal CalculateCost(Order order) => 9; 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/SortingExample/Person.cs: -------------------------------------------------------------------------------- 1 | namespace StrategyLibrary.SortingExample; 2 | 3 | public class Person 4 | { 5 | public Person(string firstName, string lastName, int yearOfBirth) 6 | { 7 | FirstName = firstName; 8 | LastName = lastName; 9 | YearOfBirth = yearOfBirth; 10 | } 11 | 12 | public string FirstName { get; set; } 13 | public string LastName { get; set; } 14 | public int YearOfBirth { get; set; } 15 | 16 | public override string ToString() => $"{FirstName} {LastName} - {YearOfBirth}"; 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/SortingExample/Strategies/Common/ISortStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace StrategyLibrary.SortingExample.Strategies.Common; 2 | 3 | public interface ISortStrategy 4 | { 5 | IReadOnlyCollection Sort(IReadOnlyCollection persons); 6 | } 7 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/SortingExample/Strategies/SortByFirstName.cs: -------------------------------------------------------------------------------- 1 | using StrategyLibrary.SortingExample.Strategies.Common; 2 | 3 | namespace StrategyLibrary.SortingExample.Strategies; 4 | 5 | public class SortByFirstName : ISortStrategy 6 | { 7 | public IReadOnlyCollection Sort(IReadOnlyCollection persons) 8 | { 9 | var sortedPersons = new List(persons); 10 | sortedPersons.Sort((x, y) => x.FirstName.CompareTo(y.FirstName)); 11 | 12 | return sortedPersons; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/SortingExample/Strategies/SortByLastName.cs: -------------------------------------------------------------------------------- 1 | using StrategyLibrary.SortingExample.Strategies.Common; 2 | 3 | namespace StrategyLibrary.SortingExample.Strategies; 4 | 5 | public class SortByLastName : ISortStrategy 6 | { 7 | public IReadOnlyCollection Sort(IReadOnlyCollection persons) 8 | { 9 | var sortedPersons = new List(persons); 10 | sortedPersons.Sort((x, y) => x.LastName.CompareTo(y.LastName)); 11 | 12 | return sortedPersons; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/SortingExample/Strategies/SortByYearOfBirth.cs: -------------------------------------------------------------------------------- 1 | using StrategyLibrary.SortingExample.Strategies.Common; 2 | 3 | namespace StrategyLibrary.SortingExample.Strategies; 4 | 5 | public class SortByYearOfBirth : ISortStrategy 6 | { 7 | public IReadOnlyCollection Sort(IReadOnlyCollection persons) 8 | { 9 | var sortedPersons = new List(persons); 10 | sortedPersons.Sort((x, y) => x.YearOfBirth.CompareTo(y.YearOfBirth)); 11 | 12 | return sortedPersons; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Strategy/StrategyLibrary/StrategyLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/BreadExample/Bread.cs: -------------------------------------------------------------------------------- 1 | namespace TemplateMethodLibrary.BreadExample; 2 | 3 | public abstract class Bread 4 | { 5 | /// 6 | /// The template method. 7 | /// 8 | public void Make() 9 | { 10 | MixIngredients(); 11 | Bake(); 12 | Slice(); 13 | } 14 | 15 | protected abstract void MixIngredients(); 16 | 17 | protected abstract void Bake(); 18 | 19 | protected virtual void Slice() => 20 | Console.WriteLine($"Slicing the {GetType().Name}!"); 21 | } 22 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/BreadExample/BreadExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace TemplateMethodLibrary.BreadExample; 4 | 5 | public static class BreadExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Bread example"); 10 | 11 | var whiteBread = new WhiteBread(); 12 | whiteBread.Make(); 13 | 14 | Console.WriteLine(); 15 | 16 | var wholeWheatBread = new WholeWheatBread(); 17 | wholeWheatBread.Make(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/BreadExample/WhiteBread.cs: -------------------------------------------------------------------------------- 1 | namespace TemplateMethodLibrary.BreadExample; 2 | 3 | public class WhiteBread : Bread 4 | { 5 | protected override void MixIngredients() => 6 | Console.WriteLine("Gathering ingredients for white bread."); 7 | 8 | protected override void Bake() => 9 | Console.WriteLine("Baking the white bread for 15 minutes."); 10 | } 11 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/BreadExample/WholeWheatBread.cs: -------------------------------------------------------------------------------- 1 | namespace TemplateMethodLibrary.BreadExample; 2 | 3 | public class WholeWheatBread : Bread 4 | { 5 | protected override void MixIngredients() => 6 | Console.WriteLine("Gathering ingredients for whole wheat bread."); 7 | 8 | protected override void Bake() => 9 | Console.WriteLine("Baking the whole wheat bread for 20 minutes."); 10 | } 11 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/ConceptualExample/Client.cs: -------------------------------------------------------------------------------- 1 | namespace TemplateMethodLibrary.ConceptualExample; 2 | 3 | public class Client 4 | { 5 | /// 6 | /// The client code calls the template method to execute the algorithm. 7 | /// Client code does not have to know the concrete class of an object it works with, 8 | /// as long as it works with objects through the interface of their base class. 9 | /// 10 | /// Abstract class. 11 | public static void ProcessSomething(AbstractClass abstractClass) => 12 | // Initial operations 13 | abstractClass.TemplateMethod(); 14 | // Additional operations 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/ConceptualExample/ConceptualExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace TemplateMethodLibrary.ConceptualExample; 4 | 5 | public static class ConceptualExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Conceptual example"); 10 | 11 | Console.WriteLine("Working with concrete class 1..."); 12 | Client.ProcessSomething(new ConcreteClass1()); 13 | 14 | Console.WriteLine("\nWorking with concrete class 2..."); 15 | Client.ProcessSomething(new ConcreteClass2()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/ConceptualExample/ConcreteClass1.cs: -------------------------------------------------------------------------------- 1 | namespace TemplateMethodLibrary.ConceptualExample; 2 | 3 | /// 4 | /// Concrete classes have to implement all abstract operations of the base class. 5 | /// They can also override some operations with a default implementation. 6 | /// 7 | public class ConcreteClass1 : AbstractClass 8 | { 9 | protected override void RequiredOperations1() => 10 | Console.WriteLine("ConcreteClass1 says: Implemented Operation1"); 11 | 12 | protected override void RequiredOperation2() => 13 | Console.WriteLine("ConcreteClass1 says: Implemented Operation2"); 14 | } 15 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/ConceptualExample/ConcreteClass2.cs: -------------------------------------------------------------------------------- 1 | namespace TemplateMethodLibrary.ConceptualExample; 2 | 3 | /// 4 | /// Usually, concrete classes override only a fraction of base class' operations. 5 | /// 6 | public class ConcreteClass2 : AbstractClass 7 | { 8 | protected override void RequiredOperations1() => 9 | Console.WriteLine("ConcreteClass2 says: Implemented Operation1"); 10 | 11 | protected override void RequiredOperation2() => 12 | Console.WriteLine("ConcreteClass2 says: Implemented Operation2"); 13 | 14 | protected override void Hook1() => 15 | Console.WriteLine("ConcreteClass2 says: Overridden Hook1"); 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using TemplateMethodLibrary.BreadExample; 3 | using TemplateMethodLibrary.ConceptualExample; 4 | 5 | namespace TemplateMethodLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Template Method - Behavioral Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | BreadExecutor.Execute(); 14 | ConceptualExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/TemplateMethod/TemplateMethodLibrary/TemplateMethodLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/BehavioralPatterns/Visitor/VisitorLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/CompanyExample/Elements/Common/IEmployeeEvaluation.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.CompanyExample.Visitors.Common; 2 | 3 | namespace VisitorLibrary.CompanyExample.Elements.Common; 4 | 5 | public interface IEmployeeEvaluation 6 | { 7 | void Evaluate(IPerformanceReview performanceReview); 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/CompanyExample/Elements/Developer.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.CompanyExample.Elements.Common; 2 | 3 | namespace VisitorLibrary.CompanyExample.Elements; 4 | 5 | public class Developer : Employee 6 | { 7 | public Developer() 8 | : base("Marc Murray", 80000, 25) 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/CompanyExample/Elements/ProductOwner.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.CompanyExample.Elements.Common; 2 | 3 | namespace VisitorLibrary.CompanyExample.Elements; 4 | 5 | public class ProductOwner : Employee 6 | { 7 | public ProductOwner() 8 | : base("Arnold Aster", 75000, 25) 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/CompanyExample/Elements/ProjectManager.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.CompanyExample.Elements.Common; 2 | 3 | namespace VisitorLibrary.CompanyExample.Elements; 4 | 5 | public class ProjectManager : Employee 6 | { 7 | public ProjectManager() 8 | : base("Anna Dover", 82000, 27) 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/CompanyExample/Visitors/Common/IPerformanceReview.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.CompanyExample.Elements.Common; 2 | 3 | namespace VisitorLibrary.CompanyExample.Visitors.Common; 4 | 5 | public interface IPerformanceReview 6 | { 7 | void Appraise(IEmployeeEvaluation employeeEvaluation); 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using VisitorLibrary.CompanyExample; 3 | using VisitorLibrary.PersonDynamicProgrammingExample; 4 | using VisitorLibrary.PersonExample; 5 | 6 | namespace VisitorLibrary; 7 | 8 | public class Executor : PatternExecutor 9 | { 10 | public override string Name => "Visitor - Behavioral Pattern"; 11 | 12 | public override void Execute() 13 | { 14 | CompanyExecutor.Execute(); 15 | PersonDynamicProgrammingExecutor.Execute(); 16 | PersonExecutor.Execute(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonDynamicProgrammingExample/Elements/BankSavingsAccount.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonDynamicProgrammingExample.Elements.Common; 2 | 3 | namespace VisitorLibrary.PersonDynamicProgrammingExample.Elements; 4 | 5 | public class BankSavingsAccount : IAsset 6 | { 7 | public int Amount { get; set; } 8 | public double MonthlyInterest { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonDynamicProgrammingExample/Elements/Common/IAsset.cs: -------------------------------------------------------------------------------- 1 | namespace VisitorLibrary.PersonDynamicProgrammingExample.Elements.Common; 2 | 3 | // IAsset is no longer required to expose visiting methods. 4 | public interface IAsset 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonDynamicProgrammingExample/Elements/Loan.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonDynamicProgrammingExample.Elements.Common; 2 | 3 | namespace VisitorLibrary.PersonDynamicProgrammingExample.Elements; 4 | 5 | public class Loan : IAsset 6 | { 7 | public int Owed { get; set; } 8 | public int MonthlyPayment { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonDynamicProgrammingExample/Elements/RealEstate.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonDynamicProgrammingExample.Elements.Common; 2 | 3 | namespace VisitorLibrary.PersonDynamicProgrammingExample.Elements; 4 | 5 | public class RealEstate : IAsset 6 | { 7 | public int EstimatedValue { get; set; } 8 | public int MonthlyIncomeFromRenting { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonExample/Elements/BankSavingsAccount.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonExample.Elements.Common; 2 | using VisitorLibrary.PersonExample.Visitors.Common; 3 | 4 | namespace VisitorLibrary.PersonExample.Elements; 5 | 6 | public class BankSavingsAccount : IAsset 7 | { 8 | public int Amount { get; set; } 9 | public double MonthlyInterest { get; set; } 10 | 11 | public void Accept(IVisitor visitor) => 12 | visitor.Visit(this); 13 | } 14 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonExample/Elements/Common/IAsset.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonExample.Visitors.Common; 2 | 3 | namespace VisitorLibrary.PersonExample.Elements.Common; 4 | 5 | public interface IAsset 6 | { 7 | void Accept(IVisitor visitor); 8 | } 9 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonExample/Elements/Loan.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonExample.Elements.Common; 2 | using VisitorLibrary.PersonExample.Visitors.Common; 3 | 4 | namespace VisitorLibrary.PersonExample.Elements; 5 | 6 | public class Loan : IAsset 7 | { 8 | public int Owed { get; set; } 9 | public int MonthlyPayment { get; set; } 10 | 11 | public void Accept(IVisitor visitor) => 12 | visitor.Visit(this); 13 | } 14 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonExample/Elements/RealEstate.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonExample.Elements.Common; 2 | using VisitorLibrary.PersonExample.Visitors.Common; 3 | 4 | namespace VisitorLibrary.PersonExample.Elements; 5 | 6 | public class RealEstate : IAsset 7 | { 8 | public int EstimatedValue { get; set; } 9 | public int MonthlyIncomeFromRenting { get; set; } 10 | 11 | public void Accept(IVisitor visitor) => 12 | visitor.Visit(this); 13 | } 14 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonExample/Person.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonExample.Elements.Common; 2 | using VisitorLibrary.PersonExample.Visitors.Common; 3 | 4 | namespace VisitorLibrary.PersonExample; 5 | 6 | public class Person 7 | { 8 | private readonly List _assets = new(); 9 | 10 | public void RegisterNewAsset(IAsset asset) => 11 | _assets.Add(asset); 12 | 13 | public void InspectAssets(IVisitor visitor) 14 | { 15 | foreach (var asset in _assets) 16 | { 17 | asset.Accept(visitor); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonExample/Visitors/Common/IVisitor.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonExample.Elements; 2 | 3 | namespace VisitorLibrary.PersonExample.Visitors.Common; 4 | 5 | /// 6 | /// The visitor interface declares a set of visiting methods that correspond 7 | /// to element classes. The signature of a visiting method allows the visitor 8 | /// to identify the exact class of the component that it's dealing with. 9 | /// 10 | public interface IVisitor 11 | { 12 | void Visit(RealEstate realEstate); 13 | void Visit(BankSavingsAccount bankSavingsAccount); 14 | void Visit(Loan loan); 15 | } 16 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonExample/Visitors/MonthlyIncomeVisitor.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonExample.Elements; 2 | using VisitorLibrary.PersonExample.Visitors.Common; 3 | 4 | namespace VisitorLibrary.PersonExample.Visitors; 5 | 6 | public class MonthlyIncomeVisitor : IVisitor 7 | { 8 | public double Amount { get; private set; } 9 | 10 | public void Visit(RealEstate realEstate) => 11 | Amount += realEstate.MonthlyIncomeFromRenting; 12 | 13 | public void Visit(BankSavingsAccount bankSavingsAccount) => 14 | Amount += bankSavingsAccount.Amount * bankSavingsAccount.MonthlyInterest; 15 | 16 | public void Visit(Loan loan) => 17 | Amount -= loan.MonthlyPayment; 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/PersonExample/Visitors/NetWorthVisitor.cs: -------------------------------------------------------------------------------- 1 | using VisitorLibrary.PersonExample.Elements; 2 | using VisitorLibrary.PersonExample.Visitors.Common; 3 | 4 | namespace VisitorLibrary.PersonExample.Visitors; 5 | 6 | public class NetWorthVisitor : IVisitor 7 | { 8 | public int Total { get; private set; } 9 | 10 | public void Visit(RealEstate realEstate) => 11 | Total += realEstate.EstimatedValue; 12 | 13 | public void Visit(BankSavingsAccount bankSavingsAccount) => 14 | Total += bankSavingsAccount.Amount; 15 | 16 | public void Visit(Loan loan) => 17 | Total -= loan.Owed; 18 | } 19 | -------------------------------------------------------------------------------- /src/BehavioralPatterns/Visitor/VisitorLibrary/VisitorLibrary.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/BuildingBlocks/BuildingBlocks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/BuildingBlocks/ConsoleExtension.cs: -------------------------------------------------------------------------------- 1 | namespace BuildingBlocks; 2 | 3 | public static class ConsoleExtension 4 | { 5 | public static void WriteSeparator(string title) 6 | { 7 | Console.WriteLine(); 8 | Console.WriteLine(title); 9 | Console.WriteLine("--------------------------------------------------"); 10 | } 11 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/PatternExecutor.cs: -------------------------------------------------------------------------------- 1 | namespace BuildingBlocks; 2 | 3 | /// 4 | /// Every design pattern example should have an executor class 5 | /// that inherits from . 6 | /// 7 | public abstract class PatternExecutor 8 | { 9 | /// 10 | /// Gets name. 11 | /// 12 | public virtual string Name => GetType().Name; 13 | 14 | /// 15 | /// The Execute method is the entry point of an executable design pattern example. 16 | /// When an arbitrary design pattern example is chosen from the command menu, 17 | /// the Execute method is the first method that is invoked. 18 | /// 19 | public abstract void Execute(); 20 | } -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/MealSimpleFactory/MealSimpleFactory.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/MealSimpleFactory/Meals/Common/IMeal.cs: -------------------------------------------------------------------------------- 1 | namespace MealSimpleFactory.Meals.Common; 2 | 3 | public interface IMeal 4 | { 5 | void ShowAmountOfCalories(); 6 | 7 | void ShowDescription(); 8 | } 9 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/MealSimpleFactory/Meals/GreenSalad.cs: -------------------------------------------------------------------------------- 1 | using MealSimpleFactory.Meals.Common; 2 | 3 | namespace MealSimpleFactory.Meals; 4 | 5 | public class GreenSalad : IMeal 6 | { 7 | public void ShowAmountOfCalories() => 8 | Console.WriteLine("Calories: 250 kcal"); 9 | 10 | public void ShowDescription() => 11 | Console.WriteLine("Green salad: lettuce, cucumber and green olives"); 12 | } 13 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/MealSimpleFactory/Meals/Hamburger.cs: -------------------------------------------------------------------------------- 1 | using MealSimpleFactory.Meals.Common; 2 | 3 | namespace MealSimpleFactory.Meals; 4 | 5 | public class Hamburger : IMeal 6 | { 7 | public void ShowAmountOfCalories() => 8 | Console.WriteLine("Calories: 450 kcal"); 9 | 10 | public void ShowDescription() => 11 | Console.WriteLine("Hamburger: beef meat, Worcestershire sauce and cheese."); 12 | } 13 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/MealSimpleFactory/Meals/NullMeal.cs: -------------------------------------------------------------------------------- 1 | using MealSimpleFactory.Meals.Common; 2 | 3 | namespace MealSimpleFactory.Meals; 4 | 5 | public class NullMeal : IMeal 6 | { 7 | public void ShowAmountOfCalories() 8 | { 9 | } 10 | 11 | public void ShowDescription() 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Common/Factories/IRestaurantFactory.cs: -------------------------------------------------------------------------------- 1 | using RestaurantAbstractFactory.Common.Products; 2 | 3 | namespace RestaurantAbstractFactory.Common.Factories; 4 | 5 | /// 6 | /// The Abstract Factory interface declares a set of methods for creating each of the abstract products. 7 | /// 8 | public interface IRestaurantFactory 9 | { 10 | IAppetizer PrepareAppetizer(); 11 | 12 | IMainCourse PrepareMainCourse(); 13 | 14 | IDessert PrepareDessert(); 15 | } -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Common/Products/IAppetizer.cs: -------------------------------------------------------------------------------- 1 | namespace RestaurantAbstractFactory.Common.Products; 2 | 3 | /// 4 | /// Abstract Products declare interfaces for a set of distinct 5 | /// but related products which make up a product family. 6 | /// Each abstract product must be implemented in all given variants, which for this project are 7 | /// and 8 | /// 9 | public interface IAppetizer : IMeal 10 | { 11 | bool IsBroth(); 12 | } 13 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Common/Products/IDessert.cs: -------------------------------------------------------------------------------- 1 | namespace RestaurantAbstractFactory.Common.Products; 2 | 3 | public interface IDessert : IMeal 4 | { 5 | void ShowSugarAmount(); 6 | } -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Common/Products/IMainCourse.cs: -------------------------------------------------------------------------------- 1 | namespace RestaurantAbstractFactory.Common.Products; 2 | 3 | public interface IMainCourse : IMeal 4 | { 5 | void ShowRecommendedDrink(); 6 | } -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Common/Products/IMeal.cs: -------------------------------------------------------------------------------- 1 | namespace RestaurantAbstractFactory.Common.Products; 2 | 3 | public interface IMeal 4 | { 5 | void ShowDescription(); 6 | } -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/FastFood/Products/FastFoodAppetizer.cs: -------------------------------------------------------------------------------- 1 | using RestaurantAbstractFactory.Common.Products; 2 | 3 | namespace RestaurantAbstractFactory.FastFood.Products; 4 | 5 | /// 6 | /// Concrete Products are various implementations of abstract products, grouped by variants. 7 | /// 8 | public class FastFoodAppetizer : IAppetizer 9 | { 10 | public void ShowDescription() => Console.WriteLine("Bread bites - with garlic and marinara sauce."); 11 | 12 | public bool IsBroth() => false; 13 | } 14 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/FastFood/Products/FastFoodDessert.cs: -------------------------------------------------------------------------------- 1 | using RestaurantAbstractFactory.Common.Products; 2 | 3 | namespace RestaurantAbstractFactory.FastFood.Products; 4 | 5 | public class FastFoodDessert : IDessert 6 | { 7 | public void ShowDescription() => Console.WriteLine("Pancakes - with nutella and bananas."); 8 | 9 | public void ShowSugarAmount() => Console.WriteLine("High sugar amount."); 10 | } 11 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/FastFood/Products/FastFoodMainCourse.cs: -------------------------------------------------------------------------------- 1 | using RestaurantAbstractFactory.Common.Products; 2 | 3 | namespace RestaurantAbstractFactory.FastFood.Products; 4 | 5 | public class FastFoodMainCourse : IMainCourse 6 | { 7 | public void ShowDescription() => Console.WriteLine("Hamburger - with beef meat, Worcestershire sauce and cheese."); 8 | 9 | public void ShowRecommendedDrink() => Console.WriteLine("Beer."); 10 | } 11 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/RestaurantAbstractFactory.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Vegetarian/Products/VegetarianAppetizer.cs: -------------------------------------------------------------------------------- 1 | using RestaurantAbstractFactory.Common.Products; 2 | 3 | namespace RestaurantAbstractFactory.Vegetarian.Products; 4 | 5 | /// 6 | /// Concrete Products are various implementations of abstract products, grouped by variants. 7 | /// 8 | public class VegetarianAppetizer : IAppetizer 9 | { 10 | public void ShowDescription() => Console.WriteLine("Broth - with pumpkin."); 11 | 12 | public bool IsBroth() => true; 13 | } 14 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Vegetarian/Products/VegetarianDessert.cs: -------------------------------------------------------------------------------- 1 | using RestaurantAbstractFactory.Common.Products; 2 | 3 | namespace RestaurantAbstractFactory.Vegetarian.Products; 4 | 5 | public class VegetarianDessert : IDessert 6 | { 7 | public void ShowDescription() => Console.WriteLine("Rice Pudding - with milk and vanilla extract"); 8 | 9 | public void ShowSugarAmount() => Console.WriteLine("Low sugar amount."); 10 | } 11 | -------------------------------------------------------------------------------- /src/CreationalPatterns/AbstractFactory/RestaurantAbstractFactory/Vegetarian/Products/VegetarianMainCourse.cs: -------------------------------------------------------------------------------- 1 | using RestaurantAbstractFactory.Common.Products; 2 | 3 | namespace RestaurantAbstractFactory.Vegetarian.Products; 4 | 5 | public class VegetarianMainCourse : IMainCourse 6 | { 7 | public void ShowDescription() => Console.WriteLine("Green salad - with lettuce, cucumber and green olives"); 8 | 9 | public void ShowRecommendedDrink() => Console.WriteLine("Sparkling water."); 10 | } 11 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Builder/CustomSandwichBuilder/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/CreationalPatterns/Builder/CustomSandwichBuilder/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/CreationalPatterns/Builder/CustomSandwichBuilder/CustomSandwichBuilder.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Builder/CustomSandwichBuilder/Products/Enums/BreadType.cs: -------------------------------------------------------------------------------- 1 | namespace CustomSandwichBuilder.Products.Enums; 2 | 3 | public enum BreadType 4 | { 5 | White, 6 | Wheat, 7 | WholeGrain, 8 | Rye, 9 | } 10 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Builder/CustomSandwichBuilder/Products/Enums/CheeseType.cs: -------------------------------------------------------------------------------- 1 | namespace CustomSandwichBuilder.Products.Enums; 2 | 3 | public enum CheeseType 4 | { 5 | Gouda, 6 | Cheddar, 7 | ParmigianoReggiano, 8 | Camembert, 9 | Pule, 10 | } 11 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Builder/CustomSandwichBuilder/Products/Enums/MeatType.cs: -------------------------------------------------------------------------------- 1 | namespace CustomSandwichBuilder.Products.Enums; 2 | 3 | public enum MeatType 4 | { 5 | Beef, 6 | Pork, 7 | Chicken, 8 | Turkey, 9 | Salami, 10 | } 11 | -------------------------------------------------------------------------------- /src/CreationalPatterns/FactoryMethod/RestaurantManagement/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/CreationalPatterns/FactoryMethod/RestaurantManagement/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/CreationalPatterns/FactoryMethod/RestaurantManagement/Common/IMeal.cs: -------------------------------------------------------------------------------- 1 | namespace RestaurantManagement.Common; 2 | 3 | /// 4 | /// The Product declares the interface, which is common to all objects that 5 | /// can be produced by the creator and its subclasses. 6 | /// 7 | public interface IMeal 8 | { 9 | void ShowDescription(); 10 | } 11 | -------------------------------------------------------------------------------- /src/CreationalPatterns/FactoryMethod/RestaurantManagement/FastFood/FastFoodRestaurant.cs: -------------------------------------------------------------------------------- 1 | using RestaurantManagement.Common; 2 | 3 | namespace RestaurantManagement.FastFood; 4 | 5 | /// 6 | /// Concrete creators override the base factory method so it returns a different type of product. 7 | /// 8 | public class FastFoodRestaurant : Restaurant 9 | { 10 | public override IMeal PrepareMainCourse() => new Hamburger(); 11 | } 12 | -------------------------------------------------------------------------------- /src/CreationalPatterns/FactoryMethod/RestaurantManagement/FastFood/Hamburger.cs: -------------------------------------------------------------------------------- 1 | using RestaurantManagement.Common; 2 | 3 | namespace RestaurantManagement.FastFood; 4 | 5 | /// 6 | /// Concrete products are different implementations of the product interface . 7 | /// 8 | public class Hamburger : IMeal 9 | { 10 | public void ShowDescription() => 11 | Console.WriteLine("Hamburger - with beef meat, Worcestershire sauce and cheese."); 12 | } 13 | -------------------------------------------------------------------------------- /src/CreationalPatterns/FactoryMethod/RestaurantManagement/RestaurantManagement.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/CreationalPatterns/FactoryMethod/RestaurantManagement/Vegetarian/GreenSalad.cs: -------------------------------------------------------------------------------- 1 | using RestaurantManagement.Common; 2 | 3 | namespace RestaurantManagement.Vegetarian; 4 | 5 | /// 6 | /// Concrete products are different implementations of the product interface . 7 | /// 8 | public class GreenSalad : IMeal 9 | { 10 | public void ShowDescription() => 11 | Console.WriteLine("Green salad - with lettuce, cucumber and green olives"); 12 | } 13 | -------------------------------------------------------------------------------- /src/CreationalPatterns/FactoryMethod/RestaurantManagement/Vegetarian/VegetarianRestaurant.cs: -------------------------------------------------------------------------------- 1 | using RestaurantManagement.Common; 2 | 3 | namespace RestaurantManagement.Vegetarian; 4 | 5 | /// 6 | /// Concrete creators override the base factory method so it returns a different type of product. 7 | /// 8 | public class VegetarianRestaurant : Restaurant 9 | { 10 | public override IMeal PrepareMainCourse() => new GreenSalad(); 11 | } 12 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/Assets/pattern-structure-with-registry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/CreationalPatterns/Prototype/PrototypeLibrary/Assets/pattern-structure-with-registry.png -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/CreationalPatterns/Prototype/PrototypeLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/ColorRegistryExample/ColorRegistry.cs: -------------------------------------------------------------------------------- 1 | using PrototypeLibrary.ColorRegistryExample.Common; 2 | 3 | namespace PrototypeLibrary.ColorRegistryExample; 4 | 5 | public class ColorRegistry 6 | { 7 | private readonly Dictionary _colors = new(); 8 | 9 | public IColorPrototype this[string key] 10 | { 11 | get => _colors[key]; 12 | set => _colors[key] = value; 13 | } 14 | 15 | public void List() 16 | { 17 | Console.WriteLine("Available colors in the registry..."); 18 | 19 | foreach (var color in _colors) 20 | { 21 | Console.WriteLine($"Name: {color.Key}"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/ColorRegistryExample/Common/IColorPrototype.cs: -------------------------------------------------------------------------------- 1 | namespace PrototypeLibrary.ColorRegistryExample.Common; 2 | 3 | /// 4 | /// The Prototype interface declares the cloning methods. 5 | /// In most cases, it’s a single Clone method. 6 | /// Instead of manually defining interface, we can use . 7 | /// 8 | public interface IColorPrototype 9 | { 10 | IColorPrototype Clone(); 11 | } 12 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/ComplexUnstableObjectExample/ComplexUnstableObjectExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace PrototypeLibrary.ComplexUnstableObjectExample; 4 | 5 | public static class ComplexUnstableObjectExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Complex unstable object example"); 10 | 11 | var complicatedObject = new ComplexUnstableObject("a", 'c', "e"); 12 | 13 | // Clients from different assembly can't call constructor 14 | // because it's internal, but they can call Clone. 15 | var unused = complicatedObject.Clone(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/DeepCloneExample/Extensions/SystemExtension.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace PrototypeLibrary.DeepCloneExample.Extensions; 4 | 5 | public static class SystemExtension 6 | { 7 | public static T DeepClone(this T source) 8 | { 9 | var serialized = JsonConvert.SerializeObject(source); 10 | var clonedObject = JsonConvert.DeserializeObject(serialized); 11 | 12 | if (clonedObject == null) 13 | { 14 | throw new JsonException("The source can't be serialized and deserialized successfully."); 15 | } 16 | 17 | return clonedObject; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/DeepCloneExample/Models/OperatingSystem.cs: -------------------------------------------------------------------------------- 1 | namespace PrototypeLibrary.DeepCloneExample.Models; 2 | 3 | public class OperatingSystem 4 | { 5 | public string Name { get; set; } = string.Empty; 6 | public string Version { get; set; } = string.Empty; 7 | public string Description { get; set; } = string.Empty; 8 | } 9 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/PrototypeLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Prototype/PrototypeLibrary/WebPageScraperExample/ICustomCloneable.cs: -------------------------------------------------------------------------------- 1 | namespace PrototypeLibrary.WebPageScraperExample; 2 | 3 | public interface ICustomCloneable 4 | { 5 | WebPageScraper Clone(); 6 | } 7 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Singleton/Greeter/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/CreationalPatterns/Singleton/Greeter/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/CreationalPatterns/Singleton/Greeter/Greeter.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/CreationalPatterns/Singleton/Greeter/Types/Common/BaseGreeter.cs: -------------------------------------------------------------------------------- 1 | namespace Greeter.Types.Common; 2 | 3 | public abstract class BaseGreeter 4 | { 5 | public virtual void Greet() => 6 | Console.WriteLine($"Greetings from {GetType().Name}!"); 7 | } 8 | -------------------------------------------------------------------------------- /src/DesignPatternsLibrary/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "DesignPatternsLibrary": { 4 | "commandName": "Project" 5 | }, 6 | "Container (Dockerfile)": { 7 | "commandName": "Docker" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/AdapterLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/Assets/pattern-structure-class-adapter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/StructuralPatterns/Adapter/AdapterLibrary/Assets/pattern-structure-class-adapter.png -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/Assets/pattern-structure-object-adapter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/StructuralPatterns/Adapter/AdapterLibrary/Assets/pattern-structure-object-adapter.png -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/BillingSystemExample/Employee.cs: -------------------------------------------------------------------------------- 1 | namespace AdapterLibrary.BillingSystemExample; 2 | 3 | public class Employee 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } = string.Empty; 7 | public decimal Salary { get; set; } 8 | } 9 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/BillingSystemExample/HRSystem.cs: -------------------------------------------------------------------------------- 1 | namespace AdapterLibrary.BillingSystemExample; 2 | 3 | /// 4 | /// This class contains the functionality which the client requires, 5 | /// but it's not compatible with the existing client code. 6 | /// So, it requires some adaptation before the client code can use it. 7 | /// 8 | public class HRSystem 9 | { 10 | public string[,] GetEmployeesInfo() => 11 | new string[4, 3] 12 | { 13 | { "1", "John", "5950" }, 14 | { "2", "Anna", "5800" }, 15 | { "3", "Nicole", "6100" }, 16 | { "4", "Steven", "5000" }, 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/BillingSystemExample/ISalaryProcessor.cs: -------------------------------------------------------------------------------- 1 | namespace AdapterLibrary.BillingSystemExample; 2 | 3 | /// 4 | /// The Client Interface describes a protocol that other classes must follow to be able to collaborate with the client code. 5 | /// 6 | public interface ISalaryProcessor 7 | { 8 | void ProcessSalaries(string[,] rawEmployees); 9 | } 10 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/BillingSystemExample/ThirdPartyBillingSystem.cs: -------------------------------------------------------------------------------- 1 | namespace AdapterLibrary.BillingSystemExample; 2 | 3 | /// 4 | /// The Service is some useful class (usually 3rd-party or legacy). 5 | /// The client can’t use this class directly because it has an incompatible interface. 6 | /// 7 | public class ThirdPartyBillingSystem 8 | { 9 | public void ProcessSalary(List employees) 10 | { 11 | foreach (var employee in employees) 12 | { 13 | Console.WriteLine($"EUR {employee.Salary} salary credited to {employee.Name}'s account."); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using AdapterLibrary.BillingSystemExample; 2 | using AdapterLibrary.MovieBroadcasterExample; 3 | using BuildingBlocks; 4 | 5 | namespace AdapterLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Adapter - Structural Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | BillingSystemExecutor.Execute(); 14 | MovieBroadcasterExecutor.Execute(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/MovieBroadcasterExample/IBroadcaster.cs: -------------------------------------------------------------------------------- 1 | namespace AdapterLibrary.MovieBroadcasterExample; 2 | 3 | public interface IBroadcaster 4 | { 5 | void BroadcastToExternalPartners(); 6 | } 7 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/MovieBroadcasterExample/Movie.cs: -------------------------------------------------------------------------------- 1 | namespace AdapterLibrary.MovieBroadcasterExample; 2 | 3 | public class Movie 4 | { 5 | public string Name { get; set; } = string.Empty; 6 | public DateTime ReleaseDate { get; set; } 7 | public double Rating { get; set; } 8 | } 9 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/MovieBroadcasterExample/MovieBroadcasterExecutor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | 3 | namespace AdapterLibrary.MovieBroadcasterExample; 4 | 5 | public static class MovieBroadcasterExecutor 6 | { 7 | public static void Execute() 8 | { 9 | ConsoleExtension.WriteSeparator("Movie broadcaster example"); 10 | 11 | var registry = new MovieRegistry(); 12 | 13 | IBroadcaster adapter = new BroadcastAdapter(registry); 14 | adapter.BroadcastToExternalPartners(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Adapter/AdapterLibrary/MovieBroadcasterExample/ThirdPartyBroadcaster.cs: -------------------------------------------------------------------------------- 1 | namespace AdapterLibrary.MovieBroadcasterExample; 2 | 3 | public class ThirdPartyBroadcaster 4 | { 5 | public void Broadcast(string jsonMovies) 6 | { 7 | Console.WriteLine("\nNew movies are available for broadcasting from 3rd party system..."); 8 | Console.WriteLine(jsonMovies); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/StructuralPatterns/Bridge/BridgeLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/BridgeLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DevicesAndRemotesExample/Abstractions/AdvancedRemoteControl.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DevicesAndRemotesExample.Abstractions.Common; 2 | using BridgeLibrary.DevicesAndRemotesExample.Implementations.Common; 3 | 4 | namespace BridgeLibrary.DevicesAndRemotesExample.Abstractions; 5 | 6 | public class AdvancedRemoteControl : RemoteControl 7 | { 8 | public AdvancedRemoteControl(Device device) 9 | : base(device) 10 | { 11 | } 12 | 13 | public virtual void Mute() 14 | { 15 | Console.WriteLine("Mute smart TV Command is issued through advanced remote."); 16 | _device.Volume = 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DevicesAndRemotesExample/Abstractions/UniversalRemoteControl.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DevicesAndRemotesExample.Abstractions.Common; 2 | using BridgeLibrary.DevicesAndRemotesExample.Implementations.Common; 3 | 4 | namespace BridgeLibrary.DevicesAndRemotesExample.Abstractions; 5 | 6 | public class UniversalRemoteControl : RemoteControl 7 | { 8 | public UniversalRemoteControl(Device device) 9 | : base(device) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DevicesAndRemotesExample/Implementations/Radio.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DevicesAndRemotesExample.Implementations.Common; 2 | 3 | namespace BridgeLibrary.DevicesAndRemotesExample.Implementations; 4 | 5 | public class Radio : Device 6 | { 7 | public override void TurnOn() 8 | { 9 | base.TurnOn(); 10 | Console.WriteLine("Radio is turned on."); 11 | } 12 | 13 | public override void TurnOff() 14 | { 15 | base.TurnOff(); 16 | Console.WriteLine("Radio is turned off."); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DevicesAndRemotesExample/Implementations/SmartTV.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DevicesAndRemotesExample.Implementations.Common; 2 | 3 | namespace BridgeLibrary.DevicesAndRemotesExample.Implementations; 4 | 5 | public class SmartTV : Device 6 | { 7 | public override void TurnOn() 8 | { 9 | base.TurnOn(); 10 | Console.WriteLine("Smart TV is turned on."); 11 | } 12 | 13 | public override void TurnOff() 14 | { 15 | base.TurnOff(); 16 | Console.WriteLine("Smart TV is turned off."); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DocumentsAndFormattersExample/Documents/Common/Document.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DocumentsAndFormattersExample.Formatters.Common; 2 | 3 | namespace BridgeLibrary.DocumentsAndFormattersExample.Documents.Common; 4 | 5 | public abstract class Document 6 | { 7 | protected readonly IFormatter _formatter; 8 | 9 | protected Document(IFormatter formatter) 10 | { 11 | _formatter = formatter; 12 | } 13 | 14 | public abstract void Print(); 15 | } 16 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DocumentsAndFormattersExample/Formatters/BackwardsFormatter.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DocumentsAndFormattersExample.Formatters.Common; 2 | 3 | namespace BridgeLibrary.DocumentsAndFormattersExample.Formatters; 4 | 5 | public class BackwardsFormatter : IFormatter 6 | { 7 | public string Format(string key, string value) => 8 | $"{key}: {new string(value.Reverse().ToArray())}"; 9 | } 10 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DocumentsAndFormattersExample/Formatters/Common/IFormatter.cs: -------------------------------------------------------------------------------- 1 | namespace BridgeLibrary.DocumentsAndFormattersExample.Formatters.Common; 2 | 3 | public interface IFormatter 4 | { 5 | string Format(string key, string value); 6 | } 7 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DocumentsAndFormattersExample/Formatters/FancyFormatter.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DocumentsAndFormattersExample.Formatters.Common; 2 | 3 | namespace BridgeLibrary.DocumentsAndFormattersExample.Formatters; 4 | 5 | public class FancyFormatter : IFormatter 6 | { 7 | public string Format(string key, string value) => 8 | $"-= {key} ----- =- {value}"; 9 | } 10 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/DocumentsAndFormattersExample/Formatters/StandardFormatter.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DocumentsAndFormattersExample.Formatters.Common; 2 | 3 | namespace BridgeLibrary.DocumentsAndFormattersExample.Formatters; 4 | 5 | public class StandardFormatter : IFormatter 6 | { 7 | public string Format(string key, string value) => 8 | $"{key}: {value}"; 9 | } 10 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BridgeLibrary.DevicesAndRemotesExample; 2 | using BridgeLibrary.DocumentsAndFormattersExample; 3 | using BridgeLibrary.MovieLicenseExample; 4 | using BuildingBlocks; 5 | 6 | namespace BridgeLibrary; 7 | 8 | public class Executor : PatternExecutor 9 | { 10 | public override string Name => "Bridge - Structural Pattern"; 11 | 12 | public override void Execute() 13 | { 14 | DevicesAndRemotesExecutor.Execute(); 15 | DocumentsAndFormattersExecutor.Execute(); 16 | MovieLicenseExecutor.Execute(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/MovieLicenseExample/Models/Enums/Discount.cs: -------------------------------------------------------------------------------- 1 | namespace BridgeLibrary.MovieLicenseExample.Models.Enums; 2 | 3 | public enum Discount 4 | { 5 | None, 6 | EarlyPayment, 7 | Senior, 8 | } 9 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/MovieLicenseExample/Models/Enums/LicenseType.cs: -------------------------------------------------------------------------------- 1 | namespace BridgeLibrary.MovieLicenseExample.Models.Enums; 2 | 3 | public enum LicenseType 4 | { 5 | OneDay, 6 | SevenDays, 7 | LifeLong, 8 | } 9 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Bridge/BridgeLibrary/MovieLicenseExample/Models/Enums/SpecialOffer.cs: -------------------------------------------------------------------------------- 1 | namespace BridgeLibrary.MovieLicenseExample.Models.Enums; 2 | 3 | public enum SpecialOffer 4 | { 5 | None, 6 | OneDayExtension, 7 | SevenDaysExtension, 8 | } 9 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/StructuralPatterns/Composite/CompositeLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/CompositeLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using CompositeLibrary.FileSystemExample; 3 | using CompositeLibrary.GiftExample; 4 | using CompositeLibrary.ShareholdersExample; 5 | 6 | namespace CompositeLibrary; 7 | 8 | public class Executor : PatternExecutor 9 | { 10 | public override string Name => "Composite - Structural Pattern"; 11 | 12 | public override void Execute() 13 | { 14 | FileSystemExecutor.Execute(); 15 | GiftExecutor.Execute(); 16 | ShareholdersExecutor.Execute(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/FileSystemExample/Common/FileSystemEntry.cs: -------------------------------------------------------------------------------- 1 | namespace CompositeLibrary.FileSystemExample.Common; 2 | 3 | public abstract class FileSystemEntry 4 | { 5 | protected FileSystemEntry(string name) 6 | { 7 | Name = name; 8 | } 9 | 10 | public string Name { get; } 11 | 12 | public abstract double GetSizeInMB(); 13 | } 14 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/FileSystemExample/File.cs: -------------------------------------------------------------------------------- 1 | using CompositeLibrary.FileSystemExample.Common; 2 | 3 | namespace CompositeLibrary.FileSystemExample; 4 | 5 | public class File : FileSystemEntry 6 | { 7 | public File(string name, double size) 8 | : base(name) 9 | { 10 | Size = size; 11 | } 12 | 13 | public double Size { get; } 14 | 15 | public override double GetSizeInMB() => Size; 16 | } 17 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/FileSystemExample/Folder.cs: -------------------------------------------------------------------------------- 1 | using CompositeLibrary.FileSystemExample.Common; 2 | 3 | namespace CompositeLibrary.FileSystemExample; 4 | 5 | public class Folder : FileSystemEntry 6 | { 7 | private readonly List _items; 8 | 9 | public Folder(string name) 10 | : base(name) 11 | { 12 | _items = new List(); 13 | } 14 | 15 | public void Add(FileSystemEntry entry) => _items.Add(entry); 16 | 17 | public void Remove(FileSystemEntry entry) => _items.Remove(entry); 18 | 19 | public override double GetSizeInMB() => _items.Sum(item => item.GetSizeInMB()); 20 | } 21 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/GiftExample/Common/Gift.cs: -------------------------------------------------------------------------------- 1 | namespace CompositeLibrary.GiftExample.Common; 2 | 3 | public abstract class Gift 4 | { 5 | protected readonly string _description; 6 | protected decimal _price; 7 | 8 | protected Gift(string description, decimal price) 9 | { 10 | _description = description; 11 | _price = price; 12 | } 13 | 14 | public abstract decimal CalculatePrice(); 15 | } 16 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/GiftExample/Common/IGiftOperations.cs: -------------------------------------------------------------------------------- 1 | namespace CompositeLibrary.GiftExample.Common; 2 | 3 | public interface IGiftOperations 4 | { 5 | void Add(Gift gift); 6 | void Remove(Gift gift); 7 | } 8 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/GiftExample/SimpleGift.cs: -------------------------------------------------------------------------------- 1 | using CompositeLibrary.GiftExample.Common; 2 | 3 | namespace CompositeLibrary.GiftExample; 4 | 5 | public class SimpleGift : Gift 6 | { 7 | public SimpleGift(string description, decimal price) 8 | : base(description, price) 9 | { 10 | } 11 | 12 | public override decimal CalculatePrice() 13 | { 14 | Console.WriteLine($"'{_description}' with the price of {_price:C}"); 15 | return _price; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/ShareholdersExample/After/Common/Shareholder.cs: -------------------------------------------------------------------------------- 1 | namespace CompositeLibrary.ShareholdersExample.After.Common; 2 | 3 | public abstract class Shareholder 4 | { 5 | public string Name { get; set; } = string.Empty; 6 | public virtual int NumberOfShares { get; set; } 7 | 8 | public abstract void PrintReport(); 9 | } 10 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/ShareholdersExample/After/Person.cs: -------------------------------------------------------------------------------- 1 | using CompositeLibrary.ShareholdersExample.After.Common; 2 | 3 | namespace CompositeLibrary.ShareholdersExample.After; 4 | 5 | public class Person : Shareholder 6 | { 7 | public override void PrintReport() => 8 | Console.WriteLine($"{Name} has {NumberOfShares} shares of the share capital."); 9 | } 10 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/ShareholdersExample/Before/Corporation.cs: -------------------------------------------------------------------------------- 1 | namespace CompositeLibrary.ShareholdersExample.Before; 2 | 3 | public class Corporation 4 | { 5 | public string Name { get; set; } = string.Empty; 6 | public List Shareholders { get; set; } = new(); 7 | } 8 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/ShareholdersExample/Before/Person.cs: -------------------------------------------------------------------------------- 1 | namespace CompositeLibrary.ShareholdersExample.Before; 2 | 3 | public class Person 4 | { 5 | public string Name { get; set; } = string.Empty; 6 | public int NumberOfShares { get; set; } 7 | 8 | public void PrintReport() => 9 | Console.WriteLine($"{Name} has {NumberOfShares} shares of the share capital."); 10 | } 11 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Composite/CompositeLibrary/ShareholdersExample/ShareholdersExecutor.cs: -------------------------------------------------------------------------------- 1 | using CompositeLibrary.ShareholdersExample.After; 2 | using CompositeLibrary.ShareholdersExample.Before; 3 | 4 | namespace CompositeLibrary.ShareholdersExample; 5 | 6 | public static class ShareholdersExecutor 7 | { 8 | public static void Execute() 9 | { 10 | BeforeExecutor.Execute(); 11 | AfterExecutor.Execute(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/StructuralPatterns/Decorator/DecoratorLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/DataStorageExample/Components/Common/IDataSource.cs: -------------------------------------------------------------------------------- 1 | namespace DecoratorLibrary.DataStorageExample.Components.Common; 2 | 3 | /// 4 | /// The component interface defines operations that can be altered by decorators. 5 | /// 6 | public interface IDataSource 7 | { 8 | void Write(string data); 9 | string Read(); 10 | void ClearContent(); 11 | } 12 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/DecoratorLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using DecoratorLibrary.DataStorageExample; 3 | using DecoratorLibrary.PancakeExample; 4 | 5 | namespace DecoratorLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Decorator - Structural Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | DataStorageExecutor.Execute(); 14 | PancakeExecutor.Execute(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/PancakeExample/Components/BigPancake.cs: -------------------------------------------------------------------------------- 1 | using DecoratorLibrary.PancakeExample.Components.Common; 2 | 3 | namespace DecoratorLibrary.PancakeExample.Components; 4 | 5 | public class BigPancake : Pancake 6 | { 7 | public BigPancake() 8 | { 9 | Description = "Big pancake"; 10 | } 11 | 12 | public override double CalculatePrice() => 10.0; 13 | } 14 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/PancakeExample/Components/Common/Pancake.cs: -------------------------------------------------------------------------------- 1 | namespace DecoratorLibrary.PancakeExample.Components.Common; 2 | 3 | public abstract class Pancake 4 | { 5 | public string Description { get; set; } = string.Empty; 6 | 7 | public abstract double CalculatePrice(); 8 | 9 | public virtual string GetDescriptionAndAddIns() => Description; 10 | } 11 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/PancakeExample/Components/SmallPancake.cs: -------------------------------------------------------------------------------- 1 | using DecoratorLibrary.PancakeExample.Components.Common; 2 | 3 | namespace DecoratorLibrary.PancakeExample.Components; 4 | 5 | public class SmallPancake : Pancake 6 | { 7 | public SmallPancake() 8 | { 9 | Description = "Small pancake"; 10 | } 11 | 12 | public override double CalculatePrice() => 6.0; 13 | } 14 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/PancakeExample/Decorators/Common/PancakeDecorator.cs: -------------------------------------------------------------------------------- 1 | using DecoratorLibrary.PancakeExample.Components.Common; 2 | 3 | namespace DecoratorLibrary.PancakeExample.Decorators.Common; 4 | 5 | public class PancakeDecorator : Pancake 6 | { 7 | private readonly Pancake _pancake; 8 | 9 | public PancakeDecorator(Pancake pancake) 10 | { 11 | _pancake = pancake; 12 | } 13 | 14 | public override double CalculatePrice() => _pancake.CalculatePrice(); 15 | 16 | public override string GetDescriptionAndAddIns() => $"{_pancake.GetDescriptionAndAddIns()}, {Description}"; 17 | } 18 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/PancakeExample/Decorators/MapleSyrup.cs: -------------------------------------------------------------------------------- 1 | using DecoratorLibrary.PancakeExample.Components.Common; 2 | using DecoratorLibrary.PancakeExample.Decorators.Common; 3 | 4 | namespace DecoratorLibrary.PancakeExample.Decorators; 5 | 6 | public class MapleSyrup : PancakeDecorator 7 | { 8 | public MapleSyrup(Pancake pancake) 9 | : base(pancake) 10 | { 11 | Description = "Maple syrup"; 12 | } 13 | 14 | public override double CalculatePrice() => base.CalculatePrice() + 1.0; 15 | } 16 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/PancakeExample/Decorators/MixedBerries.cs: -------------------------------------------------------------------------------- 1 | using DecoratorLibrary.PancakeExample.Components.Common; 2 | using DecoratorLibrary.PancakeExample.Decorators.Common; 3 | 4 | namespace DecoratorLibrary.PancakeExample.Decorators; 5 | 6 | public class MixedBerries : PancakeDecorator 7 | { 8 | public MixedBerries(Pancake pancake) 9 | : base(pancake) 10 | { 11 | Description = "Mixed berries"; 12 | } 13 | 14 | public override double CalculatePrice() => base.CalculatePrice() + 2.0; 15 | } 16 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/PancakeExample/Decorators/Nutella.cs: -------------------------------------------------------------------------------- 1 | using DecoratorLibrary.PancakeExample.Components.Common; 2 | using DecoratorLibrary.PancakeExample.Decorators.Common; 3 | 4 | namespace DecoratorLibrary.PancakeExample.Decorators; 5 | 6 | public class Nutella : PancakeDecorator 7 | { 8 | public Nutella(Pancake pancake) 9 | : base(pancake) 10 | { 11 | Description = "Nutella"; 12 | } 13 | 14 | public override double CalculatePrice() => base.CalculatePrice() + 0.7; 15 | } 16 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Decorator/DecoratorLibrary/PancakeExample/Decorators/WhippedCream.cs: -------------------------------------------------------------------------------- 1 | using DecoratorLibrary.PancakeExample.Components.Common; 2 | using DecoratorLibrary.PancakeExample.Decorators.Common; 3 | 4 | namespace DecoratorLibrary.PancakeExample.Decorators; 5 | 6 | public class WhippedCream : PancakeDecorator 7 | { 8 | public WhippedCream(Pancake pancake) 9 | : base(pancake) 10 | { 11 | Description = "Whipped cream"; 12 | } 13 | 14 | public override double CalculatePrice() => base.CalculatePrice() + 0.4; 15 | } 16 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/StructuralPatterns/Facade/FacadeLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using FacadeLibrary.MortgageExample; 3 | using FacadeLibrary.WeatherServiceExample; 4 | 5 | namespace FacadeLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Facade - Structural Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | MortgageExecutor.Execute(); 14 | WeatherServiceExecutor.Execute(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/FacadeLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/MortgageExample/Subsystem/Bank.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.MortgageExample.Subsystem; 2 | 3 | public class Bank 4 | { 5 | public bool IsUntrustworthy(Customer customer, decimal loanAmount) 6 | { 7 | Console.WriteLine($"Check credit-worthiness for the customer: {customer.Name}"); 8 | 9 | return false; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/MortgageExample/Subsystem/Credit.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.MortgageExample.Subsystem; 2 | 3 | public class Credit 4 | { 5 | public bool HasBadCredit(Customer customer) 6 | { 7 | Console.WriteLine($"Check credit for the customer: {customer.Name}"); 8 | 9 | return false; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/MortgageExample/Subsystem/Customer.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.MortgageExample.Subsystem; 2 | 3 | public class Customer 4 | { 5 | public string Name { get; set; } = string.Empty; 6 | } 7 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/MortgageExample/Subsystem/CustomerService.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.MortgageExample.Subsystem; 2 | 3 | public class CustomerService 4 | { 5 | // Naive implementation. 6 | // In a real life scenario we would need some customer registry. 7 | // There may be multiple customers with the same name. 8 | public Customer Find(string name) => 9 | new() { Name = name }; 10 | } 11 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/MortgageExample/Subsystem/Loan.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.MortgageExample.Subsystem; 2 | 3 | public class Loan 4 | { 5 | public bool HasBadLoans(Customer customer) 6 | { 7 | Console.WriteLine($"Check loans for the customer: {customer.Name}"); 8 | 9 | return false; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/WeatherServiceExample/After/TemperatureFacade/LocalTemperature.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.WeatherServiceExample.After.TemperatureFacade; 2 | 3 | public class LocalTemperature 4 | { 5 | public double Celsius { get; set; } 6 | public double Fahrenheit { get; set; } 7 | public string City { get; set; } = string.Empty; 8 | public string State { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/WeatherServiceExample/Service/Coordinates.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.WeatherServiceExample.Service; 2 | 3 | public class Coordinates 4 | { 5 | public double Latitude { get; set; } 6 | public double Longitude { get; set; } 7 | } 8 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/WeatherServiceExample/Service/GeoLookupService.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.WeatherServiceExample.Service; 2 | 3 | public class GeoLookupService 4 | { 5 | public Coordinates FindCoordinates(string zipCode) => 6 | new() 7 | { 8 | Latitude = 43.676422, 9 | Longitude = -116.278025, 10 | }; 11 | 12 | public string FindCity(string zipCode) => "Boise"; 13 | 14 | public string FindState(string zipCode) => "Idaho"; 15 | } 16 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/WeatherServiceExample/Service/TemperatureConverter.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.WeatherServiceExample.Service; 2 | 3 | public class TemperatureConverter 4 | { 5 | public double ConvertFahrenheitToCelsius(double degrees) => (degrees - 32) / 9.0 * 5.0; 6 | } 7 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/WeatherServiceExample/Service/WeatherService.cs: -------------------------------------------------------------------------------- 1 | namespace FacadeLibrary.WeatherServiceExample.Service; 2 | 3 | public class WeatherService 4 | { 5 | public double GetTemperatureFahrenheit(double latitude, double longitude) => 86.5; 6 | } 7 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Facade/FacadeLibrary/WeatherServiceExample/WeatherServiceExecutor.cs: -------------------------------------------------------------------------------- 1 | using FacadeLibrary.WeatherServiceExample.After; 2 | using FacadeLibrary.WeatherServiceExample.Before; 3 | 4 | namespace FacadeLibrary.WeatherServiceExample; 5 | 6 | public static class WeatherServiceExecutor 7 | { 8 | public static void Execute() 9 | { 10 | BeforeExecutor.Execute(); 11 | AfterExecutor.Execute(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Flyweight/FlyweightLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/StructuralPatterns/Flyweight/FlyweightLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/StructuralPatterns/Flyweight/FlyweightLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using FlyweightLibrary.DotNetStringExample; 3 | using FlyweightLibrary.ForestExample; 4 | 5 | namespace FlyweightLibrary; 6 | 7 | public class Executor : PatternExecutor 8 | { 9 | public override string Name => "Flyweight - Structural Pattern"; 10 | 11 | public override void Execute() 12 | { 13 | DotNetStringExecutor.Execute(); 14 | ForestExecutor.Execute(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/StructuralPatterns/Flyweight/FlyweightLibrary/FlyweightLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Flyweight/FlyweightLibrary/ForestExample/Tree.cs: -------------------------------------------------------------------------------- 1 | namespace FlyweightLibrary.ForestExample; 2 | 3 | public class Tree 4 | { 5 | private readonly double _latitude; 6 | private readonly double _longitude; 7 | private readonly TreeType _treeType; 8 | 9 | public Tree(double latitude, double longitude, TreeType treeType) 10 | { 11 | _latitude = latitude; 12 | _longitude = longitude; 13 | _treeType = treeType; 14 | } 15 | 16 | public void Render() => _treeType.Render(_latitude, _longitude); 17 | } 18 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/Assets/pattern-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nemanjarogic/DesignPatternsLibrary/aae9bbd5d72bf0488950d55e19de7006786533fa/src/StructuralPatterns/Proxy/ProxyLibrary/Assets/pattern-structure.png -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/CachingProxyExample/Common/IYoutubeOperations.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.CachingProxyExample.Common; 2 | 3 | /// 4 | /// The interface of a remote service. 5 | /// 6 | public interface IYoutubeOperations 7 | { 8 | VideoMetadata GetVideoMetadata(int id); 9 | Video DownloadVideo(int id); 10 | IEnumerable ShowHomepage(); 11 | } 12 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/CachingProxyExample/Common/Video.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.CachingProxyExample.Common; 2 | 3 | public class Video 4 | { 5 | public int Id { get; set; } 6 | public string Content { get; set; } = string.Empty; 7 | } 8 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/CachingProxyExample/Common/VideoMetadata.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.CachingProxyExample.Common; 2 | 3 | public class VideoMetadata 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } = string.Empty; 7 | public string Description { get; set; } = string.Empty; 8 | } 9 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/Executor.cs: -------------------------------------------------------------------------------- 1 | using BuildingBlocks; 2 | using ProxyLibrary.CachingProxyExample; 3 | using ProxyLibrary.LoggingProxyExample; 4 | using ProxyLibrary.ProtectionProxyExample; 5 | 6 | namespace ProxyLibrary; 7 | 8 | public class Executor : PatternExecutor 9 | { 10 | public override string Name => "Proxy - Structural Pattern"; 11 | 12 | public override void Execute() 13 | { 14 | CachingProxyExecutor.Execute(); 15 | LoggingProxyExecutor.Execute(); 16 | ProtectionProxyExecutor.Execute(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/LoggingProxyExample/Client.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.LoggingProxyExample; 2 | 3 | /// 4 | /// The client code is supposed to work with all objects (both subjects and proxies) 5 | /// via the Subject interface in order to support both real subjects and proxies. 6 | /// In real life, however, clients mostly work with their real subjects directly. 7 | /// In this case, to implement the pattern more easily, you can extend your proxy from the real subject's class. 8 | /// 9 | public class Client 10 | { 11 | public void PerformOperation(ISubject subject) => subject.Request(); 12 | } 13 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/LoggingProxyExample/ISubject.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.LoggingProxyExample; 2 | 3 | /// 4 | /// The Subject interface declares common operations for both and the . 5 | /// As long as the client works with using this 6 | /// interface, you'll be able to pass it a proxy instead of a real subject. 7 | /// 8 | public interface ISubject 9 | { 10 | void Request(); 11 | } 12 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/LoggingProxyExample/RealSubject.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.LoggingProxyExample; 2 | 3 | /// 4 | /// The RealSubject contains some core business logic. 5 | /// Usually, RealSubjects are capable of doing some useful work which may also be 6 | /// very slow or sensitive - e.g. correcting input data. 7 | /// A Proxy can solve these issues without any changes to the RealSubject's code. 8 | /// 9 | public class RealSubject : ISubject 10 | { 11 | public void Request() => Console.WriteLine("RealSubject: Handling Request."); 12 | } 13 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/ProtectionProxyExample/Employee.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.ProtectionProxyExample; 2 | 3 | public class Employee 4 | { 5 | public Employee(string username, string password, Role role) 6 | { 7 | Username = username; 8 | Password = password; 9 | Role = role; 10 | } 11 | 12 | public string Username { get; set; } 13 | public string Password { get; set; } 14 | public Role Role { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/ProtectionProxyExample/ISharedFolder.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.ProtectionProxyExample; 2 | 3 | public interface ISharedFolder 4 | { 5 | void Access(); 6 | } 7 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/ProtectionProxyExample/Role.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.ProtectionProxyExample; 2 | 3 | public enum Role 4 | { 5 | Worker, 6 | Manager, 7 | CEO, 8 | } 9 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/ProtectionProxyExample/SharedFolder.cs: -------------------------------------------------------------------------------- 1 | namespace ProxyLibrary.ProtectionProxyExample; 2 | 3 | public class SharedFolder : ISharedFolder 4 | { 5 | public void Access() => Console.WriteLine("The shared folder is opened."); 6 | } 7 | -------------------------------------------------------------------------------- /src/StructuralPatterns/Proxy/ProxyLibrary/ProxyLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | --------------------------------------------------------------------------------