MVP паттерн

Хичээлээр анх IBM боловсруулан гаргасан Model View Presenter (MVP) - хэвийн талаар үзнэ. MVP нь MVC загвараас үүдэлтэй боловч програмын зохион байгуулалт талаасаа нилээд өөр хандлагатай. MVP паттерн MVC -г бодвол үзүүлбэр моделтой нягт холбоогүй байдаг онцлогтой. Доор зурагт MVP хэвийн бүтцийг харууллаа.

patt_04_01

Зургаас харахад контролерын оронд Presenter орж ирэн хэрэглэгчийн оруулсан өгөгдлийн шилжилт, загварын өөрчлөлтийг үзүүлбэрт тусгах үүргийг хариуцах болсон нь харагдана.

Presenter үзүүлбэртэй интерфейсээр дамжин харьцсанаар тестлэх боломжийг сайжруулна. Учир нь загварыг модулийн тестэд зориулагдсан тусгай загвараар сольж болно. MVP хэвийг MVC гийн адилаар програмын бизнес логик талаас авч үзцгээе.

patt_04_02

Бизнес логикийн талаас харвал MVP нь програмын бүхий л бизнес логикийг загварт багтаан харин өгөгдөлд хандалтын кодыг загвараас тусгаарласан нь MVC тэй адилхан. Энэ нь MVP нь MVC загвараас үүдэлтэйг батлана. MVP -д зөвхөн үзүүлбэрийн логик л өөр болсон.
Өмнөх хичээлүүдэд үзсэнтэй ижилхэн WPF програмын жишээг MVP паттернг ашиглан хийцгээе. Програмын бүтцийг дараах UML диаграмаар харууллаа.

patt_04_03

Үзүүлбэр IProjectsView интерфейсийг хэрэгжүүлэх ProjectsView классыг ашиглана. ProjectsView ба IProjectsView -д үзүүлбэрийг шинэчлэх, Presenter - тэй холбогдоход шаардлагатай бүхий л аргууд агуулагдана. Харин Presenter дотроо IProjectsView , IProjectsModel интерфейсийн төрлүүдийн холбоосыг ProjectsPresenter.view , ProjectsPresenter.model хэлбэрийн хувьсагч /шинж/ байдлаар агуулсан. Ийм зохион байгуулалт модел болон үзүүлбэрийн хоорондын харилцааг Presenter -ээр дамжуулан хийх боломжийг олгоно.
Бүтэц хэрхэн ажиллахыг тайлбарлая. Хэрвээ хэрэглэгч Update товчийг дарвал моделийг шинэчлэх ProjectsPresenter.view_ProjectUpdated() аргыг дуудах IProjectView.ProjectUpdated үйл явдлын боловсруулагч ажиллана. Загвар шинэчлэгдэх үед Presenter -ээр дамжин хэрэглэгчийн графикийн интерфейсийг шинэчлэх үйл явдлын IProjectsModel.ProjectUpdated боловсруулагч ажиллах юм. Эхэндээ загварын ажиллагааг ойлгоход хүндрэлтэй байж магадгүй. Түвшин хоорондын хамаарлыг бага болгохын тулд интерфейсийг хэрхэн ашиглаж байгааг сайн ойлгон аваарай. Ийм бүтцээр бичигдсэн програмыг цаашид хөгжүүлэх, кодыг ойлгоход цаг хугацаа, хүч хөдөлмөр хөнгөлдөг тул аргачлалыг өөрийн ажилдаа ашиглаж сурах хэрэгтэй. Бид үзүүлбэрийг үүсгэх логикийг Presenter -т шилжүүлсэн тул MVC загварыг бодвол тестлэх боломжоор хамаагүй илүү. MVC хэвд үзүүлбэрийг моделоос шууд үүсгэн өгдөг.
За одоо програмаа зохиоё. Програм MVC паттерн хичээлд үзсэнтэй яг адилхан ажиллана.

Модел

Visual StudioProjectBilling.UI.MVP нэртэй WPF шинэ төсөл үүсгээд Графикийн паттерн хичээлд үүсгэсэн ProjectBilling.DataAccess төслийн холбоосыг нэмэн өгөөрэй. Бид шинэ шийдэл /solution/ үүсгэсэн болохоор ProjectBilling.DataAccess төслийн холбоос үүсгэхийн тулд шийдэлд төслийг нэмэн оруулах хэрэгтэй. Үүний тулд шийдлийн нэр дээр баруун даралт хийхэд гарч ирэх цэснээс Add->Existing Project гэж ороод ProjectBilling.DataAccess төслийг заан өгнө. Төсөл шийдэлд нэмэгдсэний дараа ProjectBilling.UI.MVP төслийн Reference дээр баруун даралт хийгээд Add Reference цэсээр ороод доорх зурагт үзүүлснээр ProjectBilling.DataAccess төслийн холбоосыг нэмнэ.

patt_04_04

ProjectBilling.UI.MVP төсөлд дараах агуулга бүхий ProjectsModel классыг нэмнэ.

using System;
using System.Collections.Generic;
using System.Linq;
using ProjectBilling.DataAccess;

namespace ProjectBilling.Business
{
    #region ProjectsEventArgs

    public class ProjectEventArgs : EventArgs
    {
        public Project Project { get; set; }
        public ProjectEventArgs(Project project)
        {
            Project = project;
        }
    }

    #endregion ProjectsEventArgs

    public interface IProjectsModel
    {
        void UpdateProject(Project project);
        IEnumerable<Project> GetProjects();
        Project GetProject(int Id);
        event EventHandler<ProjectEventArgs> ProjectUpdated;
    }

    public class ProjectsModel : IProjectsModel
    {
        private IEnumerable<Project> projects = null;

        public event EventHandler<ProjectEventArgs>
            ProjectUpdated = delegate { };

        public ProjectsModel()
        {
            projects = new DataServiceStub().GetProjects();
        }

        public void UpdateProject(Project project)
        {
            ProjectUpdated(this,
                new ProjectEventArgs(project));
        }

        public IEnumerable<Project> GetProjects()
        {
            return projects;
        }


        public Project GetProject(int Id)
        {
            return projects.Where(p => p.ID == Id)
                .First() as Project;
        }
    }
}

Моделийн класс ProjectsModel доорх гишүүдтэй IProjectsModel интерфейсийг хэрэгжүүлж байгаа.

  • UpdateProject() арга төслийг шинэчлэнэ. Аргыг төлвөөр дамжуулан шинэчлэлийг хийж болохоор өргөжүүлж болох ч энд энгийн байлгах үүднээс үүнийг авч үзээгүй.
  • GetProjects() төслүүдийн жагсаалтыг авчирна.
  • GetProject() төслийг ID -гаар нь буцаана
  • ProjectUpdated төсөлд өөрчлөлт ороход дуудагдах үйл явдал.

ProjectEventArgs бол гишүүдийг нь үйл явдлын ProjectUpdated боловсруулагч ашиглаж болох туслах класс

Үзүүлбэр

Үзүүлбэрийг ProjectView.xaml , ProjectView.xaml.cs файлууд үүсгэнэ. Төсөлд үзүүлбэрийг нэмэхийн тулд төслийн нэр дээр баруун даралт хийхэд гарч ирэх цэснээс Add->Window гэж ороод үзүүлбэрийн нэрээ өгөхөд VS засварлагч .xaml, .cs өргөтгөлтэй файлуудыг төсөлд нэмэн оруулна. ProjectView.xaml файл дараах агуулгатай байна.

<Window x:Class="ProjectBilling.UI.MVP.ProjectsView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Төслүүд" MinHeight="265" Height="265"
        MinWidth="250" Width="250">
    <StackPanel>
        <Label Content="Төсөл:" Margin="5, 0, 5, 0" />
        <ComboBox Name="projectsComboBox" Margin="5, 0, 5, 0"
                SelectionChanged="projectsComboBox_SelectionChanged" />
        <Label Content="Нэр:" Margin="5, 0, 5, 0" />
        <TextBox Name="nameTextBox" Margin="5, 0, 5, 0"
                IsEnabled="False" />
        <Label Content="Тооцооны өртөг:" Margin="5, 0, 5, 0" />
        <TextBox Name="estimatedTextBox" Margin="5, 0, 5, 0"
                IsEnabled="False" />
        <Label Content="Гүйцэтгэлийн өртөг:" Margin="5, 0, 5, 0" />
        <TextBox Name="actualTextBox" Margin="5, 0, 5, 0"
                IsEnabled="False" />
        <Button Name="updateButton" Content="Update"
                Margin="5, 10, 5, 0" IsEnabled="False"
                Click="updateButton_Click" />
    </StackPanel>
</Window>

Формын кодыг үзүүлбэл

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using ProjectBilling.Business;
using ProjectBilling.DataAccess;

namespace ProjectBilling.UI.MVP
{

    public interface IProjectsView
    #region IProjectsView
    {
        int NONE_SELECTED { get; }
        int SelectedProjectId { get; }
        void UpdateProject(Project project);
        void LoadProjects(IEnumerable<Project> projects);
        void UpdateDetails(Project project);
        void EnableControls(bool isEnabled);
        void SetEstimatedColor(Color? color);
        event EventHandler<ProjectEventArgs> ProjectUpdated;
        event EventHandler<ProjectEventArgs> DetailsUpdated;
        event EventHandler SelectionChanged;
    }

    #endregion IProjectsView

    #region ProjectsView


    public partial class ProjectsView : Window, IProjectsView
    {
        #region Initialization

        public int NONE_SELECTED { get { return -1; } }
        public event EventHandler<ProjectEventArgs>
        ProjectUpdated = delegate { };
        public int SelectedProjectId { get; private set; }

        public event EventHandler SelectionChanged
            = delegate { };
        public event EventHandler<ProjectEventArgs>
            DetailsUpdated = delegate { };

        public ProjectsView()
        {
            InitializeComponent();
            SelectedProjectId = NONE_SELECTED;
        }

        #endregion Initialization

        #region Event handlers

        private void updateButton_Click(object sender,
            RoutedEventArgs e)
        {
            Project project = new Project();
            project.Name = nameTextBox.Text;
            project.Estimate =
                GetDouble(estimatedTextBox.Text);
            project.Actual =
                GetDouble(actualTextBox.Text);
            project.ID =
                int.Parse(
                    projectsComboBox.SelectedValue.
                        ToString());
            ProjectUpdated(this,
                new ProjectEventArgs(project));
        }

        private void projectsComboBox_SelectionChanged(
            object sender, SelectionChangedEventArgs e)
        {
            SelectedProjectId
                = (projectsComboBox.SelectedValue == null)
                      ? NONE_SELECTED
                      : int.Parse(
                          projectsComboBox.SelectedValue.
                              ToString());
            SelectionChanged(this,
                new EventArgs());
        }

        #endregion Event handlers

        #region Public methods

        public void UpdateProject(Project project)
        {
            IEnumerable<Project> projects =
                projectsComboBox.ItemsSource as
                    IEnumerable<Project>;
            Project projectToUpdate =
                projects.Where(p => p.ID == project.ID)
                    .First() as Project;
            projectToUpdate.Name = project.Name;
            projectToUpdate.Estimate = project.Estimate;
            projectToUpdate.Actual = project.Actual;
            if (project.ID == SelectedProjectId)
                UpdateDetails(project);
        }

        public void LoadProjects(IEnumerable<Project> projects)
        {
            projectsComboBox.ItemsSource = projects;
            projectsComboBox.DisplayMemberPath = "Name";
            projectsComboBox.SelectedValuePath = "ID";
        }

        public void EnableControls(bool isEnabled)
        {
            estimatedTextBox.IsEnabled = isEnabled;
            actualTextBox.IsEnabled = isEnabled;
            updateButton.IsEnabled = isEnabled;
        }

        public void SetEstimatedColor(Color? color)
        {
            estimatedTextBox.Foreground
                = (color == null)
                      ? actualTextBox.Foreground
                      : new SolidColorBrush((Color)color);
        }

        public void UpdateDetails(Project project)
        {
            nameTextBox.Text = project.Name;
            estimatedTextBox.Text
                = project.Estimate.ToString();
            actualTextBox.Text
                = project.Actual.ToString();
            DetailsUpdated(this,
                new ProjectEventArgs(project));
        }

        #endregion Public methods

        #region Helpers

        private double GetDouble(string text)
        {
            return string.IsNullOrEmpty(text)
                ? 0 : double.Parse(text);
        }

        #endregion Helpers

    }

    #endregion ProjectsView
}

байна. Кодын бүтэц дээр үзүүлсэн UML диаграмтай тохирно.

Presenter

Presenter -ыг ердийн класс нэмэх байдлаар оруулна. Харин классын нэрийг ProjectsPresenter гэж өгөөд доорх агуулгыг оруулан өгөөрэй.

using System;
using System.Windows.Media;
using ProjectBilling.Business;
using ProjectBilling.DataAccess;

namespace ProjectBilling.UI.MVP
{
    public class ProjectsPresenter
    {
        #region Initialization

        private IProjectsView view = null;
        private IProjectsModel model = null;

        public ProjectsPresenter(IProjectsView projectsView,
            IProjectsModel projectsModel)
        {
            view = projectsView;
            view.ProjectUpdated += view_ProjectUpdated;
            view.SelectionChanged
                += view_SelectionChanged;
            view.DetailsUpdated += view_DetailsUpdated;
            model = projectsModel;
            model.ProjectUpdated += model_ProjectUpdated;
            view.LoadProjects(
                model.GetProjects());
        }

        #endregion Initialization

        #region Event handlers

        private void view_DetailsUpdated(object sender,
            ProjectEventArgs e)
        {
            SetEstimatedColor(e.Project);
        }

        private void view_SelectionChanged(object sender,
            EventArgs e)
        {
            int selectedId = view.SelectedProjectId;
            if (selectedId > view.NONE_SELECTED)
            {
                Project project =
                    model.GetProject(selectedId);
                view.EnableControls(true);
                view.UpdateDetails(project);
                SetEstimatedColor(project);
            }
            else
            {
                view.EnableControls(false);
            }
        }

        private void model_ProjectUpdated(object sender,
            ProjectEventArgs e)
        {
            view.UpdateProject(e.Project);
        }

        private void view_ProjectUpdated(object sender,
            ProjectEventArgs e)
        {
            model.UpdateProject(e.Project);
            SetEstimatedColor(e.Project);
        }

        #endregion Event handlers

        #region Helpers

        private void SetEstimatedColor(Project project)
        {
            if (project.ID == view.SelectedProjectId)
            {
                if (project.Actual <= 0)
                {
                    view.SetEstimatedColor(null);
                }
                else if (project.Actual
                         > project.Estimate)
                {
                    view.SetEstimatedColor(Colors.Red);
                }
                else
                {
                    view.SetEstimatedColor(Colors.Green);
                }
            }
        }

        #endregion Helpers
    }
}

Энд үйл явдлын дараах боловсруулагчдыг тодорхойлсон.

  • view_DetailsUpdated боловсруулагч IProjectsView.DetailsUpdated үйл явдлын хариу байдлаар дуудагдах бөгөөд төслийн гүйцэтгэлийн өртөгийг харуулах TextBox -ийн өнгийг шинэчлэх SetEstimateColor() аргыг дуудна.
  • view_SelectionChanged нь IProjectsView.SelectionChanged үйл явдал үүсэхэд үзүүлбэрийг өөрчилнө. Үйл явдал ComboBox -д шинэ төслийг сонгоход үүснэ.
  • model_ProjectUpdated боловсруулагч IProjectsModel.ProjectUpdate -ийн хариуд дуудагдан модел ба үзүүлбэрийн шинэчлэлтийг ажиллуулна.

Хэрвээ та хэвүүд ашиглан програм зохиож байгаагүй бол код ойлгомжгүй байж мэднэ. C# хэлний мэдлэгтэй бол энд бичсэн кодууд их энгийн учраас юу хийж байгааг ойлгоход амархан. Хамгийн гол зүйл бол паттерныг ашиглан програмын кодыг хэрхэн зохион байгуулж байгааг сурах юм. Хэвийг ОХП-ын ямарч хэлэнд ашиглаж болно.
Одоо програмын эхлэлийн цонх MainWindow.xaml -аас ProjectsView үзүүлбэрийг нээх боломжтой болгохын тулд MainWindow.xaml -д доорх өөрчлөлтийг оруулъя.

<Window x:Class="ProjectBilling.UI.MVP.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="250" Width="250"
        MinHeight="250" MinWidth="250">
    <StackPanel>
        <Button Content="Төслийг үзүүлэх"
                Name="showProjectsButton" Margin="5, 10, 5, 0"
                Click="showProjectsButton_Click" />
    </StackPanel>
</Window>

Үндсэн цонхонд төслийн үзүүлбэрийг харуулах товч нэмсэн тул MainWindow.cs файлын агуулгыг доорх байдлаар өөрчлөөрэй.

using System.Windows;
using ProjectBilling.Business;

namespace ProjectBilling.UI.MVP
{
    public partial class MainWindow : Window
    {
        private IProjectsModel model = null;

        public MainWindow()
        {
            InitializeComponent();
            model = new ProjectsModel();
        }

        private void showProjectsButton_Click(object sender,
            RoutedEventArgs e)
        {
            ProjectsView view = new ProjectsView();
            ProjectsPresenter presenter
                = new ProjectsPresenter(view, model);
            view.Owner = this;
            view.Show();
        }
    }
}

Програмыг ажлуулбал MVC паттерн хичээлд хийсэн жишээтэй ижилхэн үр дүн гарч ирнэ. Энд MVP -д ашиглаж байгаа Presenter бүтэц л чухал. Танд ийм амархан зүйлийг хэтэрхий их ажил нэмэн хийгээд байгаа мэт санагдаж магадгүй. Сургалтын жишээнд л ингэж санагдана. Програм том хэмжээний олон асуудлыг шийдэх хэрэгтэй болоход хэвийн ач тус мэдрэгдэнэ. Хэвийн ерөнхий бүтцийг гаргах ажиллагаа нь таны програмын том жижгээс хамаарахгүй учраас л тэгж санагдаж байгаа юм. Цааш програмын хэмжээ томрох үед энэ загвараа ашиглаад явах болохоор асуудал багатай. MVC -тэй харьцуулбал MVP нилээд дэвшлийг авчирсан.

  • MVP нь Presenter -ээр дамжуулан төлвийн шалгалт, үзүүлбэрийн логикийг удирдах боломжийг өгсөн.
  • Үзүүлбэрийг моделоос бүрэн салгаж тэдгээрийн холбоог Presenter -ээр дамжуулан зохион байгуулсан.

MVP нь MVC гээс ялгаатай нь IView интерфейсийг ашигласнаар загварт шууд өөрчлөлт хийхгүйгээр бизнес логикийг дахин ашиглах боломжийг олгодог. Жишээ нь та энэ WPF програмыг Silverlight рүү шилжүүлэх хэрэгтэй болбол Silverlight дээр IProjectsView интерфейсийг хэрэгжүүлсэн үзүүлбэрийг л зохиох хэрэгтэй. Харин IProjectsPresenter, IProjectsModel интерфейсүүдийг өөрчлөлтгүйгээр дахин ашиглаж болно.        

Хичээлийг сайн судлаад ерөнхий санааг сайн ойлгож аваарай.

Мэдээлэл таалагдсан бол найзуудтайгаа хуваалцаарай.

  Нээгдсэн тоо: 384 Бүртгүүлэх

Төрөл бүрийн класс, структуруудад хуурамч нэрийг /төлөөлөх нэр/ өгөөд дараа нь програмд төрлийн нэрийн оронд төлөөлөх нэрийг ашиглаж болно. Жишээ нь консолд мөр гаргах Console.WriteLine() аргын Console класст төлөөлөх нэрийг

using printer = System.Console;

printer.WriteLine("Монгол улс");
printer.WriteLine("Улаанбаатар хот");

өгч болно.

  Нээгдсэн тоо: 2000 Төлбөртэй

Програмын ажиллагаанд өгөгдөлтэй ажиллах асуудал том байр суурийг эзэлдэг. Тэр дундаа өгөгдлийн сантай харилцан ажиллах нь ихээр тохиолдоно. Иймээс хичээлээр бид өгөгдлийн сантай ажиллах Entity Framework технологийн талаар авч үзэх юм. Сэдэв их өргөн агуулгатай тул хэдэн хичээлээр дамжин авч үзэх болно. Хичээлийн материалыг амархан ойлгохын тулд та

  • Холбоот өгөгдлийн сангийн суурь ойлголттой байх. Сайтын Sql хэл хэсгийн хичээлүүдээс энэ талаар судлан ойлгоорой.
  • .NET фреймворкийн олонлог буюу IEnumerable интерфейсийг ойлгон мэдсэн байх. Энэ талаар Олонлог /Sets/ хичээлээс үзэээрэй. Сэдвийг олон хичээлд хөндөж байсан болохоор та олонлогийг ойлгосон байх гэж бодож байгаа.  
  • Лямбда илэрхийлэл. Энд сэдвээр Лямбда илэрхийлэл гэсэн тусдаа хичээл байгаа.   
  • Илэрхийллийн мод ухагдхууны суурь ойлголтыг Илэрхийллийн мод хичээлээс ойлгосон байх.
  • Өгөгдлийн эх үүсвэр олонлог, массив, өгөгдлийн сан гэдгээс үл хамааран өгөгдөлтэй ажилладаг LINQ технологийн суурийг заавал мэдэж байх.

шаардлагатай. Дээрх ухагдхуунуудыг мэдэж ойлгосон байхад Entity Framework технологийг ойлгоход асуудал үүсэхгүй.

  Нээгдсэн тоо: 504 Нийтийн

Хадгалагч (Memento) хэв обьектын дотоод төлвийг түүний гадна гаргаж дараа нь хайрцаглалтын зарчмыг зөрчихгүйгээр обьектыг сэргээх боломжийг олгодог.

Хэвийг хаана ашиглах

  • Дараа нь сэргээх боломжтойгоор обьектын төлвийг хадгалах хэрэгтэй бол
  • Обьектын төлвийн хадгалалт хайрцаглалтын зарчмыг зөрчихгүйгээр хийгдэх хэрэгтэй бол

  Нээгдсэн тоо: 533 Төлбөртэй

switch/case бүтэц илэрхийллийн утгыг утгуудын багцтай харьцуулан утга тохирсон бол тодорхой кодийг биелүүлдэг.

switch бүтцийн албан ёсны тодорхойлолт

switch (илэрхийлэл)
{
    case утга1:
        илэрхийллийн утга утга1-тэй тохирох үед ажиллах код
        break;
    case утга2:
        илэрхийллийн утга утга2-тэй тохирох үед ажиллах код
        break;
    //.............
    case утгаN:
        илэрхийллийн утга утгаN-тэй тохирох үед ажиллах код
        break;
    default:
        илэрхийллийн утга утгуудын багцад байхгүй үед ажиллах код
        break;
}

switch түлхүүр үгийн араас хаалтад харьцуулах илэрхийллийг өгнө.

Үйл явдал /event/ тодорхой үйлдэл хийгдсэн талаар системд мэдэгддэг. Хэрвээ бид энэхүү үйлдлийг ажиглах хэрэгтэй бол яг энд…

Нээгдсэн тоо : 290

 

Манай төсөл олон хуудсуудтай болон тэдгээрийн хооронд динамикаар шилжилт хийж байгаа ч тухайн үед шилжилт хийгдсэн хуудаст тохирох…

Нээгдсэн тоо : 369

 

Зочин (Visitor) паттерн классуудыг өөрчлөхгүйгээр тэдгээрийн обьектуудын үйлдлийг тодорхойлох боломжийг олгоно. Зочин хэвийг ашиглахдаа классуудын хоёр ангилалыг тодорхойлно.…

Нээгдсэн тоо : 336

 

Лямбда-илэрхийлэл нь нэргүй аргын хураангуй бичилтийг илэрхийлнэ. Лямбда-илэрхийлэл утга буцаадаг, буцаасан утгыг өөр аргын…

Нээгдсэн тоо : 431

 

Кодийн сайжруулалт /рефакторинг/ хичээлээр програмийн кодоо react -ийн зарчимд нийцүүлэн компонентод салгасан.…

Нээгдсэн тоо : 481

 

Хадгалагч (Memento) хэв обьектын дотоод төлвийг түүний гадна гаргаж дараа нь хайрцаглалтын зарчмыг зөрчихгүйгээр обьектыг сэргээх боломжийг олгодог.

Нээгдсэн тоо : 504

 

Делегаттай нэргүй арга нягт холбоотой. Нэргүй аргуудыг делегатийн хувийг үүсгэхэд ашигладаг.
Нэргүй аргуудын тодорхойлолт delegate түлхүүр үгээр…

Нээгдсэн тоо : 597

 

Математикт харилцан урвуу тоонууд гэж бий. Ямар нэгэн тооны урвуу тоог олохдоо тухайн тоог сөрөг нэг зэрэг дэвшүүлээд…

Нээгдсэн тоо : 689

 

Төсөлд react-router-dom санг оруулан чиглүүлэгчдийг бүртгүүлэн тохируулсан Санг суулган тохируулах хичээлээр бид хуудас…

Нээгдсэн тоо : 723

 
Энэ долоо хоногт

Хоёр тойрог гадна талаараа шүргэлцсэн. Нэг тойргийн шүргэгч нь нөгөө тойргийнхоо төвийг дайран гарсан. Шүргэлтийн цэгээс хоёрдахь тойргийн төв хүртэлх зай нь энэ тойргийн радиусаас 3 дахин урт. Нэгдүгээр тойргийн урт хоёрдугаар тойргийн уртаас хэд дахин их вэ?

Нээгдсэн тоо : 1553

 

тэгшитгэлийг бод.

Нээгдсэн тоо : 2013

 

бол илэрхийллийн утгыг ол.

Нээгдсэн тоо : 990