├── DevOfSwSuppWithOOP ├── DesignPatterns │ ├── Structural │ │ ├── Most.png │ │ ├── Proxy.png │ │ ├── Adapter.png │ │ ├── Fasada.png │ │ ├── Dekorater.png │ │ ├── Flyweight.png │ │ ├── Kompozit.png │ │ ├── Solutions │ │ │ ├── Solution2.cs │ │ │ └── Solution1.cs │ │ └── Examples │ │ │ ├── Adapter.cs │ │ │ ├── Bridge.cs │ │ │ ├── Flyweight.cs │ │ │ ├── Composite.cs │ │ │ ├── Decorator.cs │ │ │ ├── Facade.cs │ │ │ └── Proxy.cs │ ├── Creational │ │ ├── Builder.png │ │ ├── Prototype.png │ │ ├── Singleton.png │ │ ├── AbstractFactory.png │ │ ├── MethodFactory.png │ │ ├── Solutions │ │ │ ├── Solution2.cs │ │ │ └── Solution1.cs │ │ └── Examples │ │ │ ├── Prototip.cs │ │ │ ├── MethodFactory.cs │ │ │ ├── Singleton.cs │ │ │ ├── ApstractFactory.cs │ │ │ └── Builder.cs │ └── Behavioural │ │ ├── Images │ │ ├── Memento.png │ │ ├── Visitor.png │ │ ├── Iterator.png │ │ ├── Observer.png │ │ ├── Strategy.png │ │ ├── NullObject.png │ │ ├── TemplateMethod.png │ │ └── ChainOfResponsibility.png │ │ ├── Solutions │ │ ├── Solution1.cs │ │ ├── Solution2.cs │ │ └── Solutions3.cs │ │ └── Examples │ │ ├── TemplateMethod.cs │ │ ├── Iterator.cs │ │ ├── Memento.cs │ │ ├── Observer.cs │ │ ├── Strategy.cs │ │ └── ChainOfResponsibility.cs ├── OOP │ ├── Soultions │ │ └── BankingSystem │ │ │ ├── ITransaction.cs │ │ │ ├── Person.cs │ │ │ ├── IBankAccount.cs │ │ │ ├── Transaction.cs │ │ │ ├── TransactionTransfer.cs │ │ │ ├── Customer.cs │ │ │ ├── Bank.cs │ │ │ └── ClientCode.cs │ └── README.hr.md ├── Program.cs ├── DevOfSwSuppWithOOP.csproj ├── CleanCode │ ├── Solutions │ │ ├── Refactoring │ │ │ ├── Solution3.cs │ │ │ ├── Solution4.cs │ │ │ ├── Solution1.cs │ │ │ ├── Solution5.cs │ │ │ └── Solution2.cs │ │ └── Renaming │ │ │ ├── Solution3.cs │ │ │ ├── Solution5.cs │ │ │ ├── Solution1.cs │ │ │ ├── Solution2.cs │ │ │ └── Solution4.cs │ └── README.hr.md ├── SOLID │ └── README.hr.md └── CodeSmellsAndAntipatterns │ └── README.hr.md ├── LICENSE.txt ├── DevOfSwSuppWithOOP.sln ├── .gitattributes ├── README.md ├── .gitignore └── README.z.md /DevOfSwSuppWithOOP/DesignPatterns/Structural/Most.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Structural/Most.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Structural/Proxy.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Builder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Creational/Builder.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Adapter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Structural/Adapter.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Fasada.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Structural/Fasada.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Prototype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Creational/Prototype.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Singleton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Creational/Singleton.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Dekorater.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Structural/Dekorater.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Flyweight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Structural/Flyweight.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Kompozit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Structural/Kompozit.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Memento.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Memento.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Visitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Visitor.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/AbstractFactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Creational/AbstractFactory.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/MethodFactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Creational/MethodFactory.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Iterator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Iterator.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Observer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Observer.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Strategy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/Strategy.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/NullObject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/NullObject.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/TemplateMethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/TemplateMethod.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/Soultions/BankingSystem/ITransaction.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.OOPBankingSystem{ 2 | public interface ITransaction{ 3 | void ExecuteTransaction(); 4 | } 5 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/Program.cs: -------------------------------------------------------------------------------- 1 | public static class Program{ 2 | public static void Main(string[] args){ 3 | DevOfSwSuppWithOOP.DesignPatterns.Behavioral.Solution3.ClientCode.Run(); 4 | } 5 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/ChainOfResponsibility.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FC122/DevOfSwSuppWithOOP/HEAD/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Images/ChainOfResponsibility.png -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/Soultions/BankingSystem/Person.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.OOPBankingSystem{ 2 | public abstract class Person{ 3 | public string? FirstName { get; set; } 4 | public string? LastName { get; set; } 5 | } 6 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/Soultions/BankingSystem/IBankAccount.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.OOPBankingSystem{ 2 | public interface IBankAccount{ 3 | void Deposit(decimal amount); 4 | void Withdraw(decimal amount); 5 | void DisplayAccountInfo(); 6 | } 7 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DevOfSwSuppWithOOP.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/Soultions/BankingSystem/Transaction.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.OOPBankingSystem{ 2 | public abstract class Transaction : ITransaction{ 3 | public decimal Amount { get; set; } 4 | public DateTime Timestamp { get; set; } 5 | 6 | public abstract void ExecuteTransaction(); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/Soultions/BankingSystem/TransactionTransfer.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.OOPBankingSystem{ 2 | public class TransactionTransfer : Transaction{ 3 | public int SourceAccountNumber { get; set; } 4 | public int DestinationAccountNumber { get; set; } 5 | 6 | public override void ExecuteTransaction(){ 7 | Console.WriteLine($"Transfer {Amount} from account {SourceAccountNumber} to account {DestinationAccountNumber}"); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/Soultions/BankingSystem/Customer.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.OOPBankingSystem{ 2 | public class Customer : Person, IBankAccount{ 3 | public int AccountNumber { get; set; } 4 | public decimal Balance { get; set; } 5 | 6 | public void Deposit(decimal amount){ 7 | Balance += amount; 8 | } 9 | 10 | public void Withdraw(decimal amount){ 11 | if (Balance >= amount){ 12 | Balance -= amount; 13 | }else{ 14 | Console.WriteLine("Insufficient funds."); 15 | } 16 | } 17 | 18 | public void DisplayAccountInfo(){ 19 | Console.WriteLine($"Account Holder: {FirstName} {LastName}"); 20 | Console.WriteLine($"Account Number: {AccountNumber}"); 21 | Console.WriteLine($"Balance: {Balance}"); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Refactoring/Solution3.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Refactoring.Solution3{ 2 | class Counter 3 | { 4 | public static int CountDistinctNumbers(List array) 5 | { 6 | int counter = 0; 7 | for (int i = 0; i < array.Count; i++) 8 | { 9 | if (CountOccurrence(array, array[i]) == 1) 10 | { 11 | counter++; 12 | } 13 | } 14 | return counter; 15 | } 16 | 17 | public static int CountOccurrence(List array, int number) 18 | { 19 | int occurrence = 0; 20 | for (int j = 0; j < array.Count; j++) 21 | { 22 | if (number == array[j]) 23 | { 24 | occurrence++; 25 | } 26 | } 27 | return occurrence; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/Soultions/BankingSystem/Bank.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.OOPBankingSystem{ 2 | public class Bank{ 3 | private List customers; 4 | private List transactions; 5 | public Bank(){ 6 | customers = new List(); 7 | transactions = new List(); 8 | } 9 | 10 | public void AddCustomer(Customer customer){ 11 | customers.Add(customer); 12 | } 13 | 14 | public void RemoveCustomer(Customer customer){ 15 | customers.Remove(customer); 16 | } 17 | 18 | public Customer FindCustomerByAccountNumber(int accountNumber){ 19 | return customers.Find(c => c.AccountNumber == accountNumber) ?? new Customer(); 20 | } 21 | 22 | public void ExecuteTransaction(Transaction transaction){ 23 | transaction.ExecuteTransaction(); 24 | transactions.Add(transaction); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Refactoring/Solution4.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Refactoring.Solution4{ 2 | class DrugiZadatak 3 | { 4 | public static List CountUniqeCharacters(string text) 5 | { 6 | List characters = new List(); 7 | for (int i = 0; i < text.Length; i++) 8 | { 9 | if (CountCharacterOccurrence(text, text[i]) == 1) 10 | { 11 | characters.Add(text[i]); 12 | } 13 | } 14 | return characters; 15 | } 16 | 17 | public static int CountCharacterOccurrence(string text, char character) 18 | { 19 | int count = 0; 20 | for (int j = 0; j < text.Length; j++) 21 | { 22 | if (character == text[j]) 23 | { 24 | count++; 25 | } 26 | } 27 | return count; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Refactoring/Solution1.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Refactoring.Solution1{ 2 | public class VectorScaler 3 | { 4 | public void ScaleVectorByEuclideanNorm(double[] vector) 5 | { 6 | double vectorNorm = CalculateEuclideanNorm(vector); 7 | for (int i = 0; i < vector.Length; i++) 8 | vector[i] /= vectorNorm; 9 | } 10 | 11 | double CalculateEuclideanNorm(double[] vector) 12 | { 13 | double sumOfPowers = 0; 14 | for (int i = 0; i < vector.Length; i++) 15 | sumOfPowers += Math.Pow(vector[i], 2); 16 | return Math.Sqrt(sumOfPowers); 17 | } 18 | } 19 | 20 | public static class ClientCode 21 | { 22 | public static void Run() 23 | { 24 | VectorScaler vectorScaler= new VectorScaler(); 25 | double[] vector = [0, 1, 2, 3, 4]; 26 | vectorScaler.ScaleVectorByEuclideanNorm(vector); 27 | foreach(double d in vector){ 28 | Console.WriteLine(d); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Refactoring/Solution5.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Refactoring.Solution5{ 2 | class PalindromeCalculator 3 | { 4 | public List FindPalindromes(List strings) 5 | { 6 | List palindromes = new List(); 7 | 8 | if (strings == null) 9 | { 10 | return palindromes; 11 | } 12 | 13 | foreach (string str in strings) 14 | { 15 | if (IsPalindrome(str)) 16 | { 17 | palindromes.Add(str); 18 | } 19 | } 20 | 21 | return palindromes; 22 | } 23 | 24 | private bool IsPalindrome(string str) 25 | { 26 | if (string.IsNullOrEmpty(str)) 27 | { 28 | return false; 29 | } 30 | 31 | string trimmedString = str.Replace(" ", "").ToLower(); 32 | string reversedString = new string(trimmedString.Reverse().ToArray()); 33 | 34 | return trimmedString.Equals(reversedString); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Refactoring/Solution2.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Refactoring.Solution2{ 2 | class Calculator 3 | { 4 | public List CalculateAverages(List arrays) 5 | { 6 | List averages = new List(); 7 | foreach (double[] array in arrays) 8 | { 9 | averages.Add(CalculateAverage(array)); 10 | } 11 | return averages; 12 | } 13 | 14 | public double CalculateAverage(double[] array) 15 | { 16 | double average = 0; 17 | for (int i = 0; i < array.Length; i++) 18 | { 19 | average += array[i]; 20 | } 21 | return average / array.Length; 22 | } 23 | } 24 | 25 | public static class ClientCode 26 | { 27 | public static void Run() 28 | { 29 | Calculator calculator= new Calculator(); 30 | List avereages = calculator.CalculateAverages(new List([[1,2,3,4],[1,2,3,5]])); 31 | avereages.ForEach(a => 32 | Console.WriteLine($"{a}") 33 | ); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.9.34723.18 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevOfSwSuppWithOOP", "DevOfSwSuppWithOOP\DevOfSwSuppWithOOP.csproj", "{CD2FBBED-78FF-4EE8-B032-C13E45DE09CC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {CD2FBBED-78FF-4EE8-B032-C13E45DE09CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {CD2FBBED-78FF-4EE8-B032-C13E45DE09CC}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {CD2FBBED-78FF-4EE8-B032-C13E45DE09CC}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {CD2FBBED-78FF-4EE8-B032-C13E45DE09CC}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {314946D8-BFBE-4F4D-A035-118D790EDA19} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Renaming/Solution3.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Renaming.Solution3{ 2 | class RandomGenerator 3 | { 4 | private static RandomGenerator randomGenerator; 5 | private Random random; 6 | 7 | private RandomGenerator() 8 | { 9 | random = new Random(); 10 | } 11 | public static RandomGenerator GetInstance() 12 | { 13 | if (randomGenerator == null) 14 | { 15 | randomGenerator = new RandomGenerator(); 16 | } 17 | return randomGenerator; 18 | } 19 | 20 | public int GenerateInt() 21 | { 22 | return random.Next(); 23 | } 24 | 25 | public int GenerateInt(int a, int b) 26 | { 27 | return random.Next() % (b - a + 1); 28 | } 29 | 30 | public double GenerateDouble(double a, double b) 31 | { 32 | return a + (random.NextDouble() * (b - a)); 33 | } 34 | } 35 | 36 | public static class ClientCode 37 | { 38 | public static void Run() 39 | { 40 | Console.WriteLine(RandomGenerator.GetInstance().GenerateInt()); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Renaming/Solution5.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Renaming.Solution5{ 2 | public class Location 3 | { 4 | public DateTime CreatedAt { get; private set; } 5 | public double Latitude { get; private set; } 6 | public double Longitude { get; private set; } 7 | 8 | public Location(double latitude, double longitude) 9 | { 10 | // Constructor implementation 11 | } 12 | } 13 | 14 | public class PathManager 15 | { 16 | private List pathPoints; 17 | 18 | public PathManager() 19 | { 20 | pathPoints = new List(); 21 | } 22 | 23 | public void AddPathPoint(Location point) 24 | { 25 | pathPoints.Add(point); 26 | } 27 | 28 | public void RemovePathPoint(Location point) 29 | { 30 | pathPoints.Remove(point); 31 | } 32 | } 33 | 34 | public static class ClientCode 35 | { 36 | public static void Run() 37 | { 38 | PathManager pathManager = new PathManager(); 39 | 40 | pathManager.AddPathPoint(new Location(0,0)); 41 | pathManager.AddPathPoint(new Location(1,1)); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Renaming/Solution1.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Renaming.Solution1{ 2 | enum Shape { Circle, Square } 3 | class Cake 4 | { 5 | public int LayersCount { get; private set; } 6 | public Shape Shape { get; private set; } 7 | public bool HasFrosting { get; private set; } 8 | public Cake(int layersCount, Shape shape, bool hasFrosting) 9 | { 10 | LayersCount = layersCount; 11 | Shape = shape; 12 | HasFrosting = hasFrosting; 13 | } 14 | } 15 | 16 | class CakeFactory 17 | { 18 | public static Cake? Create(string type) 19 | { 20 | switch (type) 21 | { 22 | case "standard": return new Cake(2, Shape.Square, false); 23 | case "fancy": return new Cake(4, Shape.Circle, false); 24 | case "wedding": return new Cake(6, Shape.Circle, true); 25 | default: return null; 26 | } 27 | } 28 | } 29 | 30 | public static class ClientCode 31 | { 32 | public static void Run() 33 | { 34 | Cake cake = CakeFactory.Create("standard"); 35 | Console.WriteLine($"{cake.Shape}, {cake.LayersCount}, {cake.HasFrosting}"); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/Soultions/BankingSystem/ClientCode.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.OOPBankingSystem{ 2 | public static class ClientCode{ 3 | public static void Run(){ 4 | Bank bank = new(); 5 | 6 | Customer customer1 = new Customer 7 | { 8 | FirstName = "John", 9 | LastName = "Doe", 10 | AccountNumber = 123456, 11 | Balance = 1000 12 | }; 13 | 14 | Customer customer2 = new Customer 15 | { 16 | FirstName = "Jane", 17 | LastName = "Smith", 18 | AccountNumber = 654321, 19 | Balance = 2000 20 | }; 21 | 22 | bank.AddCustomer(customer1); 23 | bank.AddCustomer(customer2); 24 | 25 | customer1.DisplayAccountInfo(); 26 | customer2.DisplayAccountInfo(); 27 | 28 | TransactionTransfer transfer = new() 29 | { 30 | Amount = 500, 31 | SourceAccountNumber = customer1.AccountNumber, 32 | DestinationAccountNumber = customer2.AccountNumber 33 | }; 34 | 35 | bank.ExecuteTransaction(transfer); 36 | 37 | customer1.DisplayAccountInfo(); 38 | customer2.DisplayAccountInfo(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Renaming/Solution2.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Renaming.Solution2{ 2 | class Product 3 | { 4 | public string Name { get; private set; } 5 | public string Price { get; private set; } 6 | public bool IsStocked { get; set; } 7 | 8 | public Product(string name, string price) 9 | { 10 | Name = name; 11 | Price = price; 12 | IsStocked = false; 13 | } 14 | } 15 | 16 | class Inventory 17 | { 18 | List products; 19 | 20 | public Inventory(List products) 21 | { 22 | this.products = products; 23 | } 24 | 25 | public void Restock(Product outOfStockProduct) 26 | { 27 | foreach (Product product in products) 28 | { 29 | if (outOfStockProduct == product) 30 | product.IsStocked = true; 31 | } 32 | } 33 | 34 | public void RemoveAllOutOfStockProducts() 35 | { 36 | products.RemoveAll(product => product.IsStocked == false); 37 | } 38 | } 39 | 40 | public static class ClientCode 41 | { 42 | public static void Run() 43 | { 44 | Inventory inventory = new Inventory([new Product("Paper", "22")]); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/Solutions/Renaming/Solution4.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.CleanCode.Renaming.Solution4{ 2 | public class Note 3 | { 4 | public string Title { get; set; } 5 | public string Text { get; set; } 6 | public DateTime Date { get; private set; } 7 | 8 | public Note(string title, string text) 9 | { 10 | Title = title; 11 | Text = text; 12 | Date = DateTime.Now; 13 | } 14 | } 15 | 16 | public class Notebook 17 | { 18 | public string Author { get; private set; } 19 | public List notes; 20 | 21 | public Notebook(string author) 22 | { 23 | Author = author; 24 | notes = new List(); 25 | } 26 | 27 | public void AddNote(Note note) 28 | { 29 | notes.Add(note); 30 | } 31 | } 32 | 33 | public static class ClientCode 34 | { 35 | public static void Run() 36 | { 37 | Notebook notebook = new Notebook("Bruno Bajić"); 38 | notebook.AddNote(new Note("Hello World", "Pls Help Im In the Watter")); 39 | notebook.AddNote(new Note("Zorja Večernja", "Zora je svanula")); 40 | 41 | notebook.notes.ForEach(note => Console.WriteLine($"{note.Title}, {note.Text}\n")); 42 | 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Solutions/Solution2.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Solution2{ 2 | public interface Coffee { 3 | double GetCost(); 4 | String GetDescription(); 5 | } 6 | 7 | public class Espresso: Coffee { 8 | 9 | public double GetCost() { 10 | return 1.99; 11 | } 12 | 13 | public String GetDescription() { 14 | return "Espresso"; 15 | } 16 | } 17 | 18 | public abstract class CoffeeDecorator: Coffee { 19 | protected Coffee coffee; 20 | 21 | public CoffeeDecorator(Coffee coffee) { 22 | this.coffee = coffee; 23 | } 24 | 25 | public double GetCost() 26 | { 27 | return coffee.GetCost(); 28 | } 29 | 30 | public string GetDescription() 31 | { 32 | return coffee.GetDescription(); 33 | } 34 | } 35 | 36 | public class Milk: CoffeeDecorator { 37 | 38 | public Milk(Coffee coffee):base(coffee){} 39 | 40 | public double GetCost() { 41 | return base.GetCost() + 0.50; 42 | } 43 | 44 | public String GetDescription() { 45 | return base.GetDescription() + ", Milk"; 46 | } 47 | } 48 | 49 | public static class ClientCode{ 50 | public static void Run(){ 51 | Coffee myCoffee = new Milk(new Espresso()); 52 | Console.WriteLine("Description: " + myCoffee.GetDescription()); 53 | Console.WriteLine("Cost: $" + myCoffee.GetCost()); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Solutions/Solution1.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.Solution1{ 2 | public interface Channel{ 3 | public void Add(INotifiable notifiable); 4 | public void Remove(INotifiable notifiable); 5 | public void Notify(string message); 6 | } 7 | 8 | public interface INotifiable{ 9 | public void PushNotification(string message); 10 | } 11 | 12 | public class User : INotifiable 13 | { 14 | public void PushNotification(string message) 15 | { 16 | Console.WriteLine(message); 17 | } 18 | } 19 | 20 | public class Creator : Channel 21 | { 22 | List notifiables; 23 | public Creator(){ 24 | notifiables = new List(); 25 | } 26 | 27 | public void Add(INotifiable notifiable) 28 | { 29 | notifiables.Add(notifiable); 30 | } 31 | 32 | public void Notify(string message) 33 | { 34 | notifiables.ForEach(notifiable=>{ 35 | notifiable.PushNotification(message); 36 | }); 37 | } 38 | 39 | public void Remove(INotifiable notifiable) 40 | { 41 | notifiables.Remove(notifiable); 42 | } 43 | } 44 | 45 | public static class ClientCode{ 46 | public static void Run(string[] args){ 47 | Creator creator= new Creator(); 48 | creator.Add(new User()); 49 | creator.Add(new User()); 50 | creator.Notify("Hello Subs"); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Solutions/Solution1.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Solution1{ 2 | interface IPackable{ 3 | public void Pack(); 4 | } 5 | 6 | class Item : IPackable 7 | { 8 | string name; 9 | public Item(string name){ 10 | this.name = name; 11 | } 12 | public void Pack() 13 | { 14 | Console.WriteLine($"Pack item {name}"); 15 | } 16 | } 17 | 18 | class Package:IPackable{ 19 | string name; 20 | List packables; 21 | public Package(string name){ 22 | this.name=name; 23 | packables = new List(); 24 | } 25 | 26 | public void Add(IPackable packable){ 27 | packables.Add(packable); 28 | } 29 | 30 | public void Remove(IPackable packable){ 31 | packables.Remove(packable); 32 | } 33 | 34 | public void Pack(){ 35 | Console.WriteLine($"In {name} packing these items:"); 36 | packables.ForEach(packable=>{ 37 | packable.Pack(); 38 | }); 39 | } 40 | } 41 | 42 | public static class ClientCode{ 43 | public static void Run(){ 44 | Item lamp = new Item("lamp"); 45 | Item glass = new Item("glass"); 46 | Package smallPackage = new Package("smallPackage"); 47 | smallPackage.Add(glass); 48 | smallPackage.Add(lamp); 49 | Item speakers = new Item("speakers"); 50 | Package bigPackage = new Package("bigPackage"); 51 | bigPackage.Add(smallPackage); 52 | bigPackage.Add(speakers); 53 | bigPackage.Pack(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Solutions/Solution2.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Creational.Solution2{ 2 | //MethodFactory 3 | public class WebElement{ 4 | string name; 5 | public WebElement(string name){ 6 | Console.WriteLine($"Found {name}"); 7 | this.name = name; 8 | } 9 | public void Click(){ 10 | Console.WriteLine($"Clicked {name}"); 11 | } 12 | } 13 | 14 | public interface LoginPage{ 15 | public WebElement loginButton(); 16 | public WebElement usernameInput(); 17 | public WebElement passwordInput(); 18 | } 19 | 20 | public class ChromeLoginPage:LoginPage{ 21 | public WebElement loginButton(){return new WebElement("#LoginButton");} 22 | public WebElement usernameInput(){ return new WebElement("#userInput");} 23 | public WebElement passwordInput(){return new WebElement("#passwordElement");} 24 | } 25 | 26 | public abstract class LoginPageFactory{ 27 | public abstract LoginPage CreatePage(); 28 | } 29 | 30 | public class ChromeLoginPageFactory:LoginPageFactory{ 31 | public override LoginPage CreatePage(){ 32 | return new ChromeLoginPage(); 33 | } 34 | } 35 | 36 | public static class ClientCode 37 | { 38 | public static void Run() 39 | { 40 | //Kad želimo da kod radi za firefox, napravimo novi page i novu tvornicu 41 | LoginPageFactory loginPageFactory= new ChromeLoginPageFactory(); 42 | //ne zanimam nas kako se page stvara tj. instancira 43 | LoginPage loginPage = loginPageFactory.CreatePage(); 44 | //za bilo koji page koji prati apstrakcije Click ce raditi 45 | loginPage.loginButton().Click(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Solutions/Solution1.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Creational.Solution1{ 2 | //Builder 3 | public class Mail{ 4 | public string Subject {get;set;} 5 | public string Content {get;set;} 6 | public string Recipient {get;set;} 7 | public string Attachments {get;set;} 8 | } 9 | 10 | public interface IMailConstructor{ 11 | public IMailConstructor AddSubject(string subject); 12 | public IMailConstructor AddContent(string content); 13 | public IMailConstructor AddRecipient(string recipient); 14 | public IMailConstructor AddAttachments(string attachments); 15 | public IMailConstructor Reset(); 16 | public Mail Construct(); 17 | } 18 | 19 | public class MailConstructor: IMailConstructor{ 20 | Mail mail; 21 | public MailConstructor() { 22 | mail = new Mail(); 23 | } 24 | 25 | public IMailConstructor AddSubject(string subject){ 26 | mail.Subject = subject; 27 | return this; 28 | } 29 | 30 | public IMailConstructor AddContent(string content){ 31 | mail.Content = content; 32 | return this; 33 | } 34 | 35 | public IMailConstructor AddRecipient(string recipient){ 36 | mail.Recipient = recipient; 37 | return this; 38 | } 39 | 40 | public IMailConstructor AddAttachments(string recipient){ 41 | mail.Recipient= recipient; 42 | return this; 43 | } 44 | 45 | public IMailConstructor Reset(){ 46 | mail = new Mail(); 47 | return this; 48 | } 49 | 50 | public Mail Construct(){ 51 | return mail; 52 | } 53 | 54 | } 55 | 56 | public class SMTP { 57 | IMailConstructor mailConstructor; 58 | public SMTP(IMailConstructor mailConstructor) { 59 | this.mailConstructor = mailConstructor; 60 | } 61 | 62 | public void SendNoReplyMail(){ 63 | mailConstructor 64 | .AddSubject("No Reply") 65 | .AddContent("Hello World") 66 | .Construct(); 67 | //Sending logic here 68 | } 69 | } 70 | 71 | public static class ClientCode 72 | { 73 | public static void Run() 74 | { 75 | SMTP smtp = new SMTP(new MailConstructor()); 76 | smtp.SendNoReplyMail(); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Examples/Adapter.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Adapter{ 2 | 3 | namespace Problem 4 | { 5 | public interface ILogger{ 6 | void Log(string message); 7 | } 8 | 9 | public class ConsoleLogger : ILogger 10 | { 11 | public void Log(string message) 12 | { 13 | Console.WriteLine(message); 14 | } 15 | } 16 | 17 | //Pravimo se da je ovo vanjska klasa i nemožemo ju mjenjat 18 | public class FilerLoggerService{ 19 | public void LogToFile(string message){ 20 | Console.WriteLine($"Logging message to file. Message:{message}"); 21 | } 22 | } 23 | 24 | //ConsoleLogger više ne žeilmo, kako ćemo 25 | //omogućiti Klijentskom kodu da koristit servisnu klasu 26 | // preko ILogger sučelja 27 | 28 | public static class ClientCode 29 | { 30 | public static void Run() 31 | { 32 | ILogger logger = new ConsoleLogger(); 33 | 34 | logger.Log("Hello World"); 35 | } 36 | } 37 | } 38 | 39 | namespace Solution{ 40 | public interface ILogger{ 41 | void Log(string message); 42 | } 43 | 44 | public class ConsoleLogger : ILogger 45 | { 46 | public void Log(string message) 47 | { 48 | Console.WriteLine(message); 49 | } 50 | } 51 | 52 | //Pravimo se da je ovo vanjska klasa i nemožemo ju mjenjat 53 | public class FileLoggerService{ 54 | public void LogToFile(string message){ 55 | Console.WriteLine($"Logging message to file. Message:{message}"); 56 | } 57 | } 58 | 59 | public class FileLoggerAdapter:ILogger{ 60 | FileLoggerService fileLoggerService; 61 | public FileLoggerAdapter(){ 62 | fileLoggerService = new FileLoggerService(); 63 | } 64 | 65 | public void Log(string message){ 66 | fileLoggerService.LogToFile(message); 67 | } 68 | } 69 | 70 | public static class ClientCode 71 | { 72 | public static void Run() 73 | { 74 | ILogger logger = new FileLoggerAdapter(); 75 | 76 | logger.Log("Hello World"); 77 | } 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Examples/Prototip.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.X509Certificates; 2 | 3 | namespace DevOfSwSuppWithOOP.DesignPatterns.Creational.Prototype{ 4 | namespace Problem{ 5 | public class Cat 6 | { 7 | public string name; 8 | public string weight; 9 | private string type; 10 | public Cat(string name, string weight, string type) 11 | { 12 | this.name = name; 13 | this.weight = weight; 14 | this.type = type; 15 | } 16 | public void LogData() 17 | { 18 | Console.WriteLine($"{name},{weight},{type}"); 19 | } 20 | } 21 | class ClientCode 22 | { 23 | public static void Run() 24 | { 25 | Cat cat = new Cat("Cato", "20", "Persian"); 26 | //clone the cat 27 | Cat catClone = new Cat(cat.name, "", ""); 28 | //cant get weight and type because they are private 29 | cat.LogData(); 30 | catClone.LogData(); 31 | } 32 | } 33 | } 34 | 35 | namespace Solution{ 36 | public interface ICloneable{ 37 | object Clone(); 38 | } 39 | 40 | public class Cat:ICloneable 41 | { 42 | public string name; 43 | public string weight; 44 | private string type; 45 | public Cat(string name, string weight, string type) 46 | { 47 | this.name = name; 48 | this.weight = weight; 49 | this.type = type; 50 | } 51 | 52 | public object Clone() 53 | { 54 | return new Cat(name, weight, type); 55 | } 56 | 57 | public void LogData() 58 | { 59 | Console.WriteLine($"{name},{weight},{type}"); 60 | } 61 | } 62 | 63 | public class Clowder{ 64 | private List cats; 65 | public void Add(ICloneable clone){ 66 | cats.Add(clone); 67 | } 68 | 69 | public ICloneable GetById(int index){ 70 | return cats[index]; 71 | } 72 | } 73 | 74 | class ClientCode 75 | { 76 | public static void Run() 77 | { 78 | Cat cat = new Cat("Cato", "20", "Persian"); 79 | Cat catClone = (Cat)cat.Clone(); 80 | cat.LogData(); 81 | catClone.LogData(); 82 | } 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Examples/TemplateMethod.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.TemplateMethod{ 2 | namespace Problem{ 3 | public class Game 4 | { 5 | public Game() 6 | { 7 | Console.WriteLine("Start Game"); 8 | Console.WriteLine("Spawn Enemy"); 9 | Console.WriteLine("Spawn a Player"); 10 | Console.WriteLine("End Game"); 11 | } 12 | } 13 | public class GameManager 14 | { 15 | Game game; 16 | public GameManager(Game game) 17 | { 18 | this.game = game; 19 | } 20 | } 21 | 22 | public static class ClientCode 23 | { 24 | public static void Run(){ 25 | GameManager gameManager = new GameManager(new Game()); 26 | } 27 | } 28 | } 29 | 30 | namespace Solution{ 31 | public abstract class Game 32 | { 33 | public void Play() 34 | { 35 | StartGame(); 36 | SpawnEnemies(); 37 | SpawnAPlayer(); 38 | EndGame(); 39 | } 40 | public void StartGame() 41 | { 42 | Console.WriteLine("Start Game"); 43 | } 44 | public abstract void SpawnEnemies(); 45 | public abstract void SpawnAPlayer(); 46 | public virtual void EndGame() 47 | { 48 | Console.WriteLine("End Game"); 49 | } 50 | } 51 | 52 | public class Multiplayer : Game 53 | { 54 | public override void SpawnAPlayer() 55 | { 56 | Console.WriteLine("Spawn a bunch of Players"); 57 | } 58 | 59 | public override void SpawnEnemies() 60 | { 61 | Console.WriteLine("Spawn a bunch of Enemies"); 62 | } 63 | } 64 | 65 | public class ZombieGame : Game 66 | { 67 | public override void SpawnAPlayer() 68 | { 69 | Console.WriteLine("Spawn a Player"); 70 | } 71 | 72 | public override void SpawnEnemies() 73 | { 74 | Console.WriteLine("Spawn 5 Zombies"); 75 | } 76 | } 77 | 78 | public class GameManager 79 | { 80 | Game game; 81 | public GameManager(Game game) 82 | { 83 | this.game = game; 84 | game.Play(); 85 | } 86 | } 87 | 88 | public static class ClientCode 89 | { 90 | public static void Run(){ 91 | GameManager gameManager = new GameManager(new Multiplayer()); 92 | } 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Examples/Iterator.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.Iterator{ 2 | namespace Problem{ 3 | public class Item 4 | { 5 | public string name; 6 | 7 | public Item(string name) 8 | { 9 | this.name = name; 10 | } 11 | } 12 | } 13 | 14 | namespace Solution{ 15 | public class Item 16 | { 17 | public string name; 18 | 19 | public Item(string name) 20 | { 21 | this.name = name; 22 | } 23 | } 24 | 25 | public interface IItemIterator 26 | { 27 | public bool HasNext(); 28 | public Item GetNext(); 29 | } 30 | 31 | public interface IItemCollection 32 | { 33 | public IItemIterator CreateItemIterator(); 34 | } 35 | 36 | public class ItemIterator : IItemIterator 37 | { 38 | private ItemCollection itemCollection; 39 | int current; 40 | 41 | public ItemIterator(ItemCollection itemCollection) 42 | { 43 | this.itemCollection = itemCollection; 44 | } 45 | 46 | public Item GetNext() 47 | { 48 | if (HasNext()) 49 | { 50 | Item item = itemCollection.GetItem(current); 51 | current++; 52 | return item; 53 | } 54 | else 55 | { 56 | throw new Exception("Nema"); 57 | } 58 | } 59 | 60 | public bool HasNext() 61 | { 62 | return current <= itemCollection.Count(); 63 | } 64 | } 65 | 66 | public class ItemCollection : IItemCollection 67 | { 68 | private List items; 69 | 70 | public ItemCollection(List items) 71 | { 72 | this.items = items; 73 | } 74 | 75 | public IItemIterator CreateItemIterator() 76 | { 77 | return new ItemIterator(this); 78 | } 79 | 80 | public int Count() 81 | { 82 | return items.Count; 83 | } 84 | 85 | public Item GetItem(int index) 86 | { 87 | return items[index]; 88 | } 89 | } 90 | 91 | public static class ClientCode 92 | { 93 | public static void Run() 94 | { 95 | ItemCollection itemCollection = new ItemCollection(new List(){ 96 | new Item("BORK"), new Item("dc") 97 | }); 98 | } 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Examples/Bridge.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Bridge{ 2 | namespace Problem{ 3 | public class SteelBow 4 | { 5 | public void ShootFireArrow(FireArrow fireArrow) 6 | { 7 | fireArrow.ShootArrow(); 8 | } 9 | public void ShootRegularArrow(RegularArrow regularArrow) 10 | { 11 | regularArrow.ShootArrow(); 12 | } 13 | } 14 | public class RegularArrow 15 | { 16 | public void ShootArrow() 17 | { 18 | Console.WriteLine("Shoot Regular Arrow"); 19 | } 20 | } 21 | public class FireArrow 22 | { 23 | public void ShootArrow() 24 | { 25 | Console.WriteLine("Shoot Fire Arrow"); 26 | } 27 | } 28 | 29 | public class Game 30 | { 31 | public Game() 32 | { 33 | SteelBow steelBow = new SteelBow(); 34 | steelBow.ShootFireArrow(new FireArrow()); 35 | steelBow.ShootRegularArrow(new RegularArrow()); 36 | } 37 | } 38 | 39 | public static class ClientCode 40 | { 41 | public static void Run() 42 | { 43 | new Game(); 44 | } 45 | } 46 | } 47 | 48 | namespace Solution{ 49 | public abstract class Bow{ 50 | public List arrows; 51 | public Bow(List arrows){ 52 | this.arrows = arrows;} 53 | public void ShootArrows(){ 54 | arrows.ForEach(arrow =>{ 55 | arrow.ShootArrow(); 56 | }); 57 | arrows.Clear(); 58 | } 59 | public void ShootArrow(){ 60 | arrows[0].ShootArrow(); 61 | arrows.Remove(arrows[0]); 62 | } 63 | } 64 | public class SteelBow : Bow{ 65 | public SteelBow(List arrows) : base(arrows){} 66 | } 67 | public interface IArrow{ 68 | public void ShootArrow(); 69 | } 70 | public class RegularArrow : IArrow{ 71 | public void ShootArrow(){ 72 | Console.WriteLine("Shoot Regular Arrow"); 73 | } 74 | } 75 | public class FireArrow : IArrow{ 76 | public void ShootArrow(){ 77 | Console.WriteLine("Shoot Fire Arrow"); 78 | } 79 | } 80 | public class Game{ 81 | public Game(){ 82 | List arrows = new List() { new FireArrow(), new RegularArrow() }; 83 | Bow bow = new SteelBow(arrows); 84 | 85 | bow.ShootArrows(); 86 | } 87 | } 88 | public static class ClientCode{ 89 | public static void Run(){ 90 | new Game(); 91 | } 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DevOfSwSuppWithOOP 2 | 3 | ## Opis 4 | Skup definicija i edukacijskih primjera u svrhu učenja za kolegiji Razvoj programske podrške objektno orjentiranim načelima (RPPOON). 5 | 6 | # Sadržaj 7 | [OOP](https://github.com/FC122/DevOfSwSuppWithOOP/blob/master/DevOfSwSuppWithOOP/OOP/README.hr.md) 8 | 9 | [Clean code](https://github.com/FC122/DevOfSwSuppWithOOP/blob/master/DevOfSwSuppWithOOP/CleanCode/README.hr.md) 10 | 11 | [Code smells and antipatterns](https://github.com/FC122/DevOfSwSuppWithOOP/blob/master/DevOfSwSuppWithOOP/CodeSmellsAndAntipatterns/README.hr.md) 12 | 13 | [Creational design patterns](https://github.com/FC122/DevOfSwSuppWithOOP/blob/master/DevOfSwSuppWithOOP/DesignPatterns/Creational/README.hr.md) 14 | 15 | [Structural design patterns](https://github.com/FC122/DevOfSwSuppWithOOP/blob/master/DevOfSwSuppWithOOP/DesignPatterns/Structural/README.hr.md) 16 | 17 | [Behavioural design patterns](https://github.com/FC122/DevOfSwSuppWithOOP/blob/master/DevOfSwSuppWithOOP/DesignPatterns/Behavioural/README.hr.md) 18 | 19 | [SOLID](https://github.com/FC122/DevOfSwSuppWithOOP/blob/master/DevOfSwSuppWithOOP/SOLID/README.hr.md) 20 | 21 | ## Literatura 22 | [Refactoring guru, Website](https://refactoring.guru), 04.14.2024. 23 | 24 | [Sourcemaking, Website](https://sourcemaking.com), 04.14.2024. 25 | 26 | [FreeCodeCamp, Website](https://www.freecodecamp.org/news/clean-coding-for-beginners), 04.14.2024. 27 | 28 | [Luzkan Code Smells - Github](https://github.com/Luzkan/smells), 04.14.2024. 29 | 30 | [Design Paterns, Gamma, Helm, Johnson, Vlissides, Book](https://github.com/ben-elbert/books/blob/master/Design%20Patterns%2C%20Elements%20of%20Reusable%20Object-Oriented%20Software.pdf) 31 | 32 | [CodeAesthetic, Youtube](https://www.youtube.com/@CodeAesthetic), 04.14.2024. 33 | 34 | [Fireship, Youtube](https://www.youtube.com/watch?v=tv-_1er1mWI), 04.14.2024. 35 | 36 | [Geekific, Youtube](https://www.youtube.com/watch?v=mE3qTp1TEbg&list=PLlsmxlJgn1HJpa28yHzkBmUY-Ty71ZUGc), 04.14.2024. 37 | 38 | [CodeMaze, Website](https://code-maze.com), 04.17.2024. 39 | 40 | [CodeSmells](https://code-smells.com), 04.17.2024. 41 | 42 | [Makolyte, Website](https://makolyte.com), 04.17.2024. 43 | 44 | [CodingDrills, Website](https://www.codingdrills.com/tutorial/design-patterns-tutorial/introduction-to-dp), 05.11.2024 45 | 46 | [DOT NET TUTORIALS, Website](https://dotnettutorials.net/course/csharp-dot-net-tutorials/), 05.19.2024. 47 | 48 | # Korištenje 49 | Kloniraj repo: 50 | ``` 51 | git clone https://github.com/FC122/DevOfSwSuppWithOOP 52 | ``` 53 | ili preuzmi .zip i raspakiraj 54 | 55 | Otvori solution pomoći Visual Studija ili Visual Studio Codea 56 | 57 | U Program.cs kad želiš pokrenuti klijentski kod (ClientCode.cs) nekog namespace-a promjeni referencirani namespace. U primjeru ispod namespace je OOPBankingSystem 58 | ```cs 59 | public static class Program{ 60 | public static void Main(string[] args){ 61 | OOPBankingSystem.ClientCode.Run(); 62 | } 63 | } 64 | ``` 65 | # Autor 66 | Filip Cica 67 | 68 | # TODO 69 | - Visitor Example 70 | - Null Objekt Example 71 | - Dodati Zadatke iz 3,4,5 72 | - Naredba, Mediator, Stanje -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Examples/Memento.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.Memento{ 2 | namespace Problem{ 3 | public class File//izvornik 4 | { 5 | public string FileData { get; private set; } 6 | public File() { FileData = ""; } 7 | public void Append(string data) {FileData+=data;} 8 | } 9 | public static class ClientCode{ 10 | public static void Run(){ 11 | List fileHistory = new List(); 12 | File file = new File(); 13 | file.Append("Seminarski rad");//Pišeš rad 14 | //Želiš saveat progres - kliknes Ctrl s - ovo se dogodi: 15 | File fileVersion1 = new File(); 16 | fileVersion1.Append(file.FileData); 17 | fileHistory.Add(fileVersion1); 18 | //Kad zelis undoat moras ovo radit: 19 | file = fileHistory.Last(); 20 | //Postoji li bolji pristup? 21 | } 22 | } 23 | } 24 | namespace Solution{ 25 | public class File//izvornik 26 | { 27 | public string FileData { get; private set; } 28 | public File() { FileData = ""; } 29 | public void Append(string data) {} 30 | public FileClipboard SaveDataToClipboard() 31 | { 32 | return new FileClipboard(FileData); 33 | } 34 | public void PasteFromClipboard(FileClipboard fileClipboard) 35 | { 36 | FileData = fileClipboard.FileData; 37 | } 38 | } 39 | 40 | public class FileClipboard//Memento 41 | { 42 | public string FileData { get; private set; } 43 | public FileClipboard(string FileData) 44 | { 45 | this.FileData = FileData; 46 | } 47 | public string GetClipboardData() 48 | { 49 | return FileData; 50 | } 51 | } 52 | 53 | public class Cache//skrbnik 54 | { 55 | File file; 56 | List fileClipboards = new List(); 57 | public Cache(File file) 58 | { 59 | this.file = file; 60 | } 61 | public void SaveToCache(FileClipboard fileClipboard) 62 | { 63 | fileClipboards.Add(fileClipboard); 64 | } 65 | public void Undo() 66 | { 67 | int count = fileClipboards.Count; 68 | if (count > 1) 69 | { 70 | file.PasteFromClipboard(fileClipboards.ElementAt(count - 2)); 71 | fileClipboards.RemoveAt(count - 1); 72 | } 73 | } 74 | } 75 | 76 | public static class ClientCode 77 | { 78 | public static void Run() 79 | { 80 | File file = new File(); 81 | Cache cache = new Cache(file); 82 | file.Append("Seminarski rad"); 83 | cache.SaveToCache(new FileClipboard(file.FileData)); 84 | cache.Undo(); 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Solutions/Solution2.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.Solution2{ 2 | public class Activity{ 3 | public int Price {get; set;} 4 | public string Name{get; set;} 5 | public Activity(string name){ 6 | Name = name; 7 | } 8 | } 9 | 10 | public class VacationConfigurator 11 | { 12 | public string Destination { get; private set; } 13 | private List additionalActivities = new List(); 14 | 15 | public decimal CalculateTotal() 16 | { 17 | return additionalActivities.Sum(it => it.Price); 18 | } 19 | 20 | public void AddExtra(Activity activity) 21 | { 22 | additionalActivities.Add(activity); 23 | } 24 | 25 | public void Remove(Activity activity) 26 | { 27 | additionalActivities.Remove(activity); 28 | } 29 | 30 | public void LoadPrevious(VacationConfiguration configuration) 31 | { 32 | Destination = configuration.GetDestination(); 33 | additionalActivities.Clear(); 34 | additionalActivities.AddRange(configuration.GetAdditionalActivities()); 35 | } 36 | 37 | public VacationConfiguration Store() 38 | { 39 | return new VacationConfiguration(Destination, additionalActivities); 40 | } 41 | } 42 | 43 | public class VacationConfiguration 44 | { 45 | private string destination; 46 | private List additionalActivities; 47 | public VacationConfiguration(string destination, List additionalActivities){ 48 | this.destination = destination; 49 | this.additionalActivities = additionalActivities; 50 | } 51 | public string GetDestination(){ 52 | return destination; 53 | } 54 | 55 | public List GetAdditionalActivities(){ 56 | return additionalActivities; 57 | } 58 | } 59 | 60 | public class ConfigurationManager 61 | { 62 | private List configurations = new List(); 63 | 64 | public void AddConfiguration(VacationConfiguration configuration) 65 | { 66 | configurations.Add(configuration); 67 | } 68 | 69 | public void DeleteConfiguration(VacationConfiguration configuration) 70 | { 71 | configurations.Remove(configuration); 72 | } 73 | 74 | public VacationConfiguration GetConfiguration(int index) 75 | { 76 | return configurations[index]; 77 | } 78 | } 79 | 80 | public static class Program{ 81 | public static void Main(){ 82 | VacationConfigurator vacationConfigurator = new VacationConfigurator(); 83 | 84 | VacationConfiguration vacationConfiguration = vacationConfigurator.Store(); 85 | 86 | ConfigurationManager configManager = new ConfigurationManager(); 87 | 88 | configManager.AddConfiguration(vacationConfiguration); 89 | 90 | vacationConfigurator.AddExtra(new Activity("Walking")); 91 | 92 | vacationConfigurator.LoadPrevious(configManager.GetConfiguration(0)); 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Examples/MethodFactory.cs: -------------------------------------------------------------------------------- 1 | using DevOfSwSuppWithOOP.DesignPatterns.Creational.MethodFactory.Problem; 2 | 3 | namespace DevOfSwSuppWithOOP.DesignPatterns.Creational.MethodFactory{ 4 | namespace Problem{ 5 | class DragonDungeon 6 | { 7 | public void OpenDragonDungeon() 8 | { 9 | Console.WriteLine("Open Dragon Dungeon"); 10 | } 11 | } 12 | 13 | class IceDungeon 14 | { 15 | public void OpenIceDungeon() 16 | { 17 | Console.WriteLine("Open Ice Dungeon"); 18 | } 19 | } 20 | 21 | class DungeonMaster 22 | { 23 | DragonDungeon dragonDungeon; 24 | IceDungeon iceDungeon; 25 | public void OpenDragonDungeon() 26 | { 27 | dragonDungeon = new DragonDungeon(); 28 | dragonDungeon.OpenDragonDungeon(); 29 | } 30 | public void OpenIceDragonDungeon() 31 | { 32 | iceDungeon = new IceDungeon(); 33 | iceDungeon.OpenIceDungeon(); 34 | } 35 | } 36 | 37 | class ClientCode 38 | { 39 | public static void Run() 40 | { 41 | DungeonMaster dm = new DungeonMaster(); 42 | dm.OpenDragonDungeon(); 43 | } 44 | } 45 | } 46 | 47 | namespace Solution{ 48 | abstract class Dungeon{ 49 | public abstract void Open(); 50 | } 51 | 52 | class DragonDungeon : Dungeon 53 | { 54 | public override void Open() 55 | { 56 | Console.WriteLine("Open Dragon Dungeon"); 57 | } 58 | } 59 | 60 | class IceDungeon : Dungeon 61 | { 62 | public override void Open() 63 | { 64 | Console.WriteLine("Open Ice Dungeon"); 65 | } 66 | } 67 | 68 | abstract class DungeonFactory{ 69 | public abstract Dungeon CreateDungeon(); 70 | } 71 | 72 | class IceDungeonFactory : DungeonFactory 73 | { 74 | public override Dungeon CreateDungeon() 75 | { 76 | return new IceDungeon(); 77 | } 78 | } 79 | 80 | class DragonDungeonFactory: DungeonFactory{ 81 | public override Dungeon CreateDungeon() 82 | { 83 | return new DragonDungeon(); 84 | } 85 | } 86 | 87 | class DungeonMaster{ 88 | DungeonFactory dungeonFactory; 89 | public DungeonMaster(DungeonFactory dungeonFactory){ 90 | this.dungeonFactory = dungeonFactory; 91 | } 92 | public void OpenDungeon(){ 93 | dungeonFactory.CreateDungeon().Open(); 94 | } 95 | } 96 | 97 | class ClientCode 98 | { 99 | public static void Run() 100 | { 101 | DungeonMaster dm = new DungeonMaster( new DragonDungeonFactory()); 102 | dm.OpenDungeon(); 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Examples/Singleton.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Creational.Singleton{ 2 | namespace Problem{ 3 | public class Game { 4 | public GameManager gm = new GameManager(); 5 | public Game() 6 | { 7 | gm.GetConfigs(); 8 | } 9 | } 10 | 11 | public class Character 12 | { 13 | public GameManager gm = new GameManager(); 14 | public Character() 15 | { 16 | gm.GetCharacters(); 17 | } 18 | } 19 | 20 | public class UI 21 | { 22 | public GameManager gm = new GameManager(); 23 | public UI() 24 | { 25 | gm.GetUIElements(); 26 | } 27 | } 28 | 29 | public class GameManager 30 | { 31 | public void GetConfigs() 32 | { 33 | Console.WriteLine("Configs"); 34 | } 35 | public void GetUIElements() 36 | { 37 | Console.WriteLine("UI Elements"); 38 | } 39 | public void GetCharacters() 40 | { 41 | Console.WriteLine("Characters"); 42 | } 43 | } 44 | 45 | class ClientCode 46 | { 47 | public static void Run() 48 | { 49 | Game game = new Game(); 50 | Character character = new Character(); 51 | UI ui = new UI(); 52 | } 53 | } 54 | } 55 | 56 | namespace Solution{ 57 | public class Game 58 | { 59 | public Game() 60 | { 61 | GameManager.GetGameManager().GetConfigs(); 62 | } 63 | } 64 | 65 | public class Character 66 | { 67 | public Character() 68 | { 69 | GameManager.GetGameManager().GetCharacters(); 70 | } 71 | } 72 | public class UI 73 | { 74 | public GameManager gm = GameManager.GetGameManager(); 75 | public UI() 76 | { 77 | gm.GetUIElements(); 78 | } 79 | } 80 | 81 | public class GameManager 82 | { 83 | private static GameManager gameManager; 84 | 85 | public static GameManager GetGameManager() 86 | { 87 | if (gameManager == null) 88 | { 89 | gameManager = new GameManager(); 90 | } 91 | return gameManager; 92 | } 93 | 94 | public void GetConfigs() 95 | { 96 | Console.WriteLine("Configs"); 97 | } 98 | 99 | public void GetUIElements() 100 | { 101 | Console.WriteLine("UI Elements"); 102 | } 103 | 104 | public void GetCharacters() 105 | { 106 | Console.WriteLine("Characters"); 107 | } 108 | } 109 | 110 | class ClientCode 111 | { 112 | public static void Run() 113 | { 114 | Game game = new Game(); 115 | Character character = new Character(); 116 | UI ui = new UI(); 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Solutions/Solutions3.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.Solution3{ 2 | public abstract class Handler 3 | { 4 | public Handler NextHandler; 5 | 6 | public void SetNextHandler(Handler NextHandler) 7 | { 8 | this.NextHandler = NextHandler; 9 | } 10 | public abstract void DispatchNote(long requestedAmount); 11 | } 12 | 13 | public class HundredHandler : Handler 14 | { 15 | public override void DispatchNote(long requestedAmount) 16 | { 17 | long numberofNotesToBeDispatched = requestedAmount / 100; 18 | if (numberofNotesToBeDispatched > 0) 19 | { 20 | if (numberofNotesToBeDispatched > 1) 21 | { 22 | Console.WriteLine(numberofNotesToBeDispatched + " Hundred notes are dispatched by HundredHandler"); 23 | } 24 | else 25 | { 26 | Console.WriteLine(numberofNotesToBeDispatched + " Hundred note is dispatched by HundredHandler"); 27 | } 28 | } 29 | } 30 | } 31 | 32 | public class TwoHundredHandler : Handler 33 | { 34 | public override void DispatchNote(long requestedAmount) 35 | { 36 | long numberofNotesToBeDispatched = requestedAmount / 200; 37 | if (numberofNotesToBeDispatched > 0) 38 | { 39 | if (numberofNotesToBeDispatched > 1) 40 | { 41 | Console.WriteLine(numberofNotesToBeDispatched + " Two Hundred notes are dispatched by TwoHundredHandler"); 42 | } 43 | else 44 | { 45 | Console.WriteLine(numberofNotesToBeDispatched + " Two Hundred note is dispatched by TwoHundredHandler"); 46 | } 47 | } 48 | long pendingAmountToBeProcessed = requestedAmount % 200; 49 | if (pendingAmountToBeProcessed > 0) 50 | { 51 | NextHandler.DispatchNote(pendingAmountToBeProcessed); 52 | } 53 | } 54 | } 55 | 56 | public class FiveHundredHandler : Handler 57 | { 58 | public override void DispatchNote(long requestedAmount) 59 | { 60 | long numberofNotesToBeDispatched = requestedAmount / 500; 61 | if (numberofNotesToBeDispatched > 0) 62 | { 63 | if (numberofNotesToBeDispatched > 1) 64 | { 65 | Console.WriteLine(numberofNotesToBeDispatched + " Five Hundred notes are dispatched by FiveHundredHandler"); 66 | } 67 | else 68 | { 69 | Console.WriteLine(numberofNotesToBeDispatched + " Five Hundred note is dispatched by FiveHundredHandler"); 70 | } 71 | } 72 | long pendingAmountToBeProcessed = requestedAmount % 500; 73 | if (pendingAmountToBeProcessed > 0) 74 | { 75 | NextHandler.DispatchNote(pendingAmountToBeProcessed); 76 | } 77 | } 78 | } 79 | 80 | public static class ClientCode{ 81 | public static void Run(){ 82 | FiveHundredHandler fiveHundredHandler = new FiveHundredHandler(); 83 | TwoHundredHandler twoHundredHandler = new TwoHundredHandler(); 84 | HundredHandler hundredHandler = new HundredHandler(); 85 | 86 | fiveHundredHandler.SetNextHandler(twoHundredHandler); 87 | twoHundredHandler.SetNextHandler(hundredHandler); 88 | 89 | fiveHundredHandler.DispatchNote(200); 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Examples/Flyweight.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Flyweight{ 2 | namespace Problem{ 3 | public class Weapon 4 | { 5 | string name; 6 | string material; 7 | string category; 8 | int dmg; 9 | public Weapon(int dmg, string name, string material, string category) 10 | { 11 | this.name = name; 12 | this.material = material; 13 | this.category = category; 14 | this.dmg = dmg; 15 | Console.WriteLine($"{dmg} {name} {material} {category}"); 16 | } 17 | } 18 | 19 | public class Game 20 | { 21 | List weapons; 22 | public Game() 23 | { 24 | weapons = new List(); 25 | for (int i = 0; i < 10; i++) 26 | { 27 | weapons.Add(new Weapon(10, "Excalibur", "Metal", "Sword")); 28 | weapons.Add(new Weapon(15, "God Killer", "Wooden", "Bow")); 29 | weapons.Add(new Weapon(30, "King Slayer", "Bronze", "Spear")); 30 | } 31 | } 32 | } 33 | public static class ClientCode 34 | { 35 | public static void Run() 36 | { 37 | new Game(); 38 | } 39 | } 40 | } 41 | 42 | namespace Solution{ 43 | public class Weapon 44 | { 45 | string name; 46 | WeaponType weaponType; 47 | int dmg; 48 | 49 | public Weapon(int dmg, string name, WeaponType weaponType) 50 | { 51 | this.name = name; 52 | this.weaponType = weaponType; 53 | this.dmg = dmg; 54 | Console.WriteLine($"{dmg} {name} {weaponType.material} {weaponType.category}"); 55 | } 56 | } 57 | 58 | public class WeaponType 59 | { 60 | public string material; 61 | public string category; 62 | public WeaponType(string material, string category) 63 | { 64 | this.material = material; 65 | this.category = category; 66 | } 67 | } 68 | 69 | public class WeaponFactory 70 | { 71 | public static Dictionary weaponTypes 72 | = new Dictionary(); 73 | public static WeaponType GetWeaponType(String name) 74 | { 75 | return weaponTypes[name]; 76 | } 77 | } 78 | 79 | public class Game 80 | { 81 | List weapons; 82 | public Game() 83 | { 84 | WeaponFactory.weaponTypes.Add("MetalSword", new WeaponType("Metal", "Sword")); 85 | WeaponFactory.weaponTypes.Add("WoodenBow", new WeaponType("Wooden", "Bow")); 86 | WeaponFactory.weaponTypes.Add("King Slayer", new WeaponType("Bronze", "Spear")); 87 | weapons = new List(); 88 | for (int i = 0; i < 10; i++) 89 | { 90 | weapons.Add(new Weapon(10, "Excalibur", WeaponFactory.GetWeaponType("MetalSword"))); 91 | weapons.Add(new Weapon(10, "God Killer", WeaponFactory.GetWeaponType("MetalSword"))); 92 | weapons.Add(new Weapon(30, "King Slayer", WeaponFactory.GetWeaponType("MetalSword"))); 93 | } 94 | } 95 | } 96 | 97 | public static class ClientCode 98 | { 99 | public static void Run() 100 | { 101 | new Game(); 102 | } 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Examples/Composite.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Composite{ 2 | namespace Problem{ 3 | public class Item{ 4 | string name; 5 | int price; 6 | public Item(string name, int price){ 7 | this.name = name; 8 | this.price = price; 9 | } 10 | public string Name { get { return name; } } 11 | public int Price { get { return price;}} 12 | } 13 | 14 | public class Package{ 15 | string name; 16 | List items; 17 | 18 | public Package(string name){ 19 | this.name = name; 20 | items = new List(); 21 | } 22 | 23 | public void AddItem(Item item){ 24 | items.Add(item); 25 | } 26 | 27 | public void RemoveItem(Item item){ 28 | items.Remove(item); 29 | } 30 | public string Name{ get { return name; } } 31 | public List Items{ get{return items;}} 32 | } 33 | 34 | public static class ClientCode 35 | { 36 | public static void Run() 37 | { 38 | Package package = new Package("Package1"); 39 | int totalPrice=0; 40 | package.AddItem(new Item("Sat", 20)); 41 | package.AddItem(new Item("Pan", 30)); 42 | package.Items.ForEach(item=>{ 43 | totalPrice+=item.Price; 44 | }); 45 | 46 | Console.WriteLine($"{totalPrice}"); 47 | //kako dodati paket u paket? 48 | //sta ako imamo razlicite vrste paketa i itema? 49 | } 50 | } 51 | } 52 | 53 | namespace Solution{ 54 | public interface IItem{ 55 | public string Name {get;} 56 | public int Price {get;} 57 | } 58 | 59 | public class Item:IItem{ 60 | string name; 61 | int price; 62 | 63 | public Item(string name, int price){ 64 | this.name = name; 65 | this.price = price; 66 | } 67 | 68 | public string Name { get { return name; }} 69 | public int Price { get { return price;}} 70 | } 71 | 72 | public class Package:IItem{ 73 | string name; 74 | int price; 75 | 76 | List items; 77 | 78 | public Package(string name){ 79 | this.name = name; 80 | items = new List(); 81 | } 82 | 83 | public string Name { get { return name; }} 84 | public int Price { get { 85 | price = 0; 86 | items.ForEach(item=>{ 87 | price+=item.Price; 88 | }); 89 | return price; 90 | }} 91 | 92 | public void AddItem(IItem item){ 93 | items.Add(item); 94 | } 95 | 96 | public void RemoveItem(IItem item){ 97 | items.Remove(item); 98 | } 99 | } 100 | 101 | public static class ClientCode 102 | { 103 | public static void Run() 104 | { 105 | Package smallPackage = new Package("SmallPackage"); 106 | smallPackage.AddItem(new Item("Pan", 20)); 107 | smallPackage.AddItem(new Item("Mouse", 30)); 108 | 109 | Package bigPackage = new Package("BigPackage"); 110 | bigPackage.AddItem(smallPackage); 111 | bigPackage.AddItem(new Item("Lamp", 30)); 112 | 113 | Console.WriteLine($"{bigPackage.Price}"); 114 | } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Examples/Observer.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.Observer{ 2 | namespace Problem{ 3 | public class UserConsole 4 | { 5 | public void ShowMessageOnConsole(string message) 6 | { 7 | Console.WriteLine($"Write to user console: {message}"); 8 | } 9 | } 10 | 11 | public class File 12 | { 13 | public void SaveLogToFile(string log) 14 | { 15 | Console.WriteLine($"Write log to file{log}"); 16 | } 17 | } 18 | 19 | public class Email 20 | { 21 | public void SendMail(string mailContent) 22 | { 23 | Console.WriteLine($"Send log to mail: {mailContent}"); 24 | } 25 | } 26 | 27 | 28 | public static class ClientCode 29 | { 30 | public static void Run() 31 | { 32 | UserConsole userConsole = new UserConsole(); 33 | File file = new File(); 34 | Email email = new Email(); 35 | userConsole.ShowMessageOnConsole("System message"); 36 | file.SaveLogToFile("System message"); 37 | email.SendMail("System message"); 38 | } 39 | } 40 | } 41 | 42 | namespace Solution{ 43 | public interface ILoggable 44 | { 45 | public void Log(string message); 46 | } 47 | 48 | public class UserConsole : ILoggable 49 | { 50 | public void Log(string message) 51 | { 52 | ShowMessageOnConsole(message); 53 | } 54 | 55 | public void ShowMessageOnConsole(string message) 56 | { 57 | Console.WriteLine($"Write to user console: {message}"); 58 | } 59 | } 60 | 61 | public class File : ILoggable 62 | { 63 | public void Log(string message) 64 | { 65 | SaveLogToFile(message); 66 | } 67 | 68 | public void SaveLogToFile(string log) 69 | { 70 | Console.WriteLine($"Write log to file{log}"); 71 | } 72 | } 73 | 74 | public class Email : ILoggable 75 | { 76 | public void Log(string message) 77 | { 78 | SendMail(message); 79 | } 80 | 81 | public void SendMail(string mailContent) 82 | { 83 | Console.WriteLine($"Send log to mail: {mailContent}"); 84 | } 85 | } 86 | 87 | public interface IManageable 88 | { 89 | public void Add(ILoggable loggable); 90 | public void Remove(ILoggable loggable); 91 | public void Notify(string message); 92 | } 93 | 94 | public class LogManager : IManageable 95 | { 96 | List loggables = new List(); 97 | public void Add(ILoggable loggable) 98 | { 99 | loggables.Add(loggable); 100 | } 101 | 102 | public void Notify(string message) 103 | { 104 | loggables.ForEach(loggable => 105 | { 106 | loggable.Log(message); 107 | }); 108 | } 109 | 110 | public void Remove(ILoggable loggable) 111 | { 112 | loggables.Remove(loggable); 113 | } 114 | } 115 | 116 | public static class ClientCode 117 | { 118 | public static void Run() 119 | { 120 | IManageable logginigManager = new LogManager(); 121 | logginigManager.Add(new Email()); 122 | logginigManager.Add(new File()); 123 | logginigManager.Add(new UserConsole()); 124 | logginigManager.Notify("Doslo je do errora"); 125 | } 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Examples/ApstractFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Creational.AbstractFactry{ 2 | namespace Problem{ 3 | public class FireWizard{ 4 | public void DoFireMagic() 5 | { 6 | Console.WriteLine("Do Fire Magic"); 7 | } 8 | } 9 | 10 | public class WaterWizard{ 11 | public void DoWaterMagic(){ 12 | Console.WriteLine("Do Water Magic"); 13 | } 14 | } 15 | 16 | public class FireGoblin{ 17 | public void DoFireDamage(){ 18 | Console.WriteLine("Do Fire Damage"); 19 | } 20 | } 21 | 22 | public class WaterGoblin 23 | { 24 | public void DoWaterDamage(){ 25 | Console.WriteLine("Do Water Damage"); 26 | } 27 | } 28 | 29 | public class GameManager{ 30 | public void PlayWaterLevel(){ 31 | WaterGoblin waterGoblin = new WaterGoblin(); 32 | WaterWizard waterWizard = new WaterWizard(); 33 | waterGoblin.DoWaterDamage(); 34 | waterWizard.DoWaterMagic(); 35 | } 36 | 37 | public void PlayFireLevel(){ 38 | FireGoblin fireGoblin = new FireGoblin(); 39 | FireWizard fireWizard = new FireWizard(); 40 | fireGoblin.DoFireDamage(); 41 | fireWizard.DoFireMagic(); 42 | } 43 | } 44 | 45 | class ClientCode 46 | { 47 | public static void Run() 48 | { 49 | GameManager gameManager = new GameManager(); 50 | gameManager.PlayFireLevel(); 51 | } 52 | } 53 | } 54 | 55 | namespace Solution{ 56 | public abstract class Goblin{ 57 | public abstract void DoDamage(); 58 | } 59 | 60 | public abstract class Wizard{ 61 | public abstract void DoMagic(); 62 | } 63 | 64 | public class FireWizard:Wizard 65 | { 66 | public override void DoMagic() 67 | { 68 | Console.WriteLine("Do Fire Magic"); 69 | } 70 | } 71 | 72 | public class WaterWizard:Wizard 73 | { 74 | public override void DoMagic() 75 | { 76 | Console.WriteLine("Do Water Magic"); 77 | } 78 | } 79 | 80 | public class FireGoblin:Goblin 81 | { 82 | public override void DoDamage() 83 | { 84 | Console.WriteLine("Do Fire Damage"); 85 | } 86 | } 87 | 88 | public class WaterGoblin:Goblin 89 | { 90 | public override void DoDamage() 91 | { 92 | Console.WriteLine("Do Water Damage"); 93 | } 94 | } 95 | 96 | public abstract class CharacterFactory{ 97 | public abstract Wizard CreateWizard(); 98 | public abstract Goblin CreateGoblin(); 99 | } 100 | 101 | public class FireCharacterFactory : CharacterFactory 102 | { 103 | public override Goblin CreateGoblin() 104 | { 105 | return new FireGoblin(); 106 | } 107 | 108 | public override Wizard CreateWizard() 109 | { 110 | return new FireWizard(); 111 | } 112 | } 113 | 114 | public class WaterCharacterFactory : CharacterFactory 115 | { 116 | public override Goblin CreateGoblin() 117 | { 118 | return new WaterGoblin(); 119 | } 120 | 121 | public override Wizard CreateWizard() 122 | { 123 | return new WaterWizard(); 124 | } 125 | } 126 | 127 | public class GameManager{ 128 | public void Play( CharacterFactory characterFactory){ 129 | characterFactory.CreateGoblin(); 130 | characterFactory.CreateWizard(); 131 | } 132 | } 133 | 134 | class ClientCode 135 | { 136 | public static void Run() 137 | { 138 | CharacterFactory characterFactory = new FireCharacterFactory(); 139 | GameManager gameManager = new GameManager(); 140 | gameManager.Play(characterFactory); 141 | } 142 | } 143 | } 144 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Examples/Strategy.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.Strategy{ 2 | namespace Problem{ 3 | public class Enemy 4 | { 5 | int x; 6 | int y; 7 | 8 | public Enemy(int x, int y) 9 | { 10 | this.x = x; 11 | this.y = y; 12 | } 13 | 14 | public void Spawn() 15 | { 16 | Console.WriteLine($"Spawn at {x} {y}"); 17 | } 18 | } 19 | 20 | public class Game 21 | { 22 | string spawnWay; 23 | public Game(string spawnWay, int n) 24 | { 25 | this.spawnWay = spawnWay; 26 | Spawn(n); 27 | } 28 | 29 | public void SetSpawnWay(string spawnWay) 30 | { 31 | this.spawnWay = spawnWay; 32 | } 33 | 34 | public void Spawn(int n) 35 | { 36 | switch(spawnWay){ 37 | case "random": 38 | Random random = new Random(); 39 | for (int i = 0; i < n; i++) 40 | { 41 | new Enemy(random.Next(-100, 100), random.Next(-100, 100)); 42 | } 43 | break; 44 | 45 | case "diagonal": 46 | for (int i = 0; i < n; i++) 47 | { 48 | new Enemy(i, i); 49 | } 50 | break; 51 | 52 | case "spot": 53 | for (int i = 0; i < n; i++) 54 | { 55 | new Enemy(0, 0); 56 | } 57 | break; 58 | 59 | default: throw new NotImplementedException(); 60 | } 61 | } 62 | } 63 | 64 | public static class ClientCode 65 | { 66 | public static void Run(){ 67 | Game game = new Game("spot", 1); 68 | game.Spawn(10); 69 | } 70 | } 71 | } 72 | 73 | namespace Solution{ 74 | public class Enemy 75 | { 76 | int x; 77 | int y; 78 | 79 | public Enemy(int x, int y) 80 | { 81 | this.x = x; 82 | this.y = y; 83 | } 84 | 85 | public void Spawn() 86 | { 87 | Console.WriteLine($"Spawn at {x} {y}"); 88 | } 89 | } 90 | 91 | public interface ISpawnable 92 | { 93 | public void Spawn(int n); 94 | } 95 | 96 | public class RandomSpawn : ISpawnable 97 | { 98 | public void Spawn(int n) 99 | { 100 | Random random = new Random(); 101 | for (int i = 0; i < n; i++) 102 | { 103 | new Enemy(random.Next(-100, 100), random.Next(-100, 100)); 104 | } 105 | } 106 | } 107 | 108 | public class DiagonalSpawn : ISpawnable 109 | { 110 | public void Spawn(int n) 111 | { 112 | for (int i = 0; i < n; i++) 113 | { 114 | new Enemy(i, i); 115 | } 116 | } 117 | } 118 | 119 | public class SpotSpawn : ISpawnable 120 | { 121 | public void Spawn(int n) 122 | { 123 | for (int i = 0; i < n; i++) 124 | { 125 | new Enemy(0, 0); 126 | } 127 | } 128 | } 129 | 130 | public class Game 131 | { 132 | ISpawnable spawnable; 133 | public Game(ISpawnable spawnable, int n) 134 | { 135 | this.spawnable = spawnable; 136 | Spawn(n); 137 | } 138 | 139 | public void SetSpawnWay(ISpawnable spawnable) 140 | { 141 | this.spawnable = spawnable; 142 | } 143 | 144 | public void Spawn(int n) 145 | { 146 | spawnable.Spawn(n); 147 | } 148 | } 149 | 150 | public static class ClientCode 151 | { 152 | public static void Run(){ 153 | Game game = new Game(new SpotSpawn(), 1); 154 | game.Spawn(10); 155 | } 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Examples/Decorator.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Decorator{ 2 | namespace Problem{ 3 | public class BaseHealthEffect 4 | { 5 | public void ApplyBaseHealth() 6 | { 7 | Console.WriteLine("Apply Base Health"); 8 | } 9 | } 10 | 11 | public class HealthRegeneration 12 | { 13 | public void ApplyHealthRegeneration() 14 | { 15 | Console.WriteLine("Health Regen"); 16 | } 17 | 18 | } 19 | public class ArmorBuff 20 | { 21 | public void IncreaseArmor() 22 | { 23 | Console.WriteLine("Armor Increase"); 24 | } 25 | } 26 | 27 | public class MagicDamage 28 | { 29 | public void IncreaseMagicDamage() 30 | { 31 | Console.WriteLine("Magic Dmg"); 32 | } 33 | } 34 | 35 | public class Player 36 | { 37 | BaseHealthEffect baseHealthEffect; 38 | HealthRegeneration healthRegeneration; 39 | ArmorBuff armorBuff; 40 | MagicDamage magicDamage; 41 | public Player() 42 | { 43 | baseHealthEffect = new BaseHealthEffect(); 44 | healthRegeneration = new HealthRegeneration(); 45 | armorBuff = new ArmorBuff(); 46 | magicDamage = new MagicDamage(); 47 | baseHealthEffect.ApplyBaseHealth(); 48 | healthRegeneration.ApplyHealthRegeneration(); 49 | armorBuff.IncreaseArmor(); 50 | magicDamage.IncreaseMagicDamage(); 51 | } 52 | } 53 | 54 | public static class ClientCode 55 | { 56 | public static void Run() 57 | { 58 | new Player(); 59 | } 60 | } 61 | } 62 | 63 | namespace Solution{ 64 | public interface IEffect 65 | { 66 | public void ApplyEffect(); 67 | } 68 | public class BaseEffect : IEffect 69 | { 70 | public void ApplyEffect() 71 | { 72 | Console.WriteLine("Apply Base Effect"); 73 | } 74 | } 75 | public class NoEffect : IEffect 76 | { 77 | public void ApplyEffect() 78 | { 79 | Console.WriteLine("No Effect"); 80 | } 81 | } 82 | public class BaseEffectDecorator : IEffect 83 | { 84 | IEffect effect; 85 | public BaseEffectDecorator(IEffect effect) 86 | { 87 | this.effect = effect; 88 | } 89 | public virtual void ApplyEffect() 90 | { 91 | effect.ApplyEffect(); 92 | } 93 | } 94 | public class HealthRegenerationEffect : BaseEffectDecorator 95 | { 96 | public HealthRegenerationEffect(IEffect effect) : base(effect) { } 97 | public override void ApplyEffect() 98 | { 99 | base.ApplyEffect(); 100 | Console.WriteLine("Health Regeneration"); 101 | } 102 | } 103 | public class ArmorEffectDecorator : BaseEffectDecorator 104 | { 105 | public ArmorEffectDecorator(IEffect effect) : base(effect) { } 106 | public override void ApplyEffect() 107 | { 108 | base.ApplyEffect(); 109 | Console.WriteLine("Armor Increase"); 110 | } 111 | } 112 | public class MagicDamageDecorator : BaseEffectDecorator 113 | { 114 | public MagicDamageDecorator(IEffect effect) : base(effect) { } 115 | public override void ApplyEffect() 116 | { 117 | base.ApplyEffect(); 118 | Console.WriteLine("Magic Damage Buff"); 119 | } 120 | } 121 | public class Player 122 | { 123 | IEffect effect; 124 | public Player() 125 | { 126 | effect = new BaseEffectDecorator( 127 | new MagicDamageDecorator( 128 | new ArmorEffectDecorator( 129 | new HealthRegenerationEffect( 130 | new BaseEffect() 131 | ) 132 | ) 133 | ) 134 | ); 135 | effect.ApplyEffect(); 136 | } 137 | } 138 | public static class ClientCode 139 | { 140 | public static void Run() 141 | { 142 | new Player(); 143 | BaseEffectDecorator bef = new BaseEffectDecorator( 144 | new MagicDamageDecorator( 145 | new ArmorEffectDecorator( 146 | new NoEffect( 147 | 148 | )) 149 | ) 150 | ); 151 | } 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Creational/Examples/Builder.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Creational.Builder{ 2 | namespace Problem{ 3 | public interface Type { } 4 | public class Fire : Type { } 5 | public class Water : Type { } 6 | public class Normal : Type { } 7 | 8 | public interface Species { } 9 | public class Human : Species { } 10 | public class Elf : Species { } 11 | public class Dwarf : Species { } 12 | 13 | public interface Armor { } 14 | public class SteelArmor : Armor { } 15 | public class LeatherArmor : Armor { } 16 | 17 | public class Player{ 18 | Type type; 19 | Species species; 20 | Armor armor; 21 | public Player(Type type, Species species, Armor armor){ 22 | this.type = type; 23 | this.species = species; 24 | this.armor = armor; 25 | } 26 | public void Play(){ 27 | Console.WriteLine("Play"); 28 | } 29 | } 30 | 31 | class ClientCode 32 | { 33 | public static void Run() 34 | { 35 | Player steelDwarf = new (new Fire(), new Dwarf(), new SteelArmor()); 36 | steelDwarf.Play(); 37 | } 38 | } 39 | } 40 | 41 | namespace Solution{ 42 | public interface Type { } 43 | public class Fire : Type { } 44 | public class Water : Type { } 45 | public class Normal : Type { } 46 | 47 | public interface Species { } 48 | public class Human : Species { } 49 | public class Elf : Species { } 50 | public class Dwarf : Species { } 51 | 52 | public interface Armor { } 53 | public class SteelArmor : Armor { } 54 | public class LeatherArmor : Armor { } 55 | 56 | public class Player 57 | { 58 | public Type Type {get; set;} 59 | public Species Species {get; set;} 60 | public Armor Armor {get; set;} 61 | 62 | public Player(){} 63 | 64 | public Player(Type type, Species species, Armor armor) 65 | { 66 | Type = type; 67 | Species = species; 68 | Armor = armor; 69 | } 70 | 71 | public void Play() 72 | { 73 | Console.WriteLine("Play"); 74 | } 75 | } 76 | 77 | public interface IPlayerBuilder{ 78 | public IPlayerBuilder Type(Type type); 79 | public IPlayerBuilder Spicies(Species species); 80 | public IPlayerBuilder Armor(Armor armor); 81 | public IPlayerBuilder Reset(); 82 | public Player Build(); 83 | } 84 | 85 | public class PlayerBuilder : IPlayerBuilder 86 | { 87 | Player player; 88 | public PlayerBuilder(){ 89 | player = new Player(); 90 | } 91 | 92 | public IPlayerBuilder Armor(Armor armor) 93 | { 94 | player.Armor = armor; 95 | return this; 96 | } 97 | 98 | public IPlayerBuilder Reset() 99 | { 100 | player = new Player(); 101 | return this; 102 | } 103 | 104 | public IPlayerBuilder Spicies(Species species) 105 | { 106 | player.Species = species; 107 | return this; 108 | } 109 | 110 | public IPlayerBuilder Type(Type type) 111 | { 112 | player.Type = type; 113 | return this; 114 | } 115 | 116 | public Player Build(){ 117 | return player; 118 | } 119 | } 120 | 121 | public class PlayerManager{ 122 | IPlayerBuilder builder; 123 | 124 | public PlayerManager(IPlayerBuilder builder){ 125 | this.builder = builder; 126 | } 127 | 128 | public void ChangeBuilder(IPlayerBuilder builder){ 129 | this.builder = builder; 130 | } 131 | 132 | public Player BuildSteelDwarf(){ 133 | return builder 134 | .Reset() 135 | .Armor(new SteelArmor()) 136 | .Spicies(new Dwarf()) 137 | .Type(new Normal()) 138 | .Build(); 139 | } 140 | } 141 | 142 | class ClientCode 143 | { 144 | public static void Run() 145 | { 146 | PlayerManager playerManager = new PlayerManager(new PlayerBuilder()); 147 | Player player = playerManager.BuildSteelDwarf(); 148 | player.Play(); 149 | } 150 | } 151 | } 152 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Behavioural/Examples/ChainOfResponsibility.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Behavioral.ChainOfResponsibility{ 2 | namespace Problem{ 3 | public class GameEvent 4 | { 5 | public string EventType { get; set; } 6 | 7 | public GameEvent(string eventType) 8 | { 9 | EventType = eventType; 10 | } 11 | } 12 | 13 | public interface IEventHandler 14 | { 15 | public void HandleEvent(GameEvent gameEvent); 16 | } 17 | 18 | class KeyboardHandler 19 | { 20 | public void HandleEvent(GameEvent gameEvent) 21 | { 22 | Console.WriteLine("KeyboardHandler handled KeyPress event"); 23 | } 24 | } 25 | 26 | class MouseHandler : IEventHandler 27 | { 28 | public void HandleEvent(GameEvent gameEvent) 29 | { 30 | Console.WriteLine("MouseHandler handled MouseClick event"); 31 | } 32 | } 33 | 34 | class CollisionHandler : IEventHandler 35 | { 36 | public void HandleEvent(GameEvent gameEvent) 37 | { 38 | Console.WriteLine("CollisionHandler handled Collision event"); 39 | } 40 | } 41 | 42 | public class Game 43 | { 44 | public Game() 45 | { 46 | GameEvent gameEvent = new GameEvent("Collision"); 47 | 48 | if (gameEvent.EventType == "Collision") 49 | { 50 | new CollisionHandler().HandleEvent(gameEvent); 51 | } 52 | else if (gameEvent.EventType == "KeyPress") 53 | { 54 | new KeyboardHandler().HandleEvent(gameEvent); 55 | } 56 | else if (gameEvent.EventType == "MouseClick") 57 | { 58 | new MouseHandler().HandleEvent(gameEvent); 59 | } 60 | } 61 | } 62 | class ClientCode 63 | { 64 | public static void Run() 65 | { 66 | new Game(); 67 | } 68 | } 69 | 70 | } 71 | namespace Solution{ 72 | public class GameEvent 73 | { 74 | public string EventType { get; set; } 75 | 76 | public GameEvent(string eventType) 77 | { 78 | EventType = eventType; 79 | } 80 | } 81 | 82 | public interface IEventHandler 83 | { 84 | public void SetSuccessor(IEventHandler eventHandler); 85 | public void HandleEvent(GameEvent gameEvent); 86 | } 87 | 88 | public class BaseHandler : IEventHandler 89 | { 90 | protected IEventHandler successor; 91 | private IEventHandler last; 92 | public virtual void HandleEvent(GameEvent gameEvent) 93 | { 94 | if (successor != null) 95 | { 96 | successor.HandleEvent(gameEvent); 97 | } 98 | } 99 | 100 | public void SetSuccessor(IEventHandler eventHandler) 101 | { 102 | if (successor == null) 103 | { 104 | successor = eventHandler; 105 | last = successor; 106 | } 107 | else 108 | { 109 | last.SetSuccessor(eventHandler); 110 | last = eventHandler; 111 | } 112 | } 113 | } 114 | 115 | class KeyboardHandler : BaseHandler 116 | { 117 | public override void HandleEvent(GameEvent gameEvent) 118 | { 119 | if (gameEvent.EventType == "KeyPress") 120 | { 121 | Console.WriteLine("KeyboardHandler handled KeyPress event"); 122 | } 123 | else 124 | { 125 | Console.WriteLine("KeyboardHandler passed the event to the next handler"); 126 | successor.HandleEvent(gameEvent); 127 | } 128 | } 129 | } 130 | 131 | class MouseHandler : BaseHandler 132 | { 133 | public override void HandleEvent(GameEvent gameEvent) 134 | { 135 | if (gameEvent.EventType == "MouseClick") 136 | { 137 | Console.WriteLine("MouseHandler handled MouseClick event"); 138 | } 139 | else 140 | { 141 | Console.WriteLine("MouseHandler passed the event to the next handler"); 142 | successor.HandleEvent(gameEvent); 143 | } 144 | } 145 | } 146 | 147 | class CollisionHandler : BaseHandler 148 | { 149 | public override void HandleEvent(GameEvent gameEvent) 150 | { 151 | if (gameEvent.EventType == "Collision") 152 | { 153 | Console.WriteLine("CollisionHandler handled Collision event"); 154 | } 155 | else 156 | { 157 | Console.WriteLine("CollisionHandler cannot handle this event"); 158 | successor.HandleEvent(gameEvent); 159 | } 160 | } 161 | } 162 | 163 | public class Game 164 | { 165 | public Game() 166 | { 167 | // Creating event handlers 168 | IEventHandler keyboardHandler = new KeyboardHandler(); 169 | 170 | IEventHandler mouseHandler = new MouseHandler(); 171 | IEventHandler collisionHandler = new CollisionHandler(); 172 | IEventHandler baseHandler = new BaseHandler(); 173 | 174 | baseHandler.SetSuccessor(keyboardHandler); 175 | baseHandler.SetSuccessor(mouseHandler); 176 | baseHandler.SetSuccessor(collisionHandler); 177 | 178 | baseHandler.HandleEvent(new GameEvent("Collision")); 179 | } 180 | } 181 | 182 | class ClientCode 183 | { 184 | public static void Run() 185 | { 186 | new Game(); 187 | } 188 | } 189 | 190 | } 191 | } -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Examples/Facade.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Facade{ 2 | 3 | namespace Problem{ 4 | public class SpawnManger 5 | { 6 | public int mobs = 0; 7 | public void SpawnMob() 8 | { 9 | mobs++; 10 | } 11 | public void UnspawnMob() 12 | { 13 | mobs--; 14 | } 15 | } 16 | 17 | public class EnemyManager 18 | { 19 | public int enemies = 0; 20 | public void SpawnEnemie() 21 | { 22 | enemies++; 23 | } 24 | } 25 | 26 | public class EffectManager 27 | { 28 | public void MagicEffect() 29 | { 30 | Console.WriteLine("Magic"); 31 | } 32 | public void FireEffect() 33 | { 34 | Console.WriteLine("Fire"); 35 | } 36 | public void WaterEffect() 37 | { 38 | Console.WriteLine("Water"); 39 | } 40 | } 41 | 42 | class ClientCode 43 | { 44 | public static void Run() 45 | { 46 | EffectManager effectManager = new EffectManager(); 47 | SpawnManger spawnManger = new SpawnManger(); 48 | EnemyManager enemyManager = new EnemyManager(); 49 | 50 | string type = "Fire"; 51 | 52 | if (type == "Magic") 53 | { 54 | effectManager.MagicEffect(); 55 | } 56 | else if (type == "Fire") 57 | { 58 | effectManager.FireEffect(); 59 | } 60 | else if (type == "Water") 61 | { 62 | effectManager.WaterEffect(); 63 | } 64 | else 65 | { 66 | throw new Exception("Effect type doesn't exist"); 67 | } 68 | 69 | Random random = new Random(); 70 | if (random.Next(0, 1) == 0) 71 | { 72 | spawnManger.SpawnMob(); 73 | } 74 | else if (random.Next(0, 1) == 1) 75 | { 76 | enemyManager.SpawnEnemie(); 77 | } 78 | else 79 | { 80 | spawnManger.UnspawnMob(); 81 | } 82 | } 83 | } 84 | } 85 | 86 | namespace Solution{ 87 | public class SpawnManger 88 | { 89 | public int mobs = 0; 90 | public void SpawnMob() 91 | { 92 | mobs++; 93 | } 94 | public void UnspawnMob() 95 | { 96 | mobs--; 97 | } 98 | } 99 | 100 | public class EnemyManager 101 | { 102 | public int enemies = 0; 103 | public void SpawnEnemie() 104 | { 105 | enemies++; 106 | } 107 | } 108 | 109 | public class EffectManager 110 | { 111 | public void MagicEffect() 112 | { 113 | Console.WriteLine("Magic"); 114 | } 115 | public void FireEffect() 116 | { 117 | Console.WriteLine("Fire"); 118 | } 119 | public void WaterEffect() 120 | { 121 | Console.WriteLine("Water"); 122 | } 123 | } 124 | 125 | public interface IManager 126 | { 127 | public void ApplyEffect(string type); 128 | public void RandomSpawn(); 129 | } 130 | 131 | public class Manager : IManager 132 | { 133 | SpawnManger spawnManger; 134 | EffectManager effectManager; 135 | EnemyManager enemyManager; 136 | public Manager() 137 | { 138 | spawnManger = new SpawnManger(); 139 | effectManager = new EffectManager(); 140 | enemyManager = new EnemyManager(); 141 | } 142 | 143 | public void ApplyEffect(string type) 144 | { 145 | if (type == "Magic") 146 | { 147 | effectManager.MagicEffect(); 148 | } 149 | else if (type == "Fire") 150 | { 151 | effectManager.FireEffect(); 152 | } 153 | else if (type == "Water") 154 | { 155 | effectManager.WaterEffect(); 156 | } 157 | else 158 | { 159 | throw new Exception("Effect type doesn't exist"); 160 | } 161 | } 162 | 163 | public void RandomSpawn() 164 | { 165 | Random random = new Random(); 166 | if (random.Next(0, 1) == 0) 167 | { 168 | spawnManger.SpawnMob(); 169 | } 170 | else if (random.Next(0, 1) == 1) 171 | { 172 | enemyManager.SpawnEnemie(); 173 | } 174 | else 175 | { 176 | spawnManger.UnspawnMob(); 177 | } 178 | } 179 | } 180 | 181 | class ClientCode 182 | { 183 | public static void Run() 184 | { 185 | IManager manager = new Manager(); 186 | manager.ApplyEffect("Fire"); 187 | manager.RandomSpawn(); 188 | 189 | EffectManager effectManager = new EffectManager(); 190 | SpawnManger spawnManger = new SpawnManger(); 191 | EnemyManager enemyManager = new EnemyManager(); 192 | 193 | string type = "Fire"; 194 | 195 | if (type == "Magic") 196 | { 197 | effectManager.MagicEffect(); 198 | } 199 | else if (type == "Fire") 200 | { 201 | effectManager.FireEffect(); 202 | } 203 | else if (type == "Water") 204 | { 205 | effectManager.WaterEffect(); 206 | } 207 | else 208 | { 209 | throw new Exception("Effect type doesn't exist"); 210 | } 211 | 212 | Random random = new Random(); 213 | if (random.Next(0, 1) == 0) 214 | { 215 | spawnManger.SpawnMob(); 216 | } 217 | else if (random.Next(0, 1) == 1) 218 | { 219 | enemyManager.SpawnEnemie(); 220 | } 221 | else 222 | { 223 | spawnManger.UnspawnMob(); 224 | } 225 | } 226 | } 227 | } 228 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | Zadace.md 7 | Provjere.md 8 | ZadaciSIspita 9 | Readme.z.md 10 | 11 | # User-specific files 12 | *.rsuser 13 | *.suo 14 | *.user 15 | *.userosscache 16 | *.sln.docstates 17 | 18 | # User-specific files (MonoDevelop/Xamarin Studio) 19 | *.userprefs 20 | 21 | # Mono auto generated files 22 | mono_crash.* 23 | 24 | # Build results 25 | [Dd]ebug/ 26 | [Dd]ebugPublic/ 27 | [Rr]elease/ 28 | [Rr]eleases/ 29 | x64/ 30 | x86/ 31 | [Ww][Ii][Nn]32/ 32 | [Aa][Rr][Mm]/ 33 | [Aa][Rr][Mm]64/ 34 | bld/ 35 | [Bb]in/ 36 | [Oo]bj/ 37 | [Oo]ut/ 38 | [Ll]og/ 39 | [Ll]ogs/ 40 | 41 | # Visual Studio 2015/2017 cache/options directory 42 | .vs/ 43 | # Uncomment if you have tasks that create the project's static files in wwwroot 44 | #wwwroot/ 45 | 46 | # Visual Studio 2017 auto generated files 47 | Generated\ Files/ 48 | 49 | # MSTest test Results 50 | [Tt]est[Rr]esult*/ 51 | [Bb]uild[Ll]og.* 52 | 53 | # NUnit 54 | *.VisualState.xml 55 | TestResult.xml 56 | nunit-*.xml 57 | 58 | # Build Results of an ATL Project 59 | [Dd]ebugPS/ 60 | [Rr]eleasePS/ 61 | dlldata.c 62 | 63 | # Benchmark Results 64 | BenchmarkDotNet.Artifacts/ 65 | 66 | # .NET Core 67 | project.lock.json 68 | project.fragment.lock.json 69 | artifacts/ 70 | 71 | # ASP.NET Scaffolding 72 | ScaffoldingReadMe.txt 73 | 74 | # StyleCop 75 | StyleCopReport.xml 76 | 77 | # Files built by Visual Studio 78 | *_i.c 79 | *_p.c 80 | *_h.h 81 | *.ilk 82 | *.meta 83 | *.obj 84 | *.iobj 85 | *.pch 86 | *.pdb 87 | *.ipdb 88 | *.pgc 89 | *.pgd 90 | *.rsp 91 | *.sbr 92 | *.tlb 93 | *.tli 94 | *.tlh 95 | *.tmp 96 | *.tmp_proj 97 | *_wpftmp.csproj 98 | *.log 99 | *.vspscc 100 | *.vssscc 101 | .builds 102 | *.pidb 103 | *.svclog 104 | *.scc 105 | 106 | # Chutzpah Test files 107 | _Chutzpah* 108 | 109 | # Visual C++ cache files 110 | ipch/ 111 | *.aps 112 | *.ncb 113 | *.opendb 114 | *.opensdf 115 | *.sdf 116 | *.cachefile 117 | *.VC.db 118 | *.VC.VC.opendb 119 | 120 | # Visual Studio profiler 121 | *.psess 122 | *.vsp 123 | *.vspx 124 | *.sap 125 | 126 | # Visual Studio Trace Files 127 | *.e2e 128 | 129 | # TFS 2012 Local Workspace 130 | $tf/ 131 | 132 | # Guidance Automation Toolkit 133 | *.gpState 134 | 135 | # ReSharper is a .NET coding add-in 136 | _ReSharper*/ 137 | *.[Rr]e[Ss]harper 138 | *.DotSettings.user 139 | 140 | # TeamCity is a build add-in 141 | _TeamCity* 142 | 143 | # DotCover is a Code Coverage Tool 144 | *.dotCover 145 | 146 | # AxoCover is a Code Coverage Tool 147 | .axoCover/* 148 | !.axoCover/settings.json 149 | 150 | # Coverlet is a free, cross platform Code Coverage Tool 151 | coverage*.json 152 | coverage*.xml 153 | coverage*.info 154 | 155 | # Visual Studio code coverage results 156 | *.coverage 157 | *.coveragexml 158 | 159 | # NCrunch 160 | _NCrunch_* 161 | .*crunch*.local.xml 162 | nCrunchTemp_* 163 | 164 | # MightyMoose 165 | *.mm.* 166 | AutoTest.Net/ 167 | 168 | # Web workbench (sass) 169 | .sass-cache/ 170 | 171 | # Installshield output folder 172 | [Ee]xpress/ 173 | 174 | # DocProject is a documentation generator add-in 175 | DocProject/buildhelp/ 176 | DocProject/Help/*.HxT 177 | DocProject/Help/*.HxC 178 | DocProject/Help/*.hhc 179 | DocProject/Help/*.hhk 180 | DocProject/Help/*.hhp 181 | DocProject/Help/Html2 182 | DocProject/Help/html 183 | 184 | # Click-Once directory 185 | publish/ 186 | 187 | # Publish Web Output 188 | *.[Pp]ublish.xml 189 | *.azurePubxml 190 | # Note: Comment the next line if you want to checkin your web deploy settings, 191 | # but database connection strings (with potential passwords) will be unencrypted 192 | *.pubxml 193 | *.publishproj 194 | 195 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 196 | # checkin your Azure Web App publish settings, but sensitive information contained 197 | # in these scripts will be unencrypted 198 | PublishScripts/ 199 | 200 | # NuGet Packages 201 | *.nupkg 202 | # NuGet Symbol Packages 203 | *.snupkg 204 | # The packages folder can be ignored because of Package Restore 205 | **/[Pp]ackages/* 206 | # except build/, which is used as an MSBuild target. 207 | !**/[Pp]ackages/build/ 208 | # Uncomment if necessary however generally it will be regenerated when needed 209 | #!**/[Pp]ackages/repositories.config 210 | # NuGet v3's project.json files produces more ignorable files 211 | *.nuget.props 212 | *.nuget.targets 213 | 214 | # Microsoft Azure Build Output 215 | csx/ 216 | *.build.csdef 217 | 218 | # Microsoft Azure Emulator 219 | ecf/ 220 | rcf/ 221 | 222 | # Windows Store app package directories and files 223 | AppPackages/ 224 | BundleArtifacts/ 225 | Package.StoreAssociation.xml 226 | _pkginfo.txt 227 | *.appx 228 | *.appxbundle 229 | *.appxupload 230 | 231 | # Visual Studio cache files 232 | # files ending in .cache can be ignored 233 | *.[Cc]ache 234 | # but keep track of directories ending in .cache 235 | !?*.[Cc]ache/ 236 | 237 | # Others 238 | ClientBin/ 239 | ~$* 240 | *~ 241 | *.dbmdl 242 | *.dbproj.schemaview 243 | *.jfm 244 | *.pfx 245 | *.publishsettings 246 | orleans.codegen.cs 247 | 248 | # Including strong name files can present a security risk 249 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 250 | #*.snk 251 | 252 | # Since there are multiple workflows, uncomment next line to ignore bower_components 253 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 254 | #bower_components/ 255 | 256 | # RIA/Silverlight projects 257 | Generated_Code/ 258 | 259 | # Backup & report files from converting an old project file 260 | # to a newer Visual Studio version. Backup files are not needed, 261 | # because we have git ;-) 262 | _UpgradeReport_Files/ 263 | Backup*/ 264 | UpgradeLog*.XML 265 | UpgradeLog*.htm 266 | ServiceFabricBackup/ 267 | *.rptproj.bak 268 | 269 | # SQL Server files 270 | *.mdf 271 | *.ldf 272 | *.ndf 273 | 274 | # Business Intelligence projects 275 | *.rdl.data 276 | *.bim.layout 277 | *.bim_*.settings 278 | *.rptproj.rsuser 279 | *- [Bb]ackup.rdl 280 | *- [Bb]ackup ([0-9]).rdl 281 | *- [Bb]ackup ([0-9][0-9]).rdl 282 | 283 | # Microsoft Fakes 284 | FakesAssemblies/ 285 | 286 | # GhostDoc plugin setting file 287 | *.GhostDoc.xml 288 | 289 | # Node.js Tools for Visual Studio 290 | .ntvs_analysis.dat 291 | node_modules/ 292 | 293 | # Visual Studio 6 build log 294 | *.plg 295 | 296 | # Visual Studio 6 workspace options file 297 | *.opt 298 | 299 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 300 | *.vbw 301 | 302 | # Visual Studio LightSwitch build output 303 | **/*.HTMLClient/GeneratedArtifacts 304 | **/*.DesktopClient/GeneratedArtifacts 305 | **/*.DesktopClient/ModelManifest.xml 306 | **/*.Server/GeneratedArtifacts 307 | **/*.Server/ModelManifest.xml 308 | _Pvt_Extensions 309 | 310 | # Paket dependency manager 311 | .paket/paket.exe 312 | paket-files/ 313 | 314 | # FAKE - F# Make 315 | .fake/ 316 | 317 | # CodeRush personal settings 318 | .cr/personal 319 | 320 | # Python Tools for Visual Studio (PTVS) 321 | __pycache__/ 322 | *.pyc 323 | 324 | # Cake - Uncomment if you are using it 325 | # tools/** 326 | # !tools/packages.config 327 | 328 | # Tabs Studio 329 | *.tss 330 | 331 | # Telerik's JustMock configuration file 332 | *.jmconfig 333 | 334 | # BizTalk build output 335 | *.btp.cs 336 | *.btm.cs 337 | *.odx.cs 338 | *.xsd.cs 339 | 340 | # OpenCover UI analysis results 341 | OpenCover/ 342 | 343 | # Azure Stream Analytics local run output 344 | ASALocalRun/ 345 | 346 | # MSBuild Binary and Structured Log 347 | *.binlog 348 | 349 | # NVidia Nsight GPU debugger configuration file 350 | *.nvuser 351 | 352 | # MFractors (Xamarin productivity tool) working folder 353 | .mfractor/ 354 | 355 | # Local History for Visual Studio 356 | .localhistory/ 357 | 358 | # BeatPulse healthcheck temp database 359 | healthchecksdb 360 | 361 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 362 | MigrationBackup/ 363 | 364 | # Ionide (cross platform F# VS Code tools) working folder 365 | .ionide/ 366 | 367 | # Fody - auto-generated XML schema 368 | FodyWeavers.xsd -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/DesignPatterns/Structural/Examples/Proxy.cs: -------------------------------------------------------------------------------- 1 | namespace DevOfSwSuppWithOOP.DesignPatterns.Structural.Proxy{ 2 | namespace Problem{ 3 | public interface IChatGPTService{ 4 | public void SendPrompt(string prompt); 5 | } 6 | 7 | public class ChatGPTService: IChatGPTService{ 8 | public void SendPrompt(string prompt){ 9 | Console.WriteLine($"Prompt was sent: {prompt}"); 10 | } 11 | } 12 | 13 | public static class ClientCode 14 | { 15 | public static void Run() 16 | { 17 | //ovo radi ok ali zelimo veću kontrolu nad servisom, 18 | //kako ćemo to postići 19 | IChatGPTService chatGPTService = new ChatGPTService(); 20 | chatGPTService.SendPrompt("Hello"); 21 | } 22 | } 23 | 24 | } 25 | 26 | namespace Solution{ 27 | public interface IChatGPTService{ 28 | public void SendPrompt(string prompt); 29 | } 30 | 31 | public class ChatGPTService: IChatGPTService{ 32 | public void SendPrompt(string prompt){ 33 | Console.WriteLine($"Prompt was sent: {prompt}"); 34 | } 35 | } 36 | 37 | public class ChatGPTProxy:IChatGPTService{ 38 | IChatGPTService chatGPTService; 39 | public ChatGPTProxy( IChatGPTService chatGPTService){ 40 | this.chatGPTService = chatGPTService; 41 | } 42 | public void SendPrompt(string prompt){ 43 | chatGPTService.SendPrompt(prompt); 44 | } 45 | } 46 | 47 | public static class ClientCode 48 | { 49 | public static void Run() 50 | { 51 | IChatGPTService chatGPTService = new ChatGPTProxy(new ChatGPTService()); 52 | chatGPTService.SendPrompt("Hello"); 53 | } 54 | } 55 | } 56 | 57 | namespace Examples{ 58 | namespace VirtualProxy{ 59 | public interface IChatGPTService{ 60 | public void SendPrompt(string prompt); 61 | } 62 | 63 | public class ChatGPTService: IChatGPTService{ 64 | public void SendPrompt(string prompt){ 65 | Console.WriteLine($"Prompt was sent: {prompt}"); 66 | } 67 | } 68 | 69 | public class ChatGPTProxy:IChatGPTService{ 70 | IChatGPTService chatGPTService; 71 | 72 | public void SendPrompt(string prompt){ 73 | //ljena inicializacija 74 | if(chatGPTService == null){ 75 | chatGPTService = new ChatGPTService(); 76 | } 77 | chatGPTService.SendPrompt(prompt); 78 | } 79 | } 80 | 81 | public static class ClientCode 82 | { 83 | public static void Run() 84 | { 85 | //više se servis ne inicijalizira ovdje 86 | IChatGPTService chatGPTService = new ChatGPTProxy(); 87 | //nego pozivom SendPrompt funkcije 88 | chatGPTService.SendPrompt("Hello"); 89 | } 90 | } 91 | } 92 | 93 | namespace ProtectionProxy{ 94 | public interface IChatGPTService{ 95 | public void SendPrompt(string prompt); 96 | } 97 | 98 | public class ChatGPTService: IChatGPTService{ 99 | public void SendPrompt(string prompt){ 100 | Console.WriteLine($"Prompt was sent: {prompt}"); 101 | } 102 | } 103 | 104 | public class ChatGPTProxy:IChatGPTService{ 105 | IChatGPTService chatGPTService; 106 | public ChatGPTProxy(string username, string password){ 107 | if(AuthenticationService.Authenticate(username, password)){} 108 | chatGPTService = new ChatGPTService(); 109 | } 110 | 111 | public void SendPrompt(string prompt){ 112 | chatGPTService.SendPrompt(prompt); 113 | } 114 | } 115 | 116 | public static class AuthenticationService{ 117 | public static bool Authenticate(string username, string password){ 118 | //auth proces, ako user nije u bazi podataka vraca false inace true 119 | return true;// za svrhe primjera uvijek true 120 | } 121 | } 122 | 123 | public static class ClientCode 124 | { 125 | public static void Run() 126 | { 127 | IChatGPTService chatGPTService = new ChatGPTProxy("Filip","123"); 128 | chatGPTService.SendPrompt("Hello"); 129 | } 130 | } 131 | } 132 | 133 | namespace LoggingProxy{ 134 | public interface IChatGPTService{ 135 | public void SendPrompt(string prompt); 136 | } 137 | 138 | public class ChatGPTService: IChatGPTService{ 139 | public void SendPrompt(string prompt){ 140 | Console.WriteLine($"Prompt was sent: {prompt}"); 141 | } 142 | } 143 | 144 | public class ChatGPTProxy:IChatGPTService{ 145 | IChatGPTService chatGPTService; 146 | public ChatGPTProxy( IChatGPTService chatGPTService){ 147 | this.chatGPTService = chatGPTService; 148 | Console.WriteLine("ChatGPTService instantiated"); 149 | } 150 | public void SendPrompt(string prompt){ 151 | chatGPTService.SendPrompt(prompt); 152 | Console.WriteLine("Prompt sent"); 153 | } 154 | } 155 | 156 | public static class ClientCode 157 | { 158 | public static void Run() 159 | { 160 | IChatGPTService chatGPTService = new ChatGPTProxy(new ChatGPTService()); 161 | chatGPTService.SendPrompt("Hello"); 162 | } 163 | } 164 | } 165 | 166 | namespace CachingProxy{ 167 | public interface IChatGPTService{ 168 | public void SendPrompt(string prompt); 169 | public void LogPromptHistory(); 170 | } 171 | 172 | public class ChatGPTService: IChatGPTService{ 173 | private string lastPrompt; 174 | public void SendPrompt(string prompt){ 175 | Console.WriteLine($"Prompt was sent: {prompt}"); 176 | lastPrompt = prompt; 177 | } 178 | //pamti zadnj prompt a mi želimo sve promptove pamtiti 179 | public void LogPromptHistory(){ 180 | Console.WriteLine(lastPrompt); 181 | } 182 | } 183 | 184 | public class ChatGPTProxy:IChatGPTService{ 185 | IChatGPTService chatGPTService; 186 | List promtps; 187 | public ChatGPTProxy( IChatGPTService chatGPTService){ 188 | this.chatGPTService = chatGPTService; 189 | promtps = new List(); 190 | } 191 | 192 | public void SendPrompt(string prompt){ 193 | chatGPTService.SendPrompt(prompt); 194 | promtps.Add(prompt); 195 | } 196 | 197 | public void LogPromptHistory(){ 198 | Console.WriteLine("History"); 199 | promtps.ForEach(prompt=>{ 200 | Console.WriteLine(prompt); 201 | }); 202 | } 203 | } 204 | 205 | public static class ClientCode 206 | { 207 | public static void Run() 208 | { 209 | IChatGPTService chatGPTService = new ChatGPTProxy(new ChatGPTService()); 210 | chatGPTService.SendPrompt("Hello"); 211 | chatGPTService.SendPrompt("World"); 212 | chatGPTService.SendPrompt("Hows the weather"); 213 | chatGPTService.SendPrompt("Proxy this u fn casual"); 214 | chatGPTService.LogPromptHistory(); 215 | } 216 | } 217 | } 218 | } 219 | } -------------------------------------------------------------------------------- /README.z.md: -------------------------------------------------------------------------------- 1 | ```cs 2 | interface Ciphering { 3 | string Encryption(string text); 4 | string Decryption(string text); 5 | } 6 | 7 | class CeasarCipherAlgorithm : Ciphering { 8 | public string Encryption(string text) { 9 | // Implement Caesar cipher encryption logic 10 | } 11 | 12 | public string Decryption(string text) { 13 | // Implement Caesar cipher decryption logic 14 | } 15 | } 16 | 17 | class TheMessage { 18 | public string plaintext { get; private set; } // The readable text is called 'plaintext' in cryptography 19 | private Ciphering algorithmOfCipher; 20 | 21 | public TheMessage(string text, Ciphering cipher) { 22 | plaintext = text; 23 | algorithmOfCipher = cipher; 24 | } 25 | 26 | public void ChangePlaintextValue(string text) { 27 | plaintext = text; 28 | } 29 | 30 | public void AdjustCipher(Ciphering cipher) { 31 | algorithmOfCipher = cipher; 32 | } 33 | 34 | public string EncryptTheMessage() { 35 | return algorithmOfCipher.Encryption(plaintext); // Returns the ciphertext (the encrypted text) 36 | } 37 | } 38 | 39 | ``` 40 | 41 | 42 | Nakodiraj jedan primjer čvrste sprege i jedan primjer labave sprege. 43 | 44 | 45 | 46 | Refaktorirajte kod dan u sljedećem izlistanju. U crticama objasnite što i zašto je obuhvaćeno refaktoriranjem 47 | ```cs 48 | List extraction (List 1st){ 49 | List extract = new List(); 50 | double avg = 0; 51 | foreach (int el in 1st) 52 | avg+= el; 53 | avg / 1st.Count; 54 | 55 | foreach (int el in 1st) 56 | if (el > avg) extract.Add(el): 57 | return extract; 58 | } 59 | ``` 60 | 61 | ```cs 62 | List FindGreaterThanAverage(List numbers){ 63 | List greaterThanAverage = new(); 64 | double average = FindAverage(numbers) 65 | foreach (int numbers in numbers) 66 | if (number > average) greaterThanAverage.Add(number); 67 | return greaterThanAverage; 68 | } 69 | 70 | double FindAverage(List numbers){ 71 | double sum = 0; 72 | foreach (int number in numbers) 73 | sum+= number; 74 | return sum / numbers.Count; 75 | } 76 | ``` 77 | 78 | 79 | 80 | 81 | 82 | Objasnite što je načelo "open-closed". Dajte primjer pseudokoda koji ga narušava i objasnite u čemu se to ogleda i zašto je to problem. Prepravite kod tako da poštuje navedeno načelo. 83 | 84 | 85 | 86 | 87 | 88 | Objasnite liskov princip. Dajte primjer pseudokoda koji ga narušava i objasnite u čemu se to ogleda i zašto je to problem. 89 | ```cs 90 | public interface IAttack{int TotalDamage { get; }} 91 | public class PhysicalAttack : IAttack{ 92 | private const int BoostFactor = 2; 93 | public PhysicalAttack(bool isBoosted, int damage){ 94 | IsBoosted = isBoosted; 95 | Damage = damage; 96 | } 97 | public bool IsBoosted { get; private set; } 98 | public int Damage { get; private set; } 99 | public int TotalDamage{ 100 | get { return IsBoosted ? BoostFactor * Damage : Damage; } 101 | } 102 | } 103 | public class ComboAttack : IAttack{ 104 | private List attacks = new List(); 105 | public void Add(IAttack attack){ 106 | attacks.Add(attack); 107 | } 108 | public void Remove(IAttack attack){ 109 | attacks.Remove(attack); 110 | } 111 | public int TotalDamage{ 112 | get{ 113 | int totalDamage = 0; 114 | foreach (var attack in attacks){ 115 | totalDamage += attack.TotalDamage; 116 | } 117 | return totalDamage; 118 | } 119 | } 120 | } 121 | ``` 122 | 123 | 124 | 125 | 126 | 127 | 128 | Nacrtaj klasni dijagram Proxy obrasca, navedi dvije posljedice i napiši njegovu svrhu. 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | Primjeri napravljeni na predavanju: 137 | ```c# 138 | //singleton class 139 | public class GameManager 140 | { 141 | private static GameManager gameManager; 142 | 143 | public static GameManager GetGameManager() 144 | { // lazy initialization 145 | if (gameManager == null) 146 | { 147 | gameManager = new GameManager(); 148 | } 149 | return gameManager; 150 | } 151 | 152 | public void GetConfigs() 153 | { 154 | Console.WriteLine("Configs"); 155 | } 156 | } 157 | 158 | //Usage 159 | static void Main(string[] args) 160 | { 161 | GameManager gameManager = new GameManager() 162 | gameManager.GetConfigs(); 163 | } 164 | ``` 165 | 166 | 167 | enum Engine {V8, V6, W12} 168 | enum Tires {Winter, Summer} 169 | enum Collor {Red, Black, Gray} 170 | 171 | class CarDirector{ 172 | Car car1 = new Car(); 173 | IDrivable carBuilder; 174 | public CarDirector(IDrivable carBuilder){ 175 | this.carBuilder = carBuilder; 176 | } 177 | 178 | public Car BuildRedV8(){ 179 | return carBuilder.AddEngine(Engine.V8).AddCollor(Collor.Red).Build(); 180 | } 181 | } 182 | 183 | interface IDrivable { 184 | public CarBuilder AddEngine(Engine engine); 185 | public CarBuilder AddCollor(Collor collor); 186 | public CarBuilder AddTires(Tires tires); 187 | } 188 | 189 | interface IClonable{ 190 | public object Clone(); 191 | } 192 | 193 | 194 | 195 | class Car:IClonable{ 196 | CarDirector carDirector1 = new CarDirector(new CarBuilder()); 197 | private string name; 198 | public Engine Engine {get;set;} 199 | public Tires Tires {get;set;} 200 | public Collor Collor {get;set;} 201 | public Car(Engine engine, Tires tires, Collor collor, string name) { 202 | Engine = engine; 203 | Tires = tires; 204 | Collor = collor; 205 | this.name = name; 206 | } 207 | 208 | public Car(){} 209 | 210 | public object Clone() 211 | { 212 | Car car = new Car(this.Engine,this.Tires,this.Collor,this.name); 213 | return car; 214 | } 215 | //... 216 | } 217 | 218 | class CarBuilder:IDrivable{ 219 | Car car; 220 | public CarBuilder(){ 221 | car = new Car(); 222 | } 223 | 224 | public CarBuilder AddEngine(Engine engine){ 225 | car.Engine = engine; 226 | return this; 227 | } 228 | 229 | public CarBuilder AddTires(Tires tires){ 230 | car.Tires = tires; 231 | return this; 232 | } 233 | 234 | public CarBuilder AddCollor(Collor collor){ 235 | car.Collor = collor; 236 | return this; 237 | } 238 | 239 | public CarBuilder Reset(){ 240 | car = new Car(); 241 | return this; 242 | } 243 | 244 | public Car Build(){ 245 | return car; 246 | } 247 | 248 | } 249 | 250 | 251 | 252 | 253 | 254 | class CharacterManager{ 255 | IBuildable characterBuilder; 256 | 257 | public CharacterManager(IBuildable characterBuilder) { 258 | this.characterBuilder = characterBuilder; 259 | } 260 | 261 | public void ChangeBuilder(IBuildable characterBuilder) { 262 | this.characterBuilder = characterBuilder; 263 | } 264 | 265 | public Character SteelDwarf(Height height, Sex sex){ 266 | return characterBuilder 267 | .Reset() 268 | .SetRace(Race.Dwarf) 269 | .SetArmor(Armor.Steel) 270 | .SetHeight(height) 271 | .SetSex(sex) 272 | .Build(); 273 | } 274 | } 275 | 276 | enum Race{Elf, Dwarf, Orc} 277 | enum Armor{Steel, Leather, NoArmor} 278 | enum Height {Short, Mid, Tall, Giant} 279 | enum Sex{Male, Female, Other} 280 | 281 | class Character: ICloneable{ 282 | private string weight; 283 | public string Name {get; set;} 284 | public Race Race { get; set;} 285 | public Height Height { get; set;} 286 | public Armor Armor { get; set;} 287 | public Sex Sex { get; set;} 288 | 289 | public Character(string name, Race race, Height height, Armor armor, Sex sex){ 290 | this.Name = name; 291 | Race = race; 292 | Height = height; 293 | Armor = armor; 294 | Sex = sex; 295 | } 296 | 297 | public object Clone(){ 298 | Character character = new Character(this.Name,this.Race,this.Height,this.Armor,this.Sex); 299 | character.weight = this.weight; 300 | return character; 301 | } 302 | 303 | public Character(){} 304 | //...neke metode 305 | } 306 | 307 | interface IClonable{ 308 | public object Clone(); 309 | } 310 | 311 | interface IBuildable{ 312 | public CharacterBuilder Reset(); 313 | public CharacterBuilder SetName(string name); 314 | public CharacterBuilder SetRace(Race race); 315 | public CharacterBuilder SetHeight(Height height); 316 | public CharacterBuilder SetArmor(Armor arm); 317 | public CharacterBuilder SetSex(Sex sex); 318 | public Character Build(); 319 | } 320 | 321 | class CharacterBuilder:IBuildable{ 322 | private Character character; 323 | 324 | public CharacterBuilder(){ 325 | this.character = new Character(); 326 | } 327 | 328 | public CharacterBuilder SetName(string name){ 329 | this.character.Name = name; 330 | return this; 331 | } 332 | 333 | public CharacterBuilder SetRace(Race race){ 334 | this.character.Race = race; 335 | return this; 336 | } 337 | 338 | public CharacterBuilder SetHeight(Height height){ 339 | this.character.Height = height; 340 | return this; 341 | } 342 | 343 | public CharacterBuilder SetSex(Sex sex){ 344 | this.character.Sex = sex; 345 | return this; 346 | } 347 | 348 | public CharacterBuilder SetArmor(Armor armor){ 349 | this.character.Armor = armor; 350 | return this; 351 | } 352 | 353 | public CharacterBuilder Reset(){ 354 | character = new Character(); 355 | return this; 356 | } 357 | 358 | public Character Build() 359 | { 360 | return this.character; 361 | } 362 | } 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/SOLID/README.hr.md: -------------------------------------------------------------------------------- 1 | # SOLID načela 2 | U ovom poglavlju biti će objašnjeni SOLID principi kodiranja programske podrške u objektno orjentiranim jezicima. Koncepti objašnjeni ovdje vrijede za skoro sve oop jezike. Primjeri ovdje su programirani u C# programskom jeziku. Cilj poglavlja je detaljno i jasno objasniti čitaču svaki od principa te pokazati kako ih primjeniti na jednostavnim primjerima. 3 | 4 | SOLID je akronim koji označava pet principa objektno orijentiranog dizajna koji promiču čvrsto, održivo i fleksibilno programiranje. Ovi principi čine temelj dobre prakse u razvoju softvera. 5 | 6 | - S, Single responsibilty principle (SRP) 7 | - O, Open closed principle (OCP) 8 | - L, Lisk substitution principle (LSP) 9 | - I, Interface segregation principle (ISP) 10 | - D, Dependency inversion principle (DIP) 11 | 12 | Za svaki 13 | Teorija 14 | Profin primjer ili sličan profinom primjeru 15 | Primjer staviti u kod 16 | 17 | ## SRP 18 | Svaka klasa treba imati samo jednu odgovornost, odnosno odgovornost za jednu funkcionalnost 19 | 20 | Neispravno: 21 | ```cs 22 | class User{ 23 | int id; 24 | string Name{get; private set;} 25 | string Surname{get; private set;} 26 | } 27 | 28 | class Bank{ 29 | List users; 30 | public Bank(){ 31 | users = new Users(); 32 | } 33 | 34 | public void AddUser(User user){ 35 | users.Add(user); 36 | } 37 | 38 | public void RemoveUser(User user){ 39 | users.Remove(user) 40 | } 41 | 42 | //pripada li ova funkcionalnost ovdje? 43 | public void LogUserData(User user){ 44 | Console.WriteLine($"{user.Name}, {user.Surname}") 45 | } 46 | 47 | //pripada li ova funkcionalnost ovdje? 48 | public JSONFile ExportToJSON(){ 49 | Console.WriteLine($"Export to JSON") 50 | } 51 | } 52 | ``` 53 | Primjer iznad krši SRP jer klasa Bank ima dodatne odgovornosti nevezane za nju u obliku LogUserData i ExportToJSON metoda. Metode nevezane za klasu Bank potrebno je izdvojiti u odvojene klase. 54 | 55 | Ispravno: 56 | ```cs 57 | class Bank{ 58 | List users; 59 | public Bank(){ 60 | users = new Users(); 61 | } 62 | 63 | public void AddUser(User user){ 64 | users.Add(user); 65 | } 66 | 67 | public void RemoveUser(User user){ 68 | users.Remove(user) 69 | } 70 | } 71 | 72 | class UserLogger{ 73 | public void LogUserData(User user){ 74 | Console.WriteLine($"{user.Name}, {user.Surname}") 75 | } 76 | } 77 | 78 | class JSONExporter{ 79 | public JSONFile ExportToJSON(){ 80 | Console.WriteLine($"Export to JSON") 81 | } 82 | } 83 | ``` 84 | Primjer iznad prati SRP je sada svaka klasa ima jednu odgovornost tj. odgovorna je za jednu funkcionlanost. 85 | 86 | ## OCP 87 | Klase trebaju biti zatvorene za izmjene, ali otvorene za prosirenja 88 | 89 | Primjer dolje je sa https://makolyte.com/refactoring-the-switch-statement-code-smell/ 90 | 91 | Problem: 92 | ```cs 93 | public class Bird 94 | { 95 | private readonly BirdType birdType; 96 | 97 | public Bird(BirdType type) 98 | { 99 | birdType = type; 100 | } 101 | public List GetColors() 102 | { 103 | switch (birdType) 104 | { 105 | case BirdType.Cardinal: 106 | return new List() { BirdColor.Black, BirdColor.Red }; 107 | case BirdType.Goldfinch: 108 | return new List() { BirdColor.Black, BirdColor.Yellow, BirdColor.White }; 109 | case BirdType.Chickadee: 110 | return new List() { BirdColor.Black, BirdColor.White, BirdColor.Tan }; 111 | } 112 | throw new InvalidBirdTypeException(); 113 | } 114 | public List GetFoods() 115 | { 116 | switch (birdType) 117 | { 118 | case BirdType.Cardinal: 119 | return new List() { BirdFood.Insects, BirdFood.Seeds, BirdFood.Fruit}; 120 | case BirdType.Goldfinch: 121 | return new List() { BirdFood.Insects, BirdFood.Seeds }; 122 | case BirdType.Chickadee: 123 | return new List() { BirdFood.Insects, BirdFood.Fruit, BirdFood.Seeds }; 124 | } 125 | throw new InvalidBirdTypeException(); 126 | } 127 | public BirdSizeRange GetSizeRange() 128 | { 129 | switch (birdType) 130 | { 131 | case BirdType.Cardinal: 132 | return new BirdSizeRange() { Lower=8, Upper=9 }; 133 | case BirdType.Goldfinch: 134 | return new BirdSizeRange() { Lower=4.5, Upper=5.5 }; 135 | case BirdType.Chickadee: 136 | return new BirdSizeRange() { Lower=4.75, Upper=5.75 }; 137 | } 138 | throw new InvalidBirdTypeException(); 139 | } 140 | } 141 | ``` 142 | Primjer iznad krši OCP jer kako bi dodali funkcionalnost za jos jednu vrstu ptice potrebno je nadograditi switch u svakoj od metoda sa novim slučajem korištenja. 143 | 144 | Rješenje: 145 | ```cs 146 | public abstract class Bird 147 | { 148 | public abstract List GetColors(); 149 | public abstract List GetFoods(); 150 | public abstract BirdSizeRange GetSizeRange(); 151 | 152 | public static Bird Create(BirdType birdType) 153 | { 154 | switch (birdType) 155 | { 156 | case BirdType.Cardinal: 157 | return new Cardinal(); 158 | case BirdType.Chickadee: 159 | return new Chickadee(); 160 | case BirdType.Goldfinch: 161 | return new Goldfinch(); 162 | default: 163 | throw new InvalidBirdTypeException(); 164 | } 165 | } 166 | } 167 | 168 | public class Cardinal : Bird 169 | { 170 | public override List GetColors() 171 | { 172 | return new List() { BirdColor.Black, BirdColor.Red }; 173 | } 174 | 175 | public override List GetFoods() 176 | { 177 | return new List() { BirdFood.Insects, BirdFood.Seeds, BirdFood.Fruit }; 178 | } 179 | 180 | public override BirdSizeRange GetSizeRange() 181 | { 182 | return new BirdSizeRange() { Lower = 8, Upper = 9 }; 183 | } 184 | } 185 | 186 | public class Chickadee : Bird 187 | { 188 | public override List GetColors() 189 | { 190 | return new List() { BirdColor.Black, BirdColor.White, BirdColor.Tan }; 191 | } 192 | 193 | public override List GetFoods() 194 | { 195 | return new List() { BirdFood.Insects, BirdFood.Fruit, BirdFood.Seeds }; 196 | } 197 | 198 | public override BirdSizeRange GetSizeRange() 199 | { 200 | return new BirdSizeRange() { Lower = 4.75, Upper = 5.75 }; 201 | } 202 | } 203 | 204 | public class Goldfinch: Bird 205 | { 206 | public override List GetColors() 207 | { 208 | return new List() { BirdColor.Black, BirdColor.Yellow, BirdColor.White }; 209 | } 210 | 211 | public override List GetFoods() 212 | { 213 | return new List() { BirdFood.Insects, BirdFood.Seeds }; 214 | } 215 | 216 | public override BirdSizeRange GetSizeRange() 217 | { 218 | return new BirdSizeRange() { Lower = 4.5, Upper = 5.5 }; 219 | } 220 | } 221 | ``` 222 | Primjer iznad slijedi OCP jer kako bi dodali funkcionalnost za novu vrstu pticu potrebno je izvesti jos jednu konkretnu pticu iz apstraktne klase Bird tj. nije potrebno mijenjati postojeći kod. 223 | 224 | ## LSP 225 | Izvedene klase trebaju moci zamijeniti osnovnu. Kršenje LSP dovodi do kršenja OCP. 226 | 227 | Problem: 228 | ```cs 229 | class Bird{ 230 | public virtual void Walk(){ 231 | Console.WriteLine($"Bird is walking"); 232 | } 233 | public virtual void Fly(){ 234 | Console.WriteLine($"Bird is jumping"); 235 | } 236 | } 237 | 238 | class Emu:Bird{ 239 | public override void Walk(){ 240 | Console.WriteLine($"Bird is walking fast"); 241 | } 242 | public override void Fly(){ 243 | throw new NotImplementedException (); 244 | } 245 | } 246 | 247 | class BirdContoler{ 248 | List birds; 249 | public Birds {set{birds = value;}} 250 | 251 | public void MakeBirdsWalk(){ 252 | foreach(bird in birds){ 253 | bird.Walk(); 254 | } 255 | } 256 | 257 | public void MakeBirdsFLy(){ 258 | foreach(bird in birds){ 259 | bird.Fly();//šta kad naleti na emua? 260 | } 261 | } 262 | } 263 | ``` 264 | Primjer iznad krši LSP jer klasa Bird i klasa Emu nisu medjusobno zamjenjive jer klasa Emu forsira implementaciju metoide Fly. 265 | 266 | Rješenje 1: 267 | ```cs 268 | //prve dvije klase ostaju iste 269 | class BirdContoler{ 270 | List birds; 271 | public Birds {set{birds = value;}} 272 | 273 | public void MakeBirdsWalk(){ 274 | foreach(bird in birds){ 275 | bird.Walk(); 276 | } 277 | } 278 | 279 | //Krsi OCP 280 | public void MakeBirdsFLy(){ 281 | foreach(bird in birds){ 282 | if(bird.GetType() != typeof(Emu)) 283 | bird.Fly(); 284 | } 285 | } 286 | } 287 | ``` 288 | Primjer iznad ne krši LSP no krši OCP jer sad za svak pticu koja ne leti trebamo ažurirati i metodu MakeBirdsFly. 289 | 290 | Rješenje 2: 291 | ```cs 292 | interface IFlyable{ 293 | public void Fly(); 294 | } 295 | 296 | interface IWalkable{ 297 | public void Walk(); 298 | } 299 | 300 | class Emu:IWalkable{ 301 | public void Walk(){ 302 | Console.WriteLine($"Bird is walking fast"); 303 | } 304 | } 305 | 306 | class Sparrow: IFlyable, IWalkable{ 307 | public void Walk(){ 308 | Console.WriteLine($"Bird is walking fast"); 309 | } 310 | 311 | public void Fly(){ 312 | Console.WriteLine($"Bird is flying fast"); 313 | } 314 | } 315 | 316 | class BirdControler{ 317 | public void MakeBirdsFly(List birds){ 318 | foreach(IFlyable flyableBird in birds){ 319 | flybleBird.Fly(); 320 | } 321 | } 322 | } 323 | ``` 324 | Primjer iznad je bolji od Rješenja 1 jer ne krši ni LSP ni OCP. To je postignuto uvođenjem apstrakcija u obliku sučelja te segregacijom sučelja prema respektiblinim funkcionalnostima. 325 | 326 | ## ISP 327 | Ne treba kroz ugradnju sucelja forsirati implementaciju metoda koje se ne koriste ili nisu potrebne ili nisu valjane za danu klasu 328 | 329 | Problem: 330 | ```cs 331 | interface IBirdable{ 332 | public void Walk(); 333 | public void Fly(); 334 | } 335 | 336 | class Sparrow: IBirdable{ 337 | public void Walk(){ 338 | Console.WriteLine($"Sparrow is walking fast"); 339 | } 340 | public void Fly(){ 341 | Console.WriteLine($"Bird is flying fast"); 342 | } 343 | } 344 | 345 | class Emu:IBirdable{ 346 | public void Walk(){ 347 | Console.WriteLine($"Emu is walking fast"); 348 | } 349 | public void Fly(){ 350 | throw new NotImplementedException (); 351 | } 352 | } 353 | ``` 354 | Primjer iznad krši ISP jer forsira implementaciju metode Fly u klasama kod kojih ta metoda ne smije biti implementirana. 355 | 356 | Rješenje: 357 | ```cs 358 | interface IFlyable{ 359 | public void Fly(); 360 | } 361 | 362 | interface IWalkable{ 363 | public void Walk(); 364 | } 365 | 366 | class Emu:IWalkable{ 367 | public void Walk(){ 368 | Console.WriteLine($"Bird is walking fast"); 369 | } 370 | } 371 | 372 | class Sparrow: IFlyable, IWalkable{ 373 | public void Walk(){ 374 | Console.WriteLine($"Bird is walking fast"); 375 | } 376 | 377 | public void Fly(){ 378 | Console.WriteLine($"Bird is flying fast"); 379 | } 380 | } 381 | ``` 382 | Primjer iznad poštuje ISP jer je sučelje iz prethodnog primjera podjeljeno na dva sučelja što omogućava klasama da implementiraju funkcionalnosti koje imaju smisla u njihovom kontekstu. 383 | 384 | ## DIP 385 | Klase na višim razinama ne trebaju ovisiti o klasama na nižim razinama, nego (oboje) trebaju ovisiti o apstrakciji 386 | 387 | Problem: 388 | ```cs 389 | class Bird{ 390 | public virtual void Walk(){ 391 | Console.WriteLine($"Bird is walking"); 392 | } 393 | } 394 | 395 | class BirdContoler{ 396 | List birds; 397 | public Birds {set{birds = value;}} 398 | 399 | public void MakeBirdsWalk(){ 400 | foreach(bird in birds){ 401 | bird.Walk(); 402 | } 403 | } 404 | } 405 | ``` 406 | Primjer iznad krši DIP jer klasa BirdControler ovisi o konkretnoj klasi Bird a ne o nekoj apstrakciji. 407 | 408 | Rješenje: 409 | ```cs 410 | interface IWalkable{ 411 | public void Walk(); 412 | } 413 | 414 | class Bird:IWalkable{ 415 | public void Walk(){ 416 | Console.WriteLine($"Bird is walking"); 417 | } 418 | } 419 | 420 | class BirdContoler{ 421 | List birds; 422 | public Birds {set{birds = value;}} 423 | 424 | public void MakeBirdsWalk(){ 425 | foreach(bird in birds){ 426 | bird.Walk(); 427 | } 428 | } 429 | } 430 | ``` 431 | Primjer iznad slijedi DIP jer klase ovise o apstrakciji IWalkable. -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CleanCode/README.hr.md: -------------------------------------------------------------------------------- 1 | # Čist kod 2 | U ovom poglavlju biti će navedene i objašnjene smjernice za pisanje čistog koda. Koncepti objašnjeni ovdje vrijede za skoro programske jezike. Primjeri ovdje su programirani u C# programskom jeziku. Cilj poglavlja je detaljno i jasno objasniti kako pisati čisti kod. 3 | 4 | Pogledati video: https://www.youtube.com/watch?v=CFRhGnuXG-4 5 | 6 | ## Sadržaj 7 | - Ime treba otktivati namjeru 8 | - Funkcije trebaju biti jednostavne 9 | 10 | ## Koristi svrhovita imena 11 | Navedeno vrijedi za sva imenovanja u programiranju: klase, metode, atribute.... 12 | 13 | Pogledati ovaj video: https://www.youtube.com/watch?v=-J3wNP6u5YU 14 | ### Ime treba otkrivati namjeru 15 | Neispravno: 16 | ```cs 17 | class C{ 18 | private string m; 19 | private int y; 20 | private double p; 21 | } 22 | ``` 23 | 24 | Ispravno 25 | ```cs 26 | class Car{ 27 | private string model; 28 | private int year; 29 | private double price; 30 | } 31 | ``` 32 | 33 | ### Netreba imati nepotrebne i krive informacije 34 | Neispravno: 35 | ```cs 36 | class CarClass{ 37 | private string carModelStr; 38 | private int carYear; 39 | private double carPrice; 40 | } 41 | ``` 42 | 43 | Ispravno: 44 | ```cs 45 | class Car{ 46 | private string model; 47 | private int year; 48 | private double price; 49 | } 50 | ``` 51 | 52 | ### Ime treba biti što jednostavno, unikatno i lako prepoznatljivo 53 | Neispravno: 54 | ```cs 55 | class FourWheeledWheicleWithAnEngine{ 56 | private string modelOfTheCar; 57 | private int yearsAmount; 58 | private double carAmount; 59 | } 60 | ``` 61 | Ispravno: 62 | ```cs 63 | class Car{ 64 | private string model; 65 | private int year; 66 | private double price; 67 | } 68 | ``` 69 | 70 | ### Treba biti izgovorljivo 71 | Neisrpavno: 72 | ```cs 73 | class Carawsd{} 74 | ``` 75 | 76 | Ispravno: 77 | ```cs 78 | class CarComputerControls{} 79 | ``` 80 | 81 | ### Nesmije biti šaljivo ni dvosmisleno 82 | Neispravno: 83 | ```cs 84 | class SnazzleWagon{} 85 | ``` 86 | Ispravno: 87 | ```cs 88 | class Car{} 89 | ``` 90 | 91 | ## Funkcije trebaju biti jednostavne 92 | 93 | ### Funkcije trebaju biti male 94 | - Male funkcije je lakše razumjeti 95 | - Veliku funkciju razlomiti na više djelova ako je moguće 96 | - Višestruko ugnježđivanje nije poželjno 97 | - Više manjih funkcija je lakše razumjeti nego jednu veliku 98 | - Funkcije trebaju imati mali broj parametara, idealno bez parametara 99 | - Sve više od 3 je zabrinjavajuće i treba izbjegavati 100 | 101 | ### Funkcije trebaju raditi jednu stvar 102 | Funkcija treba raditi jednu i samo jednu stvar i treba ju raditi dobro. 103 | Nebi trebala raditi ništa u pozadini, nikakvo logiranje ili kalkulacije uz stvar koju radi. 104 | Neispravno: 105 | ```cs 106 | class Car{ 107 | private string model; 108 | private int year; 109 | private double price; 110 | 111 | public string LogAndGetOrSetPrice(int price){ 112 | Console.WriteLine(price); 113 | if(price != null){ 114 | return price; 115 | }else{ 116 | this.price = price; 117 | return ""; 118 | } 119 | } 120 | } 121 | ``` 122 | Ispravno: 123 | ```cs 124 | class Car{ 125 | private string model; 126 | private int year; 127 | private double price 128 | 129 | public void LogPrice(){ 130 | Console.WriteLine(price); 131 | } 132 | 133 | public string GetPrice(){ 134 | return price; 135 | } 136 | 137 | public void SetPrice(int price){ 138 | this.price = price; 139 | } 140 | } 141 | ``` 142 | ### Exception-i umjesto kodova za greške 143 | Kodovima je potrebno trenutno rukovati. Exceptionima rukovanje izdvajamo u posebne klase. 144 | ```cs 145 | class Program 146 | { 147 | static void Main(string[] args) 148 | { 149 | try 150 | { 151 | // Call a method that might throw an exception 152 | DoSomethingDangerous(); 153 | } 154 | catch (Exception ex) 155 | { 156 | // Handle the exception 157 | Console.WriteLine($"An error occurred: {ex.Message}"); 158 | } 159 | } 160 | } 161 | ``` 162 | ### Izbjegavati switch 163 | Metode koje koriste switch i if-else skoro uvijek rade više od jedne stvari i s vremenom rastu no ponekad ali rijetko su korisne i nije ih potrebno mijenjati. Jedna ili dvije switch funkcije kroz codebase su prihvatljive. 164 | 165 | ## Oprezno koristi komentare 166 | Nikad ne dodavaj komentare u kod. Kod treba biti čitljiv bez komentara. U slučaju da si prisiljen dodavati komentare trebaju biti kratki i precizni 167 | 168 | ## Primjeri refaktoriranja 169 | Refaktoriraj zadanu klasu: 170 | ```cs 171 | public class DistanceCalculator 172 | { 173 | double[] mostDistant(List arrays, double[] target) 174 | { 175 | double max = 0, dist; 176 | int idxMax = 0; //index of the farthest in arrays from target 177 | for (int i = 0; i < arrays.Count; i++) 178 | { 179 | dist = 0; // Euclidean distance between target and i-th vector in arrays 180 | for (int j = 0; j < arrays[i].Length; j++) 181 | dist += (target[j] - arrays[i][j]) * (target[j] - arrays[i][j]); 182 | dist = Math.Sqrt(dist); 183 | 184 | if (i == 0 || dist > max) 185 | { 186 | max = dist; 187 | idxMax = i; 188 | } 189 | } 190 | return arrays[idxMax]; // farthest from target 191 | } 192 | } 193 | 194 | ``` 195 | Rješenje: 196 | ```cs 197 | public class DistanceCalculator 198 | { 199 | static double[] FindFarthestVector(List vectors, double[] targetVector) 200 | { 201 | double distance = EuclideanDistance(vectors[0], targetVector); 202 | double maxDistance = distance; 203 | int maxIndex = 0; 204 | for (int i = 1; i < vectors.Count; i++) 205 | { 206 | distance = EuclideanDistance(vectors[i], targetVector); 207 | if (distance > maxDistance) 208 | { 209 | maxDistance = distance; 210 | maxIndex = i; 211 | } 212 | } 213 | return vectors[maxIndex]; 214 | } 215 | 216 | static double EuclideanDistance(double[] vectorA, double[] vectorB ) 217 | { 218 | double distance = 0; 219 | for (int j = 0; j < vectorA.Length; j++) 220 | distance += Math.Pow((vectorB[j] - vectorA[j]), 2); 221 | return Math.Sqrt(distance); 222 | } 223 | } 224 | 225 | ``` 226 | ## Načela 227 | 228 | ### DRY 229 | DRY (Dont Repeat Yourself) princip u programiranju znači ne ponavljati isti kod već ga organizirati tako da se zajednički dijelovi izdvoje u ponovno koristive dijelove. To olakšava održavanje i čitanje koda jer se izbjegava potreba za traženjem i mijenjanjem istog koda na više mjesta. Time se potiče efikasnost u razvoju softvera jer se fokusira na jedinstvene reprezentacije znanja unutar sustava. 230 | 231 | ### KISS 232 | KISS je skraćenica za "Keep It Simple, Stupid". To je princip u dizajnu koji potiče jednostavnost i izbjegavanje nepotrebnog kompliciranja. Ideja 233 | je da što je nešto jednostavnije, lakše je razumjeti, održavati i koristiti. 234 | 235 | ### YAGNI 236 | YAGNI, kratica za "You Ain't Gonna Need It" (Nećeš to trebati), je princip u softverskom razvoju koji potiče na izbjegavanje dodavanja funkcionalnosti ili kodiranja stvari koje trenutno nisu potrebne. Ovaj princip naglašava važnost fokusa na trenutne zahtjeve i izbjegavanje nepotrebnog dodavanja složenosti ili funkcionalnosti unaprijed. Time se smanjuje gubitak vremena na implementaciju i održavanje nepotrebnih dijelova softvera, čime se poboljšava efikasnost i agilnost u razvoju. 237 | 238 | ## Zadaci 239 | 240 | ### Preimenovanje 241 | Preimenuj entitete u zadanom kodu 242 | 243 | #### Zadatak1 244 | ```cs 245 | enum ShapesOptions { Circle, Square } 246 | class CakeClass 247 | { 248 | public int cakeLayersCount { get; private set; } 249 | public ShapesOptions cakeShapeDescription { get; private set; } 250 | public bool frostedCake { get; private set; } 251 | public CakeClass(int layers, ShapesOptions shape, bool frostedOrNot) 252 | { 253 | cakeLayersCount = layers; 254 | cakeShapeDescription = shape; 255 | frostedCake = frostedOrNot; 256 | } 257 | } 258 | 259 | class SimpleCakeObjectFactory 260 | { 261 | public static CakeClass CreateCake(string cakeType) 262 | { 263 | switch (cakeType) 264 | { 265 | case "standard": 266 | return new CakeClass(2, 267 | ShapesOptions.Square, false); 268 | case "fancy": 269 | return new CakeClass(4, 270 | ShapesOptions.Circle, false); 271 | case "wedding": 272 | return new CakeClass(6, 273 | ShapesOptions.Circle, true); 274 | default: return null; 275 | } 276 | } 277 | } 278 | 279 | ``` 280 | #### Zadatak2 281 | ```cs 282 | class ProductObject 283 | { 284 | public string name { get; private set; } // prod. name 285 | public string price { get; private set; } // prod. price 286 | public bool InStock { get; set; } // flag - is prod. in stock or not? 287 | 288 | public ProductObject(string n, string p) 289 | { 290 | this.name = n; 291 | this.price = p; 292 | this.InStock = false; 293 | } 294 | } 295 | 296 | class HandlingOfProducts 297 | { 298 | List prodsList; // List of prods., 299 | 300 | public HandlingOfProducts(List inv) // inventory of prods. 301 | { 302 | prodsList = inv; 303 | } 304 | 305 | public void revive(ProductObject product) 306 | { 307 | foreach (ProductObject prod in prodsList) 308 | { // make prod. available again 309 | if (product == prod) 310 | prod.InStock = true; 311 | } 312 | } 313 | public void endAllUnavailable() 314 | { // expel the sold out products !!! 315 | prodsList.RemoveAll(product => product.InStock == false); 316 | } 317 | } 318 | ``` 319 | 320 | #### Zadatak3 321 | ```cs 322 | class Rndgen 323 | { 324 | private static Rndgen inst; 325 | private Random PRNG; //pseudo random number generator 326 | 327 | // Private constructor 328 | private Rndgen() 329 | { 330 | this.PRNG = new Random(); 331 | } 332 | 333 | // Singleton instance creation method 334 | public static Rndgen Instance() 335 | { 336 | if (inst == null) 337 | { 338 | inst = new Rndgen(); 339 | } 340 | return inst; 341 | } 342 | 343 | public int Int1() 344 | { 345 | return this.PRNG.Next(); 346 | } 347 | 348 | public int Int2(int a, int b) 349 | { 350 | return this.PRNG.Next() % (b - a + 1); 351 | } 352 | 353 | public double Double(double a, double b) 354 | { 355 | return a + (this.PRNG.NextDouble() * (b - a)); 356 | } 357 | } 358 | ``` 359 | 360 | #### Zadatak4 361 | ```cs 362 | public class NoteObject 363 | { 364 | public string title { get; set; } 365 | public string text { get; set; } 366 | public DateTime creation { get; private set; } 367 | 368 | public NoteObject(string titleString, string textString) 369 | { 370 | title = titleString; 371 | text = textString; 372 | creation = DateTime.Now; 373 | } 374 | } 375 | 376 | public class CollectionOfNotes 377 | { 378 | public string Author { get; private set; } 379 | public List groupOfNotes; 380 | 381 | public CollectionOfNotes(string author) 382 | { 383 | Author = author; 384 | groupOfNotes = new List(); 385 | } 386 | 387 | public void AddNoteToCollection(NoteObject note) 388 | { 389 | groupOfNotes.Add(note); 390 | } 391 | } 392 | ``` 393 | 394 | #### Zadatak5 395 | ```cs 396 | public class LocationInformationData 397 | { 398 | public DateTime DATC { get; private set; } // created at 399 | public double LatofLoc { get; private set; } // latitude coordinate 400 | public double Longofloc { get; private set; } // longitude coordinate 401 | 402 | public LocationInformationData(double Lat, double Long) 403 | { 404 | // Constructor implementation 405 | } 406 | } 407 | 408 | public class PathManaging 409 | { 410 | private List LocationsList; // the path location points 411 | 412 | public PathManaging() 413 | { 414 | LocationsList = new List(); 415 | } 416 | 417 | public void AddNewLocationForPath(LocationInformationData location) 418 | { 419 | LocationsList.Add(location); 420 | } 421 | 422 | public void RemoveLocationFromPath(LocationInformationData location) 423 | { 424 | LocationsList.Remove(location); 425 | } 426 | } 427 | ``` 428 | 429 | ### Refaktoriranje 430 | Refaktoriraj zadane isječke programa. 431 | 432 | #### Zadatak1 433 | ```cs 434 | // scales the vector to unit length 435 | public class LengthManager 436 | { 437 | public LengthManager() 438 | { 439 | double[] array = { 1, 2, 3 }; 440 | unitLengthScaler(array); 441 | } 442 | //Refaktorirajte kod dan u sljedecem izlistanju 443 | void unitLengthScaler(double[] array) 444 | { 445 | double L2 = 0; 446 | // Euclidean distance of the vector to the origin 447 | // also called the L2 norm (or Euclidean norm) of the vector 448 | for (int i = 0; i < array.Length; i++) 449 | L2 += array[i] * array[i]; 450 | L2 = Math.Sqrt(L2); 451 | // just divide each vector component by its L2 norm 452 | for (int i = 0; i < array.Length; i++) 453 | array[i] /= L2; 454 | } 455 | } 456 | ``` 457 | #### Zadatak2 458 | ```cs 459 | class Avg 460 | { 461 | List averages(List arraysList) 462 | { 463 | List avgs = new List(); //resulting list 464 | double s; 465 | foreach (double[] a in arraysList) 466 | { 467 | //compact code formating 468 | s = 0; 469 | for (int i = 0; i < a.Length; i++) s += a[i]; 470 | avgs.Add(s / a.Length); 471 | } 472 | return avgs; 473 | } 474 | } 475 | ``` 476 | #### Zadatak3 477 | ```cs 478 | class DistinctClass 479 | { 480 | //static method that returns an integer and takes an array of integers as input 481 | public static int Distinct(List intList) 482 | { 483 | int res = 0;//final result 484 | for (int i = 0; i < intList.Count; i++) 485 | { 486 | int flag = 0; // flag for counting 487 | for (int j = 0; j < intList.Count; j++) 488 | { 489 | if (intList[i] == intList[j]) 490 | { 491 | flag++; // occurrence counting 492 | } 493 | } 494 | if (flag == 1) 495 | { 496 | res++; // distinct count 497 | } 498 | } 499 | return res; // the result of counting 500 | } 501 | 502 | } 503 | ``` 504 | #### Zadatak4 505 | ```cs 506 | class DrugiZadatak 507 | { 508 | public static List uniqueChars(string text) 509 | { 510 | List chars = new List(); 511 | for (int i = 0; i < text.Length; i++) 512 | { 513 | int occurrenceCount = 0; 514 | for (int j = 0; j < text.Length; j++) 515 | { 516 | if (text[i] == text[j]) 517 | { 518 | occurrenceCount++; 519 | } 520 | } 521 | if (occurrenceCount == 1) 522 | { 523 | chars.Add(text[i]); 524 | } 525 | } 526 | return chars; 527 | } 528 | } 529 | ``` 530 | #### Zadatak5 531 | ```cs 532 | class DrugiZadatak 533 | { 534 | public List palindromes(List strings) 535 | { 536 | List res = new List(); 537 | if (strings == null) return res; 538 | foreach (string str in strings) 539 | { 540 | string temp1 = str.Replace(" ", "").ToLower(); 541 | string temp2 = new string(temp1.Reverse().ToArray()); 542 | //Palindrome 543 | if (temp1.Equals(temp2)) 544 | { 545 | res.Add(str); 546 | } 547 | } 548 | return res; 549 | } 550 | } 551 | ``` -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/OOP/README.hr.md: -------------------------------------------------------------------------------- 1 | # Objektno orjentirano programiranje 2 | U ovom poglavlju biti će objašnjeni osnovni pojmovi i koncepti vezani uz oop. Koncepti objašnjeni ovdje vrijede za skoro sve oop jezike. Primjeri ovdje su programirani u C# programskom jeziku. Cilj ovog poglavlja je ponoviti osnovne koncepte oop-a a ne detaljno ih objašnjavati kako bi bolje razumjeli sljedeća poglavlja (SOLID, Oblikovni obrasci) 3 | 4 | ## Klasa 5 | Klasa u objektno orijentiranom programiranju predstavlja predložak ili "plavprint" za stvaranje objekata. U njoj se definiraju svojstva (atributi) i ponašanja (metode) objekata određenog tipa. 6 | 7 | ### Konstruktor 8 | Konstruktor je posebna vrsta metode u programiranju, koja se koristi za inicijalizaciju objekata u klasi. On se obično koristi za postavljanje početnih vrijednosti svojstava ili izvođenje drugih inicijalizacijskih radnji potrebnih za ispravno funkcioniranje objekta. 9 | 10 | ### Atribut 11 | Atributi, u kontekstu programiranja, su varijable koje su vezane uz određeni objekt ili klasu. Svaki objekt može imati svoj set atributa koji opisuju njegova svojstva ili stanje. 12 | 13 | ### Metoda 14 | Metoda u programiranju predstavlja funkciju koja je definirana unutar neke klase. Ove funkcije obično služe za izvođenje određenih operacija nad objektima te klase ili za manipulaciju s njihovim atributima. 15 | 16 | ``` cs 17 | public class Automobil 18 | { 19 | // Atributi (svojstva) klase Automobil 20 | public string Marka { get; set; } 21 | public string Model { get; set; } 22 | public int GodinaProizvodnje { get; set; } 23 | 24 | // Konstruktor klase Automobil 25 | public Automobil(string marka, string model, int godinaProizvodnje) 26 | { 27 | Marka = marka; 28 | Model = model; 29 | GodinaProizvodnje = godinaProizvodnje; 30 | } 31 | 32 | // Metoda koja ispisuje informacije o automobilu 33 | public void IspisiInformacije() 34 | { 35 | Console.WriteLine($"Automobil: {Marka} {Model}, Godina proizvodnje: {GodinaProizvodnje}"); 36 | } 37 | } 38 | ``` 39 | ### Statička klasa, metoda i atribut 40 | Statičke klase ne mogu imati instance i obično se koriste za grupiranje povezanih metoda i atributa koje se mogu koristiti bez potrebe za stvaranjem objekata. 41 | 42 | Međutim, unutar statičke klase mogu postojati i nestatički (obični) atributi i metode. Ovi atributi i metode mogu biti korišteni samo ako postoji instanca klase, što nije moguće kod statičkih klasa jer se one ne mogu instancirati. 43 | ```cs 44 | 45 | public static class StaticClassExample 46 | { 47 | // Statički atribut 48 | public static int brojac = 0; 49 | 50 | // Statička metoda 51 | public static void Pozdrav() 52 | { 53 | Console.WriteLine("Pozdrav iz statičke metode!"); 54 | } 55 | } 56 | 57 | class Program 58 | { 59 | static void Main() 60 | { 61 | // Pozivanje statičke metode bez stvaranja instance klase 62 | StaticClassExample.Pozdrav(); 63 | 64 | // Pristupanje statičkom atributu 65 | StaticClassExample.brojac++; 66 | 67 | // Ispisivanje vrijednosti statičkog atributa 68 | Console.WriteLine("Vrijednost brojaca: " + StaticClassExample.brojac); 69 | } 70 | } 71 | ``` 72 | ## Objekt 73 | Objekt je instanca klase. Objekt posjeduje svojstva definirana u klasi te može izvršavati metode koje su također definirane u klasi. Objekti omogućuju konkretizaciju apstraktnih definicija i reprezentiraju stvarne entitete ili pojave u programu. 74 | 75 | ### Instanciranje objekta 76 | Instanciranje objekta je postupak stvaranja instance određene klase. Kada se kreira instanca, rezervira se memorija za objekt, a konstruktor klase se koristi za inicijalizaciju tog objekta. Sa ključnom riječi new instanciramo objekt tj. stvaramo taj objekt. 77 | 78 | ``` cs 79 | class Program 80 | { 81 | static void Main(string[] args) 82 | { 83 | // Stvaranje novog objekta klase Automobil 84 | Automobil automobil1 = new Automobil("Toyota", "Corolla", 2020); 85 | 86 | // Pozivanje metode za ispis informacija o automobilu 87 | automobil1.IspisiInformacije(); 88 | } 89 | } 90 | ``` 91 | 92 | ## Nasljeđivanje 93 | Koncept u oop-u koji nalaže kreiranje novih klasa na temelju postojećih klasa, preuzimajući njihova svojstva i metode čime se olakšava korištenje koda i poboljšava organizacija programa. 94 | 95 | Pogledati video: https://www.youtube.com/watch?v=hxGOiiR9ZKg&t=500s 96 | 97 | ### Klasa roditelj 98 | Viša/Roditeljska/Bazna/Osnovna klasa je klasa čiji članovi su naslijeđeni od strane druge klase. Također je poznata kao roditeljska klasa ili nadklasa. Ona definira zajedničke atribute i ponašanja koji se dijele među njenim izvedenim klasama. 99 | 100 | ### Klasa dijete 101 | Niža/Dijete/Izvedena/Podklasa klasa je klasa koja nasljeđuje od druge klase. Također je poznata kao podklasa ili djetelinska klasa. Može ponovno koristiti članove bazne klase i može imati dodatne članove ili nadjačati postojeće. 102 | 103 | ``` cs 104 | // Osnovna klasa 105 | public class Vozilo 106 | { 107 | public string Marka { get; set; } 108 | public int GodinaProizvodnje { get; set; } 109 | 110 | public void IspisiInformacije() 111 | { 112 | Console.WriteLine($"Vozilo: {Marka}, Godina proizvodnje: {GodinaProizvodnje}"); 113 | } 114 | } 115 | 116 | // Podklasa Automobil koja nasljeđuje klasu Vozilo 117 | public class Automobil : Vozilo 118 | { 119 | public string Model { get; set; } 120 | 121 | // Konstruktor koji inicijalizira atribute roditeljske klase i atribut Model 122 | public Automobil(string marka, string model, int godinaProizvodnje) 123 | { 124 | Marka = marka; 125 | Model = model; 126 | GodinaProizvodnje = godinaProizvodnje; 127 | } 128 | 129 | // Metoda koja ispisuje informacije o automobilu 130 | public void IspisiAutomobilInformacije() 131 | { 132 | Console.WriteLine($"Automobil: {Marka} {Model}, Godina proizvodnje: {GodinaProizvodnje}"); 133 | } 134 | } 135 | 136 | class Program 137 | { 138 | static void Main(string[] args) 139 | { 140 | // Stvaranje novog objekta klase Automobil 141 | Automobil automobil1 = new Automobil("Toyota", "Corolla", 2020); 142 | 143 | // Pozivanje metoda za ispis informacija o automobilu 144 | automobil1.IspisiInformacije(); // Pozivanje metode iz roditeljske klase 145 | automobil1.IspisiAutomobilInformacije(); // Pozivanje metode iz podklase 146 | } 147 | } 148 | ``` 149 | ### Apstrakcija 150 | Apstrakcija je temeljni koncept u objektno orijentiranom programiranju (OOP) koji uključuje pojednostavljivanje kompleksnih sustava modeliranjem razreda na temelju njihovih bitnih značajki i ponašanja. To omogućuje programerima da se usredotoče na relevantne aspekte objekta, zanemarujući nepotrebne pojedinosti. U kontekstu OOP-a, apstrakcija obično poprima dva glavna oblika: Apstraktne klase i metode te sučelja. 151 | 152 | #### Apstraktna klasa i metoda 153 | Apstraktna klasa je klasa koja se ne može instancirati samostalno i može sadržavati apstraktne metode (metode bez implementacije). Služi kao predložak za druge klase. Apstraktna klasa može imati i ne apstraktne metode s implementiranom funkcionalnošću. 154 | 155 | #### Virtualna metoda 156 | U programskom jeziku C#, ključna riječ "virtual" koristi se za deklariranje metode u baznoj klasi koju mogu nadjačati izvedene klase ali ne moraju. Virtualna metoda sadrži implementaciju. Ovo omogućuje polimorfizam, gdje izvedena klasa može pružiti vlastitu implementaciju metode dok održava zajedničko sučelje s baznom klasom. Ključna riječ "virtual" obično se koristi u kombinaciji s ključnom riječi "override" u izvedenoj klasi, tj. ako u izvedenoj klasi želimo prilagođenu funkcionalnost virtualnu metodu je potrebno prepisati. 157 | 158 | ``` cs 159 | public abstract class Vozilo 160 | { 161 | public string Marka { get; set; } 162 | public int GodinaProizvodnje { get; set; } 163 | 164 | // Apstraktna metoda koja će biti implementirana u podklasama 165 | public abstract void Pokreni(); 166 | 167 | // Virtualna metoda koju podklase mogu prebrisati po potrebi 168 | public virtual void Zaustavi() 169 | { 170 | Console.WriteLine("Vozilo je zaustavljeno."); 171 | } 172 | 173 | // Obična (konkretna) metoda 174 | public void IspisiInformacije() 175 | { 176 | Console.WriteLine($"Vozilo: {Marka}, Godina proizvodnje: {GodinaProizvodnje}"); 177 | } 178 | } 179 | 180 | // Podklasa Automobil koja nasljeđuje apstraktnu klasu Vozilo 181 | public class Automobil : Vozilo 182 | { 183 | public string Model { get; set; } 184 | 185 | public Automobil(string marka, string model, int godinaProizvodnje) 186 | { 187 | Marka = marka; 188 | Model = model; 189 | GodinaProizvodnje = godinaProizvodnje; 190 | } 191 | 192 | // Implementacija apstraktne metode Pokreni iz bazne klase 193 | public override void Pokreni() 194 | { 195 | Console.WriteLine("Automobil je pokrenut."); 196 | } 197 | 198 | // Prebrisavanje virtualne metode Zaustavi koje je opcionalno 199 | public override void Zaustavi() 200 | { 201 | Console.WriteLine("Automobil je zaustavljen."); 202 | } 203 | } 204 | 205 | class Program 206 | { 207 | static void Main(string[] args) 208 | { 209 | Automobil automobil1 = new Automobil("Toyota", "Corolla", 2020); 210 | 211 | automobil1.IspisiInformacije(); 212 | automobil1.Pokreni(); 213 | automobil1.Zaustavi(); // Poziva se prebrisana metoda 214 | } 215 | } 216 | ``` 217 | 218 | #### Sučelja 219 | Sučelje je ugovor koji definira skup potpisa metoda. Klasa koji implementira sučelje mora pružiti konkretne implementacije svih metoda deklariranih u tom sučelju. Sučelja omogućuju postizanje apstrakcije definiranjem što objekt treba raditi, bez specificiranja kako to treba učiniti. 220 | ``` cs 221 | // Sučelje IVozilo 222 | public interface IVozilo 223 | { 224 | // Potpisi metoda 225 | void Pokreni(); 226 | void Zaustavi(); 227 | } 228 | 229 | // Klasa Automobil koja implementira sučelje IVozilo 230 | public class Automobil : IVozilo 231 | { 232 | public void Pokreni() 233 | { 234 | Console.WriteLine("Automobil je pokrenut."); 235 | } 236 | 237 | public void Zaustavi() 238 | { 239 | Console.WriteLine("Automobil je zaustavljen."); 240 | } 241 | } 242 | 243 | class Program 244 | { 245 | static void Main(string[] args) 246 | { 247 | Automobil automobil1 = new Automobil(); 248 | 249 | automobil1.Pokreni(); 250 | automobil1.Zaustavi(); 251 | } 252 | } 253 | ``` 254 | 255 | ## Enkapsulacija 256 | Koncept u oop-u koji nalaže skrivanje internih detalja objekta i izlaganja samo onoga što je nužno. Enkapsulacija pruža nekoliko prednosti, uključujući zaštitu podataka, organizaciju koda i fleksibilnost u dizajnu. 257 | 258 | ### Pristupni modifikatori 259 | Pristupni modifikatori (private, public, protected, internal) kontroliraju vidljivost članova klase. Označavanjem određenih članova kao privatne, ograničavate izravan pristup tim članovima izvan klase. 260 | 261 | - private - entitet (svojstvo, metoda, ...) je dostupan samo unutar klase 262 | - public - entitet je dostupan u bilo kojem djelu programa 263 | - protected - entitet je dostupan unutar iste klase i u izvedenim klasama 264 | - internal - entitet je dostupan unutar istog assemblyja (DLL ili SDK) 265 | 266 | ``` cs 267 | public class Brojevi 268 | { 269 | public int JavniBroj { get; set; } // Dostupno izvan klase 270 | 271 | private int PrivatniBroj { get; set; } // Dostupno samo unutar klase 272 | 273 | protected int ZasticeniBroj { get; set; } // Dostupno samo unutar klase i izvedenih klasa 274 | 275 | internal int InterniBroj { get; set; } // Dostupno samo unutar istog projekta ili assemblyja 276 | } 277 | 278 | public class IzvedeniBrojevi : Brojevi 279 | { 280 | public void Metoda() 281 | { 282 | // Možemo pristupiti ZasticeniBroj jer je protected i dostupan izvedenoj klasi 283 | Console.WriteLine(ZasticeniBroj); 284 | } 285 | } 286 | 287 | class Program 288 | { 289 | static void Main(string[] args) 290 | { 291 | Brojevi brojevi = new Brojevi(); 292 | 293 | // Možemo pristupiti JavniBroj jer je public 294 | brojevi.JavniBroj = 10; 295 | 296 | // Ne možemo pristupiti PrivatniBroj jer je private i nije dostupan izvan klase 297 | // brojevi.PrivatniBroj = 5; 298 | 299 | // Ne možemo pristupiti ZasticeniBroj jer nije dostupan izvan klase ni izvedenih klasa 300 | // brojevi.ZasticeniBroj = 15; 301 | 302 | // Ne možemo pristupiti InterniBroj jer nije dostupan izvan istog projekta ili assemblyja 303 | // brojevi.InterniBroj = 20; 304 | } 305 | } 306 | ``` 307 | ## Polimorfizam 308 | Koncept u oop-u koji nalaže da treba biti moguće imati entitete koji se jednako zovu a drugačije ponašaju. 309 | 310 | ### Statički polimorfiza 311 | Statički polimorfizam se postiže kroz preopterećenje metoda ili operatora. To znači da isto ime metode ili operatora može imati različite implementacije, ali se razlikuju po broju ili tipu parametara. 312 | 313 | ```cs 314 | public class Matematika 315 | { 316 | // Metoda za zbrajanje dva cijela broja 317 | public int Zbroji(int a, int b) 318 | { 319 | return a + b; 320 | } 321 | 322 | // Metoda za zbrajanje tri cijela broja 323 | public int Zbroji(int a, int b, int c) 324 | { 325 | return a + b + c; 326 | } 327 | 328 | // Metoda za zbrajanje dva decimalna broja 329 | public double Zbroji(double a, double b) 330 | { 331 | return a + b; 332 | } 333 | } 334 | 335 | class Program 336 | { 337 | static void Main(string[] args) 338 | { 339 | Matematika mat = new Matematika(); 340 | 341 | // Poziv metode za zbrajanje dva cijela broja 342 | int rezultat1 = mat.Zbroji(3, 5); 343 | Console.WriteLine("Zbroj dva cijela broja: " + rezultat1); 344 | 345 | // Poziv metode za zbrajanje tri cijela broja 346 | int rezultat2 = mat.Zbroji(3, 5, 7); 347 | Console.WriteLine("Zbroj tri cijela broja: " + rezultat2); 348 | 349 | // Poziv metode za zbrajanje dva decimalna broja 350 | double rezultat3 = mat.Zbroji(3.5, 4.7); 351 | Console.WriteLine("Zbroj dva decimalna broja: " + rezultat3); 352 | } 353 | } 354 | ``` 355 | 356 | ### Dinamički polimorfizam 357 | Dinamički polimorfizam omogućuje različite implementacije metoda prema vrsti objekta koji ga poziva. 358 | Postiže se kroz naslijeđivanje i virtualne metode. Bazna klasa definira virtualne metode koje se mogu prebrisati u izvedenim klasama. 359 | 360 | ### Parametarski polimorfizam 361 | Parametarski polimorfizam se postiže kroz korištenje generičkih tipova. Generički tipovi omogućuju definiranje klasa, struktura ili metoda koji mogu raditi s različitim tipovima podataka, čime se postiže veća fleksibilnost i ponovno korištenje koda. Korištenjem generičkih tipova, programer može stvoriti komponente koje su neovisne o konkretnim tipovima podataka s kojima će raditi. Parametarski polimorfizam omogućuje pisanje općenitih algoritama i struktura podataka koje mogu biti korisne u različitim kontekstima 362 | 363 | ## Ovisnost 364 | 365 | ### Ubrizgavanje ovisnosti 366 | Pogeldati ovaj video: https://www.youtube.com/watch?v=J1f5b4vcxCQ 367 | 368 | Obrazac koji se koristi u oop-u kako bi se riješio problem ovisnosti između klasa ubrizgavanjem tih ovisnosti izvana, umjesto da klasa stvara svoje ovisnosti unutar sebe. Osnovni cilj DI-ja je postizanje labave povezanosti između klasa, čime se sustav čini modularnim, održivijim i stabilnijim. 369 | 370 | #### Ubrizgavanje konstruktorom 371 | ```cs 372 | // Interface koji definira uslugu 373 | public interface IService 374 | { 375 | void PerformOperation(); 376 | } 377 | 378 | // Implementacija IService sučelja 379 | public class Service : IService 380 | { 381 | public void PerformOperation() 382 | { 383 | Console.WriteLine("Operation performed by Service"); 384 | } 385 | } 386 | 387 | // Klasa koja ovisi o IService sučelju kroz konstruktor 388 | public class Client 389 | { 390 | private readonly IService _service; 391 | 392 | // Konstruktor koji prima IService implementaciju 393 | public Client(IService service) 394 | { 395 | _service = service; 396 | } 397 | 398 | // Metoda koja koristi uslugu IService 399 | public void ExecuteOperation() 400 | { 401 | _service.PerformOperation(); 402 | } 403 | } 404 | 405 | class Program 406 | { 407 | static void Main(string[] args) 408 | { 409 | // Instanciranje implementacije IService 410 | IService service = new Service(); 411 | 412 | // Stvaranje instance klijenta s proslijeđenom implementacijom IService 413 | Client client = new Client(service); 414 | 415 | // Izvođenje operacije kroz klijenta 416 | client.ExecuteOperation(); 417 | } 418 | } 419 | ``` 420 | 421 | #### Ubrizgavanje metodom 422 | ```cs 423 | // Interface koji definira uslugu 424 | public interface IService 425 | { 426 | void PerformOperation(); 427 | } 428 | 429 | // Implementacija IService sučelja 430 | public class Service : IService 431 | { 432 | public void PerformOperation() 433 | { 434 | Console.WriteLine("Operation performed by Service"); 435 | } 436 | } 437 | 438 | // Klasa koja ovisi o IService sučelju kroz metodu 439 | public class Client 440 | { 441 | // Metoda koja prima IService implementaciju kao argument 442 | public void ExecuteOperation(IService service) 443 | { 444 | service.PerformOperation(); 445 | } 446 | } 447 | 448 | class Program 449 | { 450 | static void Main(string[] args) 451 | { 452 | // Instanciranje implementacije IService 453 | IService service = new Service(); 454 | 455 | // Stvaranje instance klijenta i poziv metode s proslijeđenom implementacijom IService 456 | Client client = new Client(); 457 | client.ExecuteOperation(service); 458 | } 459 | } 460 | ``` 461 | 462 | #### Ubrizgavanje svojstvom 463 | ```cs 464 | // Interface koji definira uslugu 465 | public interface IService 466 | { 467 | void PerformOperation(); 468 | } 469 | 470 | // Implementacija IService sučelja 471 | public class Service : IService 472 | { 473 | public void PerformOperation() 474 | { 475 | Console.WriteLine("Operation performed by Service"); 476 | } 477 | } 478 | 479 | // Klasa koja ovisi o IService sučelju kroz svojstvo 480 | public class Client 481 | { 482 | // Javno svojstvo za IService implementaciju 483 | public IService Service { get; set; } 484 | 485 | // Metoda koja koristi IService uslugu 486 | public void ExecuteOperation() 487 | { 488 | Service.PerformOperation(); 489 | } 490 | } 491 | 492 | class Program 493 | { 494 | static void Main(string[] args) 495 | { 496 | // Instanciranje implementacije IService 497 | IService service = new Service(); 498 | 499 | // Stvaranje instance klijenta i postavljanje svojstva IService 500 | Client client = new Client(); 501 | client.Service = service; 502 | 503 | // Izvođenje operacije kroz klijenta 504 | client.ExecuteOperation(); 505 | } 506 | } 507 | ``` 508 | 509 | ### Čvrst sprega 510 | Javlja se kada su dvije ili više klasa visoko ovisne jedna o drugoj, te promjene u jednoj klasi mogu zahtijevati promjene u drugoj. Ova vrsta povezanosti može otežati održavanje i proširivanje sustava jer promjene u jednoj klasi često zahtijevaju prilagodbe u drugim klasama s kojima je čvrsto povezana. Osnovni cilj u objektno orijentiranom programiranju je smanjiti čvrstu povezanost kako bi se poboljšala modularnost i fleksibilnost sustava. 511 | ```cs 512 | // Klasa koja predstavlja neku funkcionalnost 513 | public class Servis 514 | { 515 | // Metoda koja obrađuje neki podatak 516 | public void ObaviPosao() 517 | { 518 | Console.WriteLine("Obavlja se neki posao..."); 519 | } 520 | } 521 | 522 | // Klasa koja ovisi o funkcionalnosti Servis klase 523 | public class Klijent 524 | { 525 | private readonly Servis servis; 526 | 527 | // Konstruktor koji stvara čvrstu spregu između Klijent i Servis klase 528 | public Klijent() 529 | { 530 | servis = new Servis(); 531 | } 532 | 533 | // Metoda koja koristi funkcionalnost Servis klase 534 | public void KoristiServis() 535 | { 536 | servis.ObaviPosao(); 537 | } 538 | } 539 | 540 | class Program 541 | { 542 | static void Main(string[] args) 543 | { 544 | Klijent klijent = new Klijent(); 545 | klijent.KoristiServis(); 546 | } 547 | } 548 | ``` 549 | ### Labava sprega 550 | Javlja se kada su dvije ili više klasa neovisne jedna o drugoj te promjene u jednoj klasi ne zahtijevaju promjene u drugoj. Ova vrsta povezanosti promiče fleksibilnost i olakšava održavanje sustava, jer promjene u jednoj klasi ne bi trebale zahtijevati prilagodbe u drugim klasama s kojima interagira. 551 | ```cs 552 | // Interface koji definira funkcionalnost 553 | public interface IServis 554 | { 555 | void ObaviPosao(); 556 | } 557 | 558 | // Implementacija IServis sučelja 559 | public class Servis : IServis 560 | { 561 | public void ObaviPosao() 562 | { 563 | Console.WriteLine("Obavlja se neki posao..."); 564 | } 565 | } 566 | 567 | // Klasa koja ovisi o funkcionalnosti Servis klase 568 | public class Klijent 569 | { 570 | private readonly IServis _servis; 571 | 572 | // Konstruktor koji koristi dependency injection 573 | public Klijent(IServis servis) 574 | { 575 | _servis = servis; 576 | } 577 | 578 | // Metoda koja koristi funkcionalnost Servis klase 579 | public void KoristiServis() 580 | { 581 | _servis.ObaviPosao(); 582 | } 583 | } 584 | 585 | class Program 586 | { 587 | static void Main(string[] args) 588 | { 589 | IServis servis = new Servis(); 590 | Klijent klijent = new Klijent(servis); 591 | klijent.KoristiServis(); 592 | } 593 | } 594 | ``` 595 | ## Zadaci 596 | 597 | ### 1. Zadatak 598 | Implementirajte bankovni sustav koristeći se načelima objektno orijentiranog programiranja. Osim osnovnih funkcionalnosti bankovnog sustava, naglasak je na korištenju sučelja, apstraktnih klasa, virtualnih metoda, apstraktnih metoda, labave spregu, ubrizgavanja ovisnosti, polimorfizma, nasljeđivanja i enkapsulacije. 599 | 600 | 601 | Sučelja koja možete definirati: 602 | 603 | - IBankovniRacun: Definira osnovne operacije za upravljanje bankovnim računima. 604 | - ITransakcija: Definira metode za izvršavanje transakcija. 605 | 606 | 607 | Apstraktne klase koje možete definirati: 608 | 609 | - Osoba: Apstraktna klasa koja predstavlja osnovne osobne podatke korisnika. 610 | - Transakcija: Apstraktna klasa koja sadrži zajednička svojstva svih vrsta transakcija. 611 | 612 | 613 | Klase koje možete definirati: 614 | 615 | - Korisnik: Klasa koja implementira sučelje IBankovniRacun i sadrži informacije o korisniku. 616 | - Banka: Klasa koja upravlja korisnicima i omogućuje izvršavanje transakcija. Implementira ubrizgavanje ovisnosti kako bi se postigla labava sprega s korisnicima. 617 | - Konkretne vrste transakcija (npr. Uplata, Isplata) koje nasljeđuju Transakcija. 618 | 619 | 620 | Virtualne metode i polimorfizam: 621 | 622 | - U klasama Osoba, Transakcija i drugim relevantnim klasama, implementirati virtualne metode koje se mogu nadjačati u podklasama za specifične potrebe. 623 | 624 | 625 | Apstraktne metode: 626 | 627 | - ITransakcija definira apstraktnu metodu IzvrsiTransakciju() koju implementiraju konkretne transakcijske klase. 628 | 629 | Enkapsulacija: 630 | 631 | - Odredi koje vrijable trebaju biti enkapsulirane (odredi gdje je potrebno staviti private, public, protected ili internal) kako bi se osigurala zaštita podataka i održavanje skladnog stanja objekata. 632 | 633 | Dodatni uvjeti: 634 | 635 | Implementirati mehanizme ubrizgavanja ovisnosti kako bi se omogućila labava sprega i jednostavno testiranje. 636 | Održavati jasnu hijerarhiju klasa kroz nasljeđivanje kako bi se postigla čitljivost i skalabilnost koda. 637 | Koristiti apstraktne klase i sučelja tamo gdje je to primjenjivo radi definiranja zajedničkih karakteristika i funkcionalnosti. 638 | Ovaj zadatak osigurava primjenu naprednih OOP koncepta i tehnika kako bi se postigla visoka razina modularnosti, fleksibilnosti i čitljivosti koda. Sretno! -------------------------------------------------------------------------------- /DevOfSwSuppWithOOP/CodeSmellsAndAntipatterns/README.hr.md: -------------------------------------------------------------------------------- 1 | # Mirisi u kodu i antiobrasci 2 | U ovom poglavlju biti će navedeni i objašnjeni Mirisi u kodu i Antiobrasci te će biti objašnjena razlika između dvoje. Konepti objašnjeni ovdje vrijede za skoro programske jezike. Primjeri ovdje su programirani u C# programskom jeziku. Cilj poglavlja je objasniti kako prepoznati i kako popraviti mirise i antiobrazce u kodu. 3 | 4 | ## Koja je razlika? 5 | Mirisi u kodu su indikatori da sustav pati od znatnih problema. Antiobrasci su rješenja, pristupi ili metodologije koji nisu učinkoviti tj. loši su i imaju negativne posljedice na sustav. 6 | 7 | Ukratko: 8 | 9 | - Mirisi su indikatori lošeg koda. Tj. "A vidi, ovdje je ista metoda copy-pasteana triput" 10 | - Antiobrasci su loša rješenja. Tj. "Zast je ovaj lik koristio QuickSort za sortiranje 10 brojeva?" 11 | 12 | ## Mirisi u kodu 13 | Ako neki kod sadrži nekoliko instanci mirisa u kodu, nije nužno da je kod loš niti je nužno da problemi postoje ali je potrebno razmotriti do čega taj miris može dovesti u budućnosti te ima li smisla popravljati miris i ako ima kako, kakav će to utjecaj imati na sistem te koliko će trajati uz razne druge faktore koji ovise o specifičnoj situaciji. 14 | 15 | ### Duplicirani kod 16 | Miris koji nastaje kad se isti komadić koda pojavljuje kroz program, klasu ili metodu. 17 | #### Komadić koda koji se ponavlja kroz druge metode i klase 18 | U ovom slučaju ako je moguće i ima smisla taj komadić koda treba staviti u metodu i pozivati ju svagdje gdje se taj kod ponavlja. 19 | #### Može biti cijela metoda koja je prisutna u više klasa 20 | Potrebno je izbrisati jednu od metode i svagdje koristiti jednu ili prebaciti metodu u novu ili klasu gdje bolje pripada. 21 | #### Mogu biti različite metode koje rješavaju isti problem 22 | U rijetkim slučajevima ovaj pristup je u redu. U slučajevima kad nije potrebno je odabrati bolje rješenje po određenim parametrima i koristit ga svagdje 23 | #### Može biti nepotrebno instanciranje objekta više puta 24 | Ako je objekt instanciran isponova u više metoda klase potrebno ga je referencirati na razini klase i instancirati ga u konstruktoru. Nema smisla u slučajevima kad se ista klasa instancira sa razlicitim parametrima u različitim metodama. 25 | 26 | Neispravno: 27 | ```cs 28 | class Player{ 29 | Bulets bulets; 30 | Location location 31 | public Player(){ 32 | bulets = new Bulets(100) 33 | location = new Location(0,0); 34 | } 35 | public void Shoot(){ 36 | AnimationControler animationControler = new AnimationControler(); 37 | ShootingAnimation shootingAnimation = new ShootingAnimation() 38 | animationControler.LoadAnimation(shootingAnimation); 39 | animationControler.ExecuteAnimation(); 40 | animationControler.FinishAnimtion(); 41 | bulets.Pop(); 42 | } 43 | public void Walk(Direction direction){ 44 | AnimationControler animationControler = new AnimationControler(); 45 | WalkingAnimation walkingAnimation = new WalkingAnimation() 46 | animationControler.LoadAnimation(walkingAnimation); 47 | animationControler.ExecuteAnimation(); 48 | animationControler.FinishAnimtion(); 49 | location.Update(direction); 50 | } 51 | } 52 | ``` 53 | Ispravno: 54 | ```cs 55 | class Player{ 56 | AnimationControler animationControler; 57 | Bulets bulets; 58 | Location location 59 | public Player(){ 60 | animationControler = new AnimationControler(); 61 | bulets = new Bulets(100) 62 | location = new Location(0,0); 63 | } 64 | public void Shoot(){ 65 | RunAnimation(new ShootingAnimation()) 66 | bulets.Pop(); 67 | } 68 | public void Walk(Direction direction){ 69 | RunAnimation(new WalkingAnimation()) 70 | location.Update(direction); 71 | } 72 | public void RunAnimation(Animation animation){ 73 | animationControler.LoadAnimation(animation); 74 | animationControler.ExecuteAnimation(); 75 | animationControler.FinishAnimtion(); 76 | } 77 | } 78 | ``` 79 | ### Velike metode 80 | Metoda sa previše parametara i previše linija koda. Velike metode je potrebno rasjeći na više malih smislenih metoda koje pomažu razumljivosti velike metode. 81 | 82 | #### Metoda s velikim brojem linija 83 | Podjeliti metodu na smislene dijelove. Svaki smisleni dio staviti u novu metodu te nove metode referencirati u velikoj metodi umjesto komadića koda. 84 | 85 | Neispravno: 86 | ```cs 87 | class UserControler{ 88 | public void Register(string name, string password){ 89 | if(name< 3 || name > 20){ 90 | throw new ParameterNotValidException(name); 91 | } 92 | if(password<3 || password> 20){ 93 | throw new ParameterNotValidException(surname); 94 | } 95 | DatabaseService.Insert(new User(name, password)); 96 | } 97 | } 98 | ``` 99 | Ispravno: 100 | ```cs 101 | class UserControler{ 102 | public void Register(string name, string password){ 103 | ValidateInput(name); 104 | ValidateInput(surname); 105 | DatabaseService.Insert(new User(name, password)); 106 | } 107 | 108 | void ValidateInput(string input){ 109 | if(input< 3 || input > 20){ 110 | throw new ParameterNotValidException(input); 111 | } 112 | } 113 | } 114 | ``` 115 | 116 | 117 | #### Metoda s velikom brojem parametara 118 | Potrebno razmotriti mogućnost spajanja nekih parametara u novi objekt i referencirati objekt umjesto parametara 119 | 120 | Neispravno: 121 | ```cs 122 | public void CreateCustomer(string firstName, string lastName, int age, string email, string address, string city, string postalCode) 123 | { 124 | //Neka logika 125 | } 126 | ``` 127 | Ispravno: 128 | ```cs 129 | public class Customer 130 | { 131 | public string FirstName { get; set; } 132 | public string LastName { get; set; } 133 | public int Age { get; set; } 134 | public string Email { get; set; } 135 | public string Address { get; set; } 136 | public string City { get; set; } 137 | public string PostalCode { get; set; } 138 | } 139 | 140 | public void CreateCustomer(Customer customer) 141 | { 142 | //Neka logika 143 | } 144 | 145 | ``` 146 | #### Ne razumljiva metoda 147 | Ako je metoda glomazna i tesko razumljiva potrebno je komadiće logike enkapsulirati u manje metode koje imenom otkrivaju sto rade sto na kraju veliku metodu čini razumljivijom 148 | Neispravno: 149 | ```cs 150 | public class DistanceCalculator 151 | { 152 | public static double? CalculateDistance(double?[] point1, double?[] point2, DistanceMetric metric = DistanceMetric.Euclidean) 153 | { 154 | if (point1 == null || point2 == null) 155 | throw new ArgumentNullException("Points cannot be null."); 156 | 157 | if (point1.Length != point2.Length) 158 | throw new ArgumentException("Points must have the same dimensionality."); 159 | 160 | double sum = 0.0; 161 | 162 | for (int i = 0; i < point1.Length; i++) 163 | { 164 | if (!point1[i].HasValue || !point2[i].HasValue) 165 | return null; // If any coordinate is missing, return null 166 | 167 | double difference = Math.Abs(point1[i].Value - point2[i].Value); 168 | 169 | switch (metric) 170 | { 171 | case DistanceMetric.Euclidean: 172 | sum += difference * difference; 173 | break; 174 | case DistanceMetric.Manhattan: 175 | sum += difference; 176 | break; 177 | default: 178 | throw new ArgumentException("Unsupported distance metric."); 179 | } 180 | } 181 | 182 | switch (metric) 183 | { 184 | case DistanceMetric.Euclidean: 185 | return Math.Sqrt(sum); 186 | case DistanceMetric.Manhattan: 187 | return sum; 188 | default: 189 | throw new ArgumentException("Unsupported distance metric."); 190 | } 191 | } 192 | } 193 | ``` 194 | Ispravno: 195 | ```cs 196 | public class DistanceCalculator 197 | { 198 | public static double? CalculateDistance(double?[] point1, double?[] point2, DistanceMetric metric = DistanceMetric.Euclidean) 199 | { 200 | ValidatePoints(point1, point2); 201 | 202 | double sum = CalculateDistanceSum(point1, point2, metric); 203 | 204 | return CalculateFinalDistance(sum, metric); 205 | } 206 | 207 | private static void ValidatePoints(double?[] point1, double?[] point2) 208 | { 209 | if (point1 == null || point2 == null) 210 | throw new ArgumentNullException("Points cannot be null."); 211 | 212 | if (point1.Length != point2.Length) 213 | throw new ArgumentException("Points must have the same dimensionality."); 214 | } 215 | 216 | private static double CalculateDistanceSum(double?[] point1, double?[] point2, DistanceMetric metric) 217 | { 218 | double sum = 0.0; 219 | 220 | for (int i = 0; i < point1.Length; i++) 221 | { 222 | if (!point1[i].HasValue || !point2[i].HasValue) 223 | return double.NaN; // If any coordinate is missing, return NaN 224 | 225 | double difference = Math.Abs(point1[i].Value - point2[i].Value); 226 | 227 | switch (metric) 228 | { 229 | case DistanceMetric.Euclidean: 230 | sum += difference * difference; 231 | break; 232 | case DistanceMetric.Manhattan: 233 | sum += difference; 234 | break; 235 | default: 236 | throw new ArgumentException("Unsupported distance metric."); 237 | } 238 | } 239 | 240 | return sum; 241 | } 242 | 243 | private static double? CalculateFinalDistance(double sum, DistanceMetric metric) 244 | { 245 | if (double.IsNaN(sum)) 246 | return null; 247 | 248 | switch (metric) 249 | { 250 | case DistanceMetric.Euclidean: 251 | return Math.Sqrt(sum); 252 | case DistanceMetric.Manhattan: 253 | return sum; 254 | default: 255 | throw new ArgumentException("Unsupported distance metric."); 256 | } 257 | } 258 | } 259 | ``` 260 | 261 | #### Veliki broj komentara 262 | Na svakom mjestu gdje je prisutan komentar razmotriti potrebu dodavanja nove metode umjesto koda koji je komentiran. Nova metoda bi se zvala slicno kao i komentar u većini slučajeva. 263 | Neispravno: 264 | ```cs 265 | void FindLongestWord(List words){ 266 | int maxLength = 0; 267 | foreach(word in words){ 268 | if(word.Length > maxLength){//Checks which word is longer 269 | maxLength = word.Length; 270 | } 271 | } 272 | } 273 | ``` 274 | Ispravno: 275 | ```cs 276 | void FindLongestWord(List words){ 277 | int maxLength = 0; 278 | foreach(word in words){ 279 | maxLength = CompareValues(word.Length, maxLength) 280 | } 281 | } 282 | 283 | int CompareValues(int wordA, int wordB){ 284 | if(wordA>wordB){ 285 | return wordA; 286 | } 287 | return wordB 288 | } 289 | ``` 290 | #### Puno privremenih varijabli 291 | Napraviti novu klasu gdje su privremene varijable metode atributi nove klase a klasa sadrži tu metodu. 292 | Dobar primjer: https://blog.ploeh.dk/2015/09/18/temporary-field-code-smell/ 293 | 294 | ### Velike klase 295 | Klase sa velikim brojem atributa i velikim brojem velikih metoda. Za velike metode je potrebno napraviti ono što je navedeno u poglavlju [Velike metode](#velike-metode). Za atribute je potrebno razmotriti ima li smisla grupirati određene atribute u novu klasu i koristiti tu klasu umjesto brojnih atributa slično kao u poglavlju [Metode s velikim brojem parametara](#metoda-s-velikom-brojem-parametara) 296 | 297 | ### Zavidne metode 298 | Metode koje koriste veliki broj varijabl i/ili metoda iz neke druge klase. Za takve metode je potrebno razmotriti ima li smisla prebaciti ih u klasu gdje su atribute koje ta metoda koristi 299 | #### Dio metode koristi podatke druge klase 300 | Ako je moguće, dio metode koji koristi podatke druge klase je potrebno prebaciti u tu drugu klasu kao zasebnu metodu te tu novu metodu koristiti u početnoj. 301 | #### Metoda koristi podatke iz više drugih klasa 302 | Ako je moguće, odrediti koja klasa se najviše koristiti u metodi te premjestit metodu tamo. 303 | Neispravno: 304 | ```cs 305 | class ShapeRenderer{ 306 | public Constants Const { get; set; } 307 | public Math Math{ get; set; } 308 | ... 309 | public double Scale(int value, int norm){ 310 | return value/norm; 311 | } 312 | } 313 | 314 | class CircleControler{ 315 | ... 316 | public void RenderCircle(double radius){ 317 | Shaper shaper = new Shaper() 318 | radius = shaper.Scale(radius, 2); 319 | RenderShape(shaper.Math.Pow(radius,2)*shaper.Const.Pi) 320 | } 321 | ... 322 | public void CreateTarget(){ 323 | RenderCircle(2); 324 | RenderCircle(3); 325 | RenderCircle(4); 326 | } 327 | } 328 | ``` 329 | Ispravno: 330 | ```cs 331 | class ShapeRenderer{ 332 | public Constants Const { get; set; } 333 | public Math Math{ get; set; } 334 | ... 335 | public double Scale(int value, int norm){ 336 | return value/norm; 337 | } 338 | public void RenderCircle(double radius){ 339 | radius = shaper.Scale(radius, 2); 340 | RenderShape(shaper.Math.Pow(radius,2)*shaper.Const.Pi) 341 | } 342 | } 343 | 344 | class CircleControler{ 345 | ShapeRenderer shapeRenderer; 346 | public void CreateTarget(){ 347 | shapeRenderer.RenderCircle(2); 348 | shapeRenderer.RenderCircle(3); 349 | shapeRenderer.RenderCircle(4); 350 | } 351 | } 352 | ``` 353 | ### Nakpunine podataka 354 | Kad klasa sadrži veliki broj atributa i/ili kad metoda sadrži veliki broj parametara. Potrebno je razmotriti ima li smisla razbiti klasu na više manjih klasa. U slučaju metode vrijedi isto potrebno razmotriti ima li smisla razbiti metodu na više manjih metoda. Slično kao u [Metode s velikim brojem parametara](#metoda-s-velikom-brojem-parametara) 355 | 356 | ### Odbijeno nasljedstvo 357 | Radi se o dječijim klasama koje ne koriste sve atribut i metode svojih roditelja. Vrlo vjerovatno se radi o krivo sastavljenoj hijerarhiji klasa. U slučaju da ovo stvara preveliki problem razmisli ima li smilsa koristi kompoziciju umjesto nasljedivanja. 358 | Dobar blog sa primjerima u Javi: https://www.geeksforgeeks.org/favoring-composition-over-inheritance-in-java-with-examples/ 359 | Dobar blog sa primjerima u C#: https://code-maze.com/csharp-composition-vs-inheritance/ 360 | 361 | ### Lijene klase 362 | Male klase koje su često neptorebne i potrebno ih je ukloniti ili spojiti sa roditeljkom klasom ili nekom drugom klasom s kojim imas smisla biti spojena. Ponekad ima smisla ostaviti ju kakva je jer moeže uzrokovati probleme u sustavu zbog brkanja zavisnosti. 363 | Alt objašnjenj: https://code-smells.com/dispensables/lazy-class 364 | 365 | ### Privremeni atributi 366 | Atributi koji su povremeno ili rjetko korišteni, zbog njih je kod teže razumjeti. Takvi atributi nisu nužni i može ih se izdvojiti u drugu klasu. 367 | Dobar primjer: https://blog.ploeh.dk/2015/09/18/temporary-field-code-smell/ 368 | 369 | ### Divergentne promjene vs Operacija sačmaricom 370 | Divergente promjene se odnose na promjene koje nastaju kad je potrebno izmjeniti dio klase što uzrokuje promjene u drugim dijelovima klase. S druge strane Operacija sačmaricom su promjene koje nastaju kad potrebno izmjeniti dio klase što uzrokuje promjene u nizu drugih klasa. 371 | Dobar blog: https://code-maze.com/csharp-refactoring-change-preventers/ 372 | 373 | ### Podatkovne klase 374 | Klase koje sadrže samo atribute, geter i seter bez metoda koje imaju neku svrhu. Služe kao spremnici za podatke (u Kotlinu postoje podatkovne klase specifično za ovu svrhu). Data klase nisu same u sebi loše i ponekad imaju svrhu. 375 | 376 | Ako ih ima smisla koristiti potrebno je paziti na enkapsulaciju podataka. To uljučuje da podatci trebaju biti privtni i imati geter i setere samo ako je potrebno. Za kolekcije je potrebno pobrinuti se da ne vraćamo kolekciju već pogled na kolekciju i pripadne metode za modifikaciju kolekcije. 377 | 378 | Ako neke klase/metode većinski koriste podatke Podatkovne klase vidjeti ima li smisla prebaciti ih u tu klasu/metodu 379 | 380 | Dobar blog: https://code-smells.com/dispensables/data-class 381 | 382 | ### Opsežna uporaba komentara 383 | Komentari skoro nikada nisu potrebni. Ako kod sadrži komentare, komentirani dio je vrlo vjerovatno potrebno prevaciti u novu metodu i nazvati tu metodu na način da je razumljivo što radi i umjesto komentiranog koda korisiti novo napravljenu metodu. 384 | Pogledati ovaj video: https://www.youtube.com/watch?v=Bf7vDBBOBUA 385 | ### Naredba switch 386 | Switch je moguće koristiti u OOP jezicima ali je rjetko poželjno zbog alternativa koje OOP nudi polimorfizmom i nasljedivanjem. Jedna ili dvije switch naredbe u sustavu su ok i nebi trebale stvarati problem. Često korištena kao Jednostavna tvornica (nije oblikovni obrazac) koja stvara različite objekte iste klase. 387 | 388 | Primjer dolje je sa https://makolyte.com/refactoring-the-switch-statement-code-smell/ 389 | 390 | Neispravno: 391 | ```cs 392 | public class Bird 393 | { 394 | private readonly BirdType birdType; 395 | 396 | public Bird(BirdType type) 397 | { 398 | birdType = type; 399 | } 400 | public List GetColors() 401 | { 402 | switch (birdType) 403 | { 404 | case BirdType.Cardinal: 405 | return new List() { BirdColor.Black, BirdColor.Red }; 406 | case BirdType.Goldfinch: 407 | return new List() { BirdColor.Black, BirdColor.Yellow, BirdColor.White }; 408 | case BirdType.Chickadee: 409 | return new List() { BirdColor.Black, BirdColor.White, BirdColor.Tan }; 410 | } 411 | throw new InvalidBirdTypeException(); 412 | } 413 | public List GetFoods() 414 | { 415 | switch (birdType) 416 | { 417 | case BirdType.Cardinal: 418 | return new List() { BirdFood.Insects, BirdFood.Seeds, BirdFood.Fruit}; 419 | case BirdType.Goldfinch: 420 | return new List() { BirdFood.Insects, BirdFood.Seeds }; 421 | case BirdType.Chickadee: 422 | return new List() { BirdFood.Insects, BirdFood.Fruit, BirdFood.Seeds }; 423 | } 424 | throw new InvalidBirdTypeException(); 425 | } 426 | public BirdSizeRange GetSizeRange() 427 | { 428 | switch (birdType) 429 | { 430 | case BirdType.Cardinal: 431 | return new BirdSizeRange() { Lower=8, Upper=9 }; 432 | case BirdType.Goldfinch: 433 | return new BirdSizeRange() { Lower=4.5, Upper=5.5 }; 434 | case BirdType.Chickadee: 435 | return new BirdSizeRange() { Lower=4.75, Upper=5.75 }; 436 | } 437 | throw new InvalidBirdTypeException(); 438 | } 439 | } 440 | ``` 441 | 442 | Ispravno: 443 | ```cs 444 | public abstract class Bird 445 | { 446 | public abstract List GetColors(); 447 | public abstract List GetFoods(); 448 | public abstract BirdSizeRange GetSizeRange(); 449 | 450 | public static Bird Create(BirdType birdType) 451 | { 452 | switch (birdType) 453 | { 454 | case BirdType.Cardinal: 455 | return new Cardinal(); 456 | case BirdType.Chickadee: 457 | return new Chickadee(); 458 | case BirdType.Goldfinch: 459 | return new Goldfinch(); 460 | default: 461 | throw new InvalidBirdTypeException(); 462 | } 463 | } 464 | } 465 | 466 | public class Cardinal : Bird 467 | { 468 | public override List GetColors() 469 | { 470 | return new List() { BirdColor.Black, BirdColor.Red }; 471 | } 472 | 473 | public override List GetFoods() 474 | { 475 | return new List() { BirdFood.Insects, BirdFood.Seeds, BirdFood.Fruit }; 476 | } 477 | 478 | public override BirdSizeRange GetSizeRange() 479 | { 480 | return new BirdSizeRange() { Lower = 8, Upper = 9 }; 481 | } 482 | } 483 | 484 | public class Chickadee : Bird 485 | { 486 | public override List GetColors() 487 | { 488 | return new List() { BirdColor.Black, BirdColor.White, BirdColor.Tan }; 489 | } 490 | 491 | public override List GetFoods() 492 | { 493 | return new List() { BirdFood.Insects, BirdFood.Fruit, BirdFood.Seeds }; 494 | } 495 | 496 | public override BirdSizeRange GetSizeRange() 497 | { 498 | return new BirdSizeRange() { Lower = 4.75, Upper = 5.75 }; 499 | } 500 | } 501 | 502 | public class Goldfinch: Bird 503 | { 504 | public override List GetColors() 505 | { 506 | return new List() { BirdColor.Black, BirdColor.Yellow, BirdColor.White }; 507 | } 508 | 509 | public override List GetFoods() 510 | { 511 | return new List() { BirdFood.Insects, BirdFood.Seeds }; 512 | } 513 | 514 | public override BirdSizeRange GetSizeRange() 515 | { 516 | return new BirdSizeRange() { Lower = 4.5, Upper = 5.5 }; 517 | } 518 | } 519 | ``` 520 | ### Čovjek u sredini 521 | Kad klasa služi kao posrednik između klijenta i klase koja obavlja posao. Ako želimo dodati novu funkcionlanost u klasu koja obavlja posao moramo dodati i nove metode u klasu koja služi kao posrednik kako bi se nove funkcionalnosti mogle koristiti u klijentskom kodu. 522 | Primjer dolje je sa: https://www.thecodebuzz.com/middle-man-code-smell-resolution-examples 523 | 524 | Neispravno: 525 | ```cs 526 | class Program 527 | { 528 | static void Main(string[] args) 529 | { 530 | Person person = new Person(); 531 | person = person.GetManager(); 532 | } 533 | } 534 | 535 | 536 | class Person 537 | { 538 | public Department Department { get; set; } 539 | public Person GetManager() 540 | { 541 | return Department.GetManager(); 542 | } 543 | } 544 | 545 | 546 | class Department 547 | { 548 | private readonly Person _manager; 549 | public Department(Person manager) 550 | { 551 | _manager = manager; 552 | } 553 | public Person GetManager() 554 | { 555 | return _manager; 556 | } 557 | } 558 | ``` 559 | 560 | Ispravno: 561 | ```cs 562 | class Program 563 | { 564 | static void Main(string[] args) 565 | { 566 | Person person = new Person(); 567 | Department department = person.GetDepartment(); 568 | person = department.GetManager(); 569 | } 570 | } 571 | 572 | class Person 573 | { 574 | public Department Department; 575 | public Department GetDepartment() 576 | { 577 | return Department; 578 | } 579 | } 580 | 581 | class Department 582 | { 583 | private readonly Person _manager; 584 | public Department(Person manager) 585 | { 586 | _manager = manager; 587 | } 588 | public Person GetManager() 589 | { 590 | return _manager; 591 | } 592 | } 593 | ``` 594 | 595 | ## Antiobrasci 596 | Ako neki sustav pati od jednog ili više antiobrazaca potrebno je razmotriti o kojim se obrascima radi te koja se moguća rješenja mogu implementirati kako bi se suzbili utjecaji antiobrazaca. Potrebno je razmotriti do čega antiobrazci u sustavu mogu s vremenom dovesti, ima li ih smisla popravljati i ako ima koliko će popravljanje trajati. 597 | 598 | ### Božanska klasa 599 | Antiobrazac kod kojeg jedna klasa sadrži previše metoda i atributa te je prevelika odgovornost na njoj i krši načela OOP-a. Takvu klasu je moguće i potrebno razdvojiti na više manjih klasa grupiranjem srodnih atributa i metoda božanske klase. 600 | 601 | ### Mrtav kod 602 | Kod u sustavu koji nesluži nikakvoj svrsi, često zbunjujuć i nije jasno što točno radi. Najčešće nema nikakvih posljedica ukljanjanja takvog koda i poželjno je. 603 | 604 | ### Funkcijska dekompozicija 605 | Proceduralni pristup u objektno orijentiranom programiranju koje se često manifestira u forsiranju proceduralnog dizajna u objektno orjentiranom jeziku gdje to nema smisla. Očituje se u manjku OOP strukture ne korištenju kompozcije niti nasljedivanje što često rezultira klasama koje imaju jednu metodu koja se zove slično kao i klasa. 606 | 607 | Dobar izvor: https://sourcemaking.com/antipatterns/functional-decomposition 608 | 609 | ### Poltergeist 610 | Antiobrazac koji opisuje dizajn sustava gdje postoje klase koje se instanciraju, odrade nešto posla i ostatak životnog vremena provedu ne radeći ništa tj. samo zauzimaju nepotrebne resurse. 611 | 612 | Dobar izvor: https://sourcemaking.com/antipatterns/poltergeists 613 | 614 | ### Zlatni čekić 615 | Antiobrazac koji se manifestira korištenjem istog pristupa za sve probleme u sustavu. 616 | 617 | Dobar izvor: https://sourcemaking.com/antipatterns/golden-hammer 618 | 619 | ### Špageti kod 620 | Antiobrazac koji opisuje sustav s lošom oop strukturom na način da ga je teško održavati, manjka u nasljedivanju i kompoziciji i ako ih koristi ne radi to ispravno i s time pridonisi ne razumljivosti koda. 621 | 622 | Dobar izvor: https://sourcemaking.com/antipatterns/spaghetti-code 623 | 624 | ### Cut and paste programiranje 625 | Pojavljivanje istih ili sličnih dijelova kod na više mjesta u aplikaciju. Nastaje kad copy-pastamo kod iz jednog dijela aplikacije u drugi. Opasno jer kod koji kopiramo moze sadržavati bugove koje onda raznosimo po sustavu i kad treba popraviti taj bug potrebno ga je naći popraviti na više mjesta. 626 | 627 | ### Magični brojevi i stringovi 628 | Zboj uporabe loših značenje konstanti je djelomično ili potpuno skriveno. 629 | 630 | ### Realni tipovi za novac 631 | Kod korištenja realnih tipova podatak za predstavljanje novca dolazi do grešaka u zaokruživanju pri izvođenju operacija nad brojevima što stvara neželjen deficit ili suficit. Novce je potrebno predstaviti sa cjelobrojnim tipovima podataka ili koristiti posebne tipove za novce. 632 | 633 | ### Strah od dodavanja klasa 634 | Loša metodologija kod koje programer umjesto da definira novu klasu sa novom potrebnom metodom i atributima stavlja novu metodu i atribute u postojeću klasu. Ovakav pristup negativno utječa na čitljivost 635 | 636 | ## STUPID code 637 | Šest pristupa u kodiranju koji rezultiraju sustavom koji nije modularan, kojeg je teško testirati te je otporan na promjene. 638 | 639 | - Singleton 640 | Oblikovni obrazac koji ograničava broj instanci u sustavu na način da postoji jedna instanca dostupna kroz cijeli sustav.To je nekad poželjno no često krivo korišteno na mjestime gdje nije potreban. 641 | - Tight coupling 642 | Čvrsta sprega je pojava u oop sustavima gdje promjena jedne klase zahtjeva promjenu druge. Nekad imas smisla implementirati ali najčešće želimo imati sustav čije komponente lako zamjenjive. 643 | - Untestability 644 | U kontekstu oop-a odnosi se na unit testiranje tj. testiranje klasa. Ako su dvije klase previše ovisne jedna o drugoj to otežava testiranje 645 | - Premature optimisation 646 | Događa se programer nepotrebno komplicira ili previse misli pri implementaciji (engl. overthingking) i onda napravi nepotrebno kompleksan sustav. Pri implementaciji bilo koje funkcionalnosti prvo nakodiraj funkcionalnsot da radi a tek nakon što funkcionalnost radi vidi trebaš li je optimizirati ili ne. 647 | - Indescriptive naming 648 | [Koristi svrhovita imena](/DevOfSwSuppWithOOP/CleanCode/README.hr.md#koristi-svrhovita-imena) 649 | - Duplication 650 | [Duplicirani kod](#duplicirani-kod) 651 | --------------------------------------------------------------------------------