├── 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 |
--------------------------------------------------------------------------------