Ocena mojego kodu obsługującego 2 windy (początkujący alert)

0

Hej,

W temacie programowania obiektowego - a co za tym idzie też w c# - jestem w miarę nowy. Uczę się go od 3 miesięcy. Wcześniej miałem styczność z różnymi językami, ale zawsze była to zabawa językami nie-obiektowymi.

Stworzyłem aplikację WPF, która wyświetla 2 windy (2xLabel) i ma obok n pięter w postaci Buttonów. Po przyciśnięciu przycisku piętra - "wołamy" windę.
"Algorytm" działania wind nie jest zbyt wyszukany - po prostu jeżeli jakaś winda jest wolna to jedzie do najbliższego zgłoszenia.

Chodzi mi o ocenę kodu mojej aplikacji. Czy idę w ogóle w dobrą stronę, czy robię coś zbyt "łopatologicznie", mało elastycznie (obsługa większej ilości wind w planach ;) ) czy niezgodnie z konwencją.

Zaznaczam, że nie przygotowywałem kodu pod używanie go przez kogoś innego, więc wiem, że można namieszać w nim, jeżeli nie zna się "konwencji" ;)

OK, już się nie tłumaczę. Poniżej kody XAML i C#:

XAML:

<Window x:Class="Windy.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="980" Width="368">
    <Grid Name="Widok">
        <Label x:Name="winda1Label" Content="Winda 1" HorizontalAlignment="Left" Margin="121,913,0,0" VerticalAlignment="Top"/>
        <Button Content="0" HorizontalAlignment="Left" Margin="81,913,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="1" HorizontalAlignment="Left" Margin="81,883,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="2" HorizontalAlignment="Left" Margin="81,853,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="3" HorizontalAlignment="Left" Margin="81,823,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="4" HorizontalAlignment="Left" Margin="81,793,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="5" HorizontalAlignment="Left" Margin="81,763,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="6" HorizontalAlignment="Left" Margin="81,733,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="7" HorizontalAlignment="Left" Margin="81,703,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="8" HorizontalAlignment="Left" Margin="81,673,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="9" HorizontalAlignment="Left" Margin="81,643,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="10" HorizontalAlignment="Left" Margin="81,613,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="11" HorizontalAlignment="Left" Margin="81,583,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="12" HorizontalAlignment="Left" Margin="81,553,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="13" HorizontalAlignment="Left" Margin="81,523,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="14" HorizontalAlignment="Left" Margin="81,493,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="15" HorizontalAlignment="Left" Margin="81,463,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="16" HorizontalAlignment="Left" Margin="81,433,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="17" HorizontalAlignment="Left" Margin="81,403,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="18" HorizontalAlignment="Left" Margin="81,373,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="19" HorizontalAlignment="Left" Margin="81,343,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="20" HorizontalAlignment="Left" Margin="81,313,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="21" HorizontalAlignment="Left" Margin="81,283,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="22" HorizontalAlignment="Left" Margin="81,253,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="23" HorizontalAlignment="Left" Margin="81,223,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="24" HorizontalAlignment="Left" Margin="81,193,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="25" HorizontalAlignment="Left" Margin="81,163,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="26" HorizontalAlignment="Left" Margin="81,133,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="27" HorizontalAlignment="Left" Margin="81,103,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="28" HorizontalAlignment="Left" Margin="81,73,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="29" HorizontalAlignment="Left" Margin="81,43,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        <Button Content="30" HorizontalAlignment="Left" Margin="81,13,0,0" VerticalAlignment="Top" Click="Button_Click" Width="20"/>
        
        
        <Label x:Name="winda2Label" Content="Winda 2" HorizontalAlignment="Left" Margin="213,913,0,0" VerticalAlignment="Top"/>

    </Grid>
</Window> 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Windows.Threading;

namespace Windy
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        PanelSterujący panel;
        public static Brush DomyślnyKolorPrzycisku;
        public MainWindow()
        {
            // TO DO LIST
            // 1. Określenie, która winda będzie szybciej na miejscu - niezależnie od tego, czy jest w drodze, czy nie.
            // --- >> 2. Jak naciskamy kilka przycisków na raz to nie musimy robić kolejki, tylko może najlepiej zatrzymać się na kilku piętrach po drodze. << --- DONE
            // 3. Zadania dla poszczególnych wind, jeżeli się zatrzymają gdzieś.
            // 4. Dodać obsługę większej ilości Wind w PaneluSterującym

            InitializeComponent();
            
            var winda1 = new Winda(ref winda1Label);
            var winda2 = new Winda(ref winda2Label);
            var listaPrzycisków = Widok.Children.OfType<Button>();
            var listaPrzycisków2 = listaPrzycisków.ToList<Button>();
            DomyślnyKolorPrzycisku = listaPrzycisków2[0].Background;
            panel = new PanelSterujący(ref winda1, ref winda2, ref listaPrzycisków2);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            panel.ZawołajWindę(int.Parse(((Button)sender).Content.ToString())); 
        }
    }

    public class Winda
    {
        private BackgroundWorker workerWindy;
        public bool Stoi;
        public int Piętro;
        public int NaKtórePiętro;
        private Label ktoraWindaLabel;

        public Winda(ref Label label)
        {
            this.Stoi = true;
            this.Piętro = 0;
            this.ktoraWindaLabel = label;
        }

        public void Jedź(int piętro)
        {
            workerWindy = new BackgroundWorker();
            this.Stoi = false;
            this.NaKtórePiętro = piętro;
            workerWindy.DoWork += workerWindy_Jedź;
            workerWindy.RunWorkerAsync();
        }

        private void workerWindy_Jedź(object sender, DoWorkEventArgs e)
        {
            int ile = Math.Abs(this.Piętro - this.NaKtórePiętro);
            int wKtórąStronę = (NaKtórePiętro - Piętro) / Math.Abs(NaKtórePiętro - Piętro);
            for (int i = 0; i < ile; i++)
            {
                System.Threading.Thread.Sleep(500);
                this.Piętro += wKtórąStronę;
                zmienUstawienieElementów(true, false, wKtórąStronę * (-30));
            }
            System.Threading.Thread.Sleep(5000);
            zmienUstawienieElementów(false, true);
            this.Stoi = true;
            PanelSterujący.SprawdźCzyJestJeszczeCośWKolejce();
        }

        private void zmienUstawienieElementów(bool winda, bool przycisk, int wKtórąStronę = 0)
        {
            if (winda)
            {
                Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
                {
                    this.ktoraWindaLabel.Margin = new Thickness(this.ktoraWindaLabel.Margin.Left, this.ktoraWindaLabel.Margin.Top + wKtórąStronę, 0, 0);
                }));
            }
            if (przycisk)
            {
                Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
                {
                    PanelSterujący.ListaPrzycisków[this.Piętro].Background = MainWindow.DomyślnyKolorPrzycisku;
                    PanelSterujący.ListaPrzycisków[this.Piętro].IsEnabled = true;
                }));
            }
        }
    }

    public class PanelSterujący
    {
        public static Winda Winda1;
        public static Winda Winda2;
        public static List<Button> ListaPrzycisków { get; set; }
        public static List<int> ListaPięterDoObsłużenia { get; set; }

        public PanelSterujący(ref Winda winda1, ref Winda winda2, ref List<Button> listaPrzycisków)
        {
            ListaPrzycisków = listaPrzycisków;
            ListaPięterDoObsłużenia = new List<int>();
            Winda1 = winda1;
            Winda2 = winda2;
        }

        public static void SprawdźCzyJestJeszczeCośWKolejce()
        {
            if (ListaPięterDoObsłużenia.Count > 0)
                if (Winda1.Stoi || Winda2.Stoi)
                    wyślijWindę();
        }

        private static int znajdźNajbliższąWartość(int piętro)
        {
            var minOdległość = ListaPięterDoObsłużenia.Min(n => Math.Abs(piętro - n));
            return ListaPięterDoObsłużenia.First(n => Math.Abs(piętro - n) == minOdległość);
        }

        private static void wyślijWindę()
        {
            var ktoraWinda = Winda1;
            int najbliższePiętro = 0;
            if (Winda1.Stoi && Winda2.Stoi)
            {
                int najbliższePiętro1 = znajdźNajbliższąWartość(Winda1.Piętro);
                int najbliższePiętro2 = znajdźNajbliższąWartość(Winda2.Piętro);
                bool pierwszeMniejszeOdDrugiego = najbliższePiętro1 - Winda1.Piętro <= najbliższePiętro2 - Winda2.Piętro;
                najbliższePiętro = pierwszeMniejszeOdDrugiego ? najbliższePiętro1 : najbliższePiętro2;
                ktoraWinda = pierwszeMniejszeOdDrugiego ? Winda1 : Winda2;
            }
            else
            {
                ktoraWinda = (Winda1.Stoi && !Winda2.Stoi) ? Winda1 : Winda2;
                najbliższePiętro = znajdźNajbliższąWartość(ktoraWinda.Piętro);
            }
            ListaPięterDoObsłużenia.Remove(najbliższePiętro);
            ktoraWinda.Jedź(najbliższePiętro);
        }

        public void ZawołajWindę(int piętro)
        {
            if (!(Winda1.Piętro == piętro && Winda1.Stoi) && !(Winda2.Piętro == piętro && Winda2.Stoi))
            {
                ListaPięterDoObsłużenia.Add(piętro);
                ListaPrzycisków[piętro].IsEnabled = false;
                SprawdźCzyJestJeszczeCośWKolejce();
            }
        }
    }
} 

dodanie znacznika <code class="xml"> - @furious programming

0

Pierwsze co rzuca się w oczy to używanie polskich znaków w nazwach metod i zmiennych. Nie należy to do dobrych praktyk programistycznych.

0

<abbr title="Don't repeat yourself">dry</abbr>

1 użytkowników online, w tym zalogowanych: 0, gości: 1