Главная страница
Навигация по странице:

  • Оборудование

  • Содержание работы: Задание 1.

  • Раьаатата. Использование порождающих шаблонов


    Скачать 90.2 Kb.
    НазваниеИспользование порождающих шаблонов
    АнкорРаьаатата
    Дата12.11.2021
    Размер90.2 Kb.
    Формат файлаdocx
    Имя файла23._15._.docx
    ТипПрактическая работа
    #270064

    ПРАКТИЧЕСКАЯ РАБОТА № 15

    Тема: Использование порождающих шаблонов

    Цель работы: изучение порождающих шаблонов и умение их использовать при написании программ

    Оборудование: ПК, программное обеспечение – Visual Studio, инструкции по выполнению работы.

    Справочный материал:

    Паттерн Builder принадлежит к порождающим паттернам и используется для порождения объектов. Необходимость использования паттерна Builder в программе возникает в случаях, когда нужно добавлять новые возможности без существенного изменения кода. Под возможностями понимаются дополнительные преобразования, которые генерируют конечный продукт (объект). В паттерне Builder представление объекта отделяется от его конструирования (построения). При этом, для конкретной конструкции получаются разные представления.

    Паттерн Singleton (одиночка, одиночка) относится к порождающим паттернам. Паттерн Singleton предназначен для создания заданного количества экземпляров (объектов) класса. Чаще всего паттерн Singleton используется для создания гарантированно одного экземпляра класса. Паттерн Singleton важен в случаях, когда для некоторых классов нужно чтобы существовало определенное количество экземпляров, например один экземпляр.

    Содержание работы:

    Задание 1. Реализация паттерна Builder на языке C#, структура которого изображена на рисунке



    Объявляются следующие классы:

    • Product — класс, который является продуктом (результатом работы паттерна). Это произвольный класс. В демонстрационных целях в этом классе объявляется три целочисленных переменных, каждая из которых условно считается частью продукта;

    • Builder — абстрактный класс, который служит интерфейсом между распорядителем (Director) и классом, создающим конкретный объект (ConcreteBuilder);

    • ConcreteBuilder — класс, который строит конкретный объект;

    • Director — класс, являющийся распорядителем. Этот класс строит (конфигурирует) объект класса ConcreteBuilder для использования его клиентом.

    • Program — класс, который выступает в роли клиента. В этом классе реализуется функция main(), в которой продемонстрирована работа клиента. Клиент обращается к распорядителю (Director) для того, чтобы тот построил объект класса ConcreteBuilder. Затем построенный объект возвращается клиенту в методе GetResult().

    Текст программы:

    using System;

    namespace ConsoleApp8 {

    // Паттерн Builder. Пример реализации на C#

    // 1. Класс, служащий продуктом. Содержит три части

    class Product {

    // Внутренние переменные

    private int part1, part2, part3;

    // Конструктор

    public Product() {

    part1 = 0; part2 = 0; part3 = 0; }

    // Методы доступа

    public int GetPart1() { return part1; }

    public int GetPart2() { return part2; }

    public int GetPart3() { return part3; }

    public void SetPart1(int part1) {

    this.part1 = part1; }

    public void SetPart2(int part2) {

    this.part2 = part2; }

    public void SetPart3(int part3) {

    this.part3 = part3; } }

    // 2. Класс, который служит интерфейсом между распорядителем и конкретным строителем

    abstract class Builder {

    // Метод, создающий продукт

    public abstract void CreateProduct();

    // Методы, которые строят части продукта

    public abstract void BuildPart1(int part);

    public abstract void BuildPart2(int part);

    public abstract void BuildPart3(int part);

    // Метод, возвращающий продукт клиенту

    public abstract Product GetProduct(); }

    // Класс - конкретный строитель, наследует абстрактный класс Builder

    class ConcreteBuilder: Builder {

    // Внутренняя переменная - ссылка на продукт

    private Product currentBuilder;

    // Методы, которые объявляются в абстрактном классе Builder, их нужно реализовывать

    public override void CreateProduct() {

    currentBuilder = new Product(); }

    public override void BuildPart1(int part) {

    currentBuilder.SetPart1(part); }

    public override void BuildPart2(int part) {

    currentBuilder.SetPart2(part); }

    public override void BuildPart3(int part) {

    currentBuilder.SetPart3(part); }

    public override Product GetProduct() {

    return currentBuilder; } }

    // Класс-распорядитель, содержит методы построения объекта Product из частей

    class Director {

    // Ссылка на Builder

    private Builder builder;

    // Конструктор - инициализируется экземпляром Builder

    public Director(Builder _builder) {

    builder = _builder; }

    // Метод, который строит объект класса Product из частей

    public void Construct() {

    // Построить экземпляр класса Product

    builder.CreateProduct();

    builder.BuildPart1(10);

    builder.BuildPart2(20);

    builder.BuildPart3(30); } }

    // Класс, содержащий функцию клиента

    class Program {

    static void Main(string[] args) {

    // Это клиент

    // 1. Объявить ссылку на продукт

    Product product;

    // 2. Создать конкретного строителя

    Builder B = new ConcreteBuilder();

    // 3. Создать распорядителя и сконфигурировать его строителем

    Director D = new Director(B);

    // 4. Вызвать методы построения продукта - доверить это распорядителю

    D.Construct();

    // 5. Вернуть построенный продукт клиенту

    product = B.GetProduct();

    // 6. Проверить, как построен продукт

    Console.WriteLine("product.part1 = {0}", product.GetPart1());

    Console.WriteLine("product.part2 = {0}", product.GetPart2());

    Console.WriteLine("product.part3 = {0}", product.GetPart3());

    } } }

    Результат работы программы – прислать скриншот

    Задание 2. Написать программу на C#, реализующую паттерн Singleton

    using System;

    using static System.Console;

    namespace ConsoleApp9{

    // Реализация паттерна Singleton - Одиночка

    class Singleton {

    // Статический метод, который возвращает экземпляр класса Singleton.

    // Данный метод может быть заменен соответствующим свойством.

    public static Singleton Instance() {

    if (_instance == null) {

    _instance = new Singleton();

    return _instance; }

    else {

    return null; } }

    // Конструктор класса, объявленный как protected, для того чтобы:

    // - запретить создание экземпляра класса оператором new;

    // - можно было наследовать данный класс.

    protected Singleton() { }

    // Статическая внутренняя переменная, которая хранит экземпляр класса.

    // К этой переменной есть доступ из методов данного класса.

    // Из методов других классов доступа к переменной нет.

    private static Singleton _instance = null;

    // -------------------------------------------------

    // Другие внутренние поля класса

    private int d;

    // Свойство для доступа к полю d

    public int D {

    get { return d; }

    set { d = value; } }

    // Метод, который выводит значение поля d

    public void Print(string text) {

    WriteLine("------------------");

    WriteLine("{0}. d = {1}", text, d); } }

    // Класс, выступающий клиентом

    class Program {

    static void Main(string[] args) {

    // Это есть код клиента.

    // Создать единственный экземпляр класса Singleton

    Singleton obj1 = Singleton.Instance();

    // Проверить obj1 на равенство null

    if (obj1 != null) {

    obj1.D = 25;

    obj1.Print("obj1"); }

    else

    WriteLine("obj1 == null");

    // Попытка создать другой экземпляр класса

    Singleton obj2 = Singleton.Instance();

    if (obj2 != null) {

    obj2.D = 77;

    obj2.Print("obj2"); }

    else

    WriteLine("obj2 == null"); } } }

    Результат выполнения программы: прислать скриншот
    Задание 3. Написать программу на C#, реализующую паттерн AbstractFactory

    using System;

    namespace RefactoringGuru.DesignPatterns.AbstractFactory.Conceptual {

    // Интерфейс Абстрактной Фабрики объявляет набор методов, которые возвращают

    различные абстрактные продукты. Эти продукты называются семейством и

    связаны темой или концепцией высокого уровня. Продукты одного семейства

    обычно могут взаимодействовать между собой. Семейство продуктов может

    // иметь несколько вариаций, но продукты одной вариации несовместимы с

    продуктами другой.

    public interface IAbstractFactory {

    IAbstractProductA CreateProductA();

    IAbstractProductB CreateProductB(); }

    // Конкретная Фабрика производит семейство продуктов одной вариации. Фабрика

    гарантирует совместимость полученных продуктов. Обратите внимание, что

    сигнатуры методов Конкретной Фабрики возвращают абстрактный продукт, в то

    время как внутри метода создается экземпляр конкретного продукта.

    class ConcreteFactory1 : IAbstractFactory {

    public IAbstractProductA CreateProductA() {

    return new ConcreteProductA1(); }

    public IAbstractProductB CreateProductB() {

    return new ConcreteProductB1(); } }

    // Каждая Конкретная Фабрика имеет соответствующую вариацию продукта.

    class ConcreteFactory2 : IAbstractFactory {

    public IAbstractProductA CreateProductA() {

    return new ConcreteProductA2(); }

    public IAbstractProductB CreateProductB() {

    return new ConcreteProductB2(); } }

    // Каждый отдельный продукт семейства продуктов должен иметь базовый

    интерфейс. Все вариации продукта должны реализовывать этот интерфейс.

    public interface IAbstractProductA {

    string UsefulFunctionA(); }

    // Конкретные продукты создаются соответствующими Конкретными Фабриками.

    class ConcreteProductA1 : IAbstractProductA {

    public string UsefulFunctionA() {

    return "The result of the product A1."; } }

    class ConcreteProductA2 : IAbstractProductA {

    public string UsefulFunctionA() {

    return "The result of the product A2."; } }

    // Базовый интерфейс другого продукта. Все продукты могут взаимодействовать

    друг с другом, но правильное взаимодействие возможно только между

    продуктами одной и той же конкретной вариации.

    public interface IAbstractProductB {

    // Продукт B способен работать самостоятельно...

    string UsefulFunctionB();

    // ...а также взаимодействовать с Продуктами А той же вариации.

    Абстрактная Фабрика гарантирует, что все продукты, которые она

    создает, имеют одинаковую вариацию и, следовательно, совместимы.

    string AnotherUsefulFunctionB(IAbstractProductA collaborator); }

    // Конкретные Продукты создаются соответствующими Конкретными Фабриками.

    class ConcreteProductB1 : IAbstractProductB {

    public string UsefulFunctionB() {

    return "The result of the product B1."; }

    // Продукт B1 может корректно работать только с Продуктом A1. Тем не

    менее, он принимает любой экземпляр Абстрактного Продукта А в

    качестве аргумента.

    public string AnotherUsefulFunctionB(IAbstractProductA collaborator) {

    var result = collaborator.UsefulFunctionA();
    return $"The result of the B1 collaborating with the ({result})"; } }

    class ConcreteProductB2 : IAbstractProductB {

    public string UsefulFunctionB() {

    return "The result of the product B2."; }

    // Продукт B2 может корректно работать только с Продуктом A2. Тем не

    менее, он принимает любой экземпляр Абстрактного Продукта А в качестве

    аргумента.

    public string AnotherUsefulFunctionB(IAbstractProductA collaborator) {

    var result = collaborator.UsefulFunctionA();

    return $"The result of the B2 collaborating with the ({result})"; } }

    // Клиентский код работает с фабриками и продуктами только через абстрактные

    типы: Абстрактная Фабрика и Абстрактный Продукт. Это позволяет передавать

    любой подкласс фабрики или продукта клиентскому коду, не нарушая его.

    class Client {

    public void Main() {

    // Клиентский код может работать с любым конкретным классом фабрики.

    Console.WriteLine("Client: Testing client code with the first factory type...");

    ClientMethod(new ConcreteFactory1());

    Console.WriteLine();

    Console.WriteLine("Client: Testing the same client code with the second factory type...");

    ClientMethod(new ConcreteFactory2()); }

    public void ClientMethod(IAbstractFactory factory) {

    var productA = factory.CreateProductA();

    var productB = factory.CreateProductB();

    Console.WriteLine(productB.UsefulFunctionB());

    Console.WriteLine(productB.AnotherUsefulFunctionB(productA)); } }

    class Program {

    static void Main(string[] args) {

    new Client().Main(); } } }

    Результат выполнения программы: прислать скриншот
    Задание 4. Написать программу на C#, реализующую паттерн FactoryMethod

    using System;

    namespace RefactoringGuru.DesignPatterns.FactoryMethod.Conceptual{

    // Класс Создатель объявляет фабричный метод, который должен возвращать

    объект класса Продукт. Подклассы Создателя обычно предоставляют

    реализацию этого метода.

    abstract class Creator {

    // Обратите внимание, что Создатель может также обеспечить реализацию

    фабричного метода по умолчанию.

    public abstract IProduct FactoryMethod();

    // Также заметьте, что, несмотря на название, основная обязанность

    Создателя не заключается в создании продуктов. Обычно он содержит

    некоторую базовую бизнес-логику, которая основана на объектах

    Продуктов, возвращаемых фабричным методом. Подклассы могут косвенно

    изменять эту бизнес-логику, переопределяя фабричный метод и возвращая

    из него другой тип продукта.

    public string SomeOperation() {

    // Вызываем фабричный метод, чтобы получить объект-продукт.

    var product = FactoryMethod();

    // Далее, работаем с этим продуктом.

    var result = "Creator: The same creator's code has just worked with "

    + product.Operation();

    return result; } }

    // Конкретные Создатели переопределяют фабричный метод для того, чтобы

    // изменить тип результирующего продукта.

    class ConcreteCreator1 : Creator {

    // Обратите внимание, что сигнатура метода по-прежнему использует тип

    абстрактного продукта, хотя фактически из метода возвращается

    конкретный продукт. Таким образом, Создатель может оставаться

    независимым от конкретных классов продуктов.

    public override IProduct FactoryMethod() {

    return new ConcreteProduct1(); } }

    class ConcreteCreator2 : Creator {

    public override IProduct FactoryMethod() {

    return new ConcreteProduct2(); } }

    // Интерфейс Продукта объявляет операции, которые должны выполнять все

    конкретные продукты.

    public interface IProduct {

    string Operation(); }

    // Конкретные Продукты предоставляют различные реализации интерфейса

    Продукта.

    class ConcreteProduct1 : IProduct {

    public string Operation() {

    return "{Result of ConcreteProduct1}"; } }

    class ConcreteProduct2 : IProduct {

    public string Operation() {

    return "{Result of ConcreteProduct2}"; } }

    class Client {

    public void Main() {

    Console.WriteLine("App: Launched with the ConcreteCreator1.");

    ClientCode(new ConcreteCreator1());

    Console.WriteLine("");

    Console.WriteLine("App: Launched with the ConcreteCreator2.");

    ClientCode(new ConcreteCreator2()); }

    // Клиентский код работает с экземпляром конкретного создателя, хотя и

    через его базовый интерфейс. Пока клиент продолжает работать с

    создателем через базовый интерфейс, вы можете передать ему любой

    подкласс создателя.

    public void ClientCode(Creator creator) {

    Console.WriteLine("Client: I'm not aware of the creator's class," +

    "but it still works.\n" + creator.SomeOperation()); } }

    class Program {

    static void Main(string[] args) {

    new Client().Main(); } } }

    Результат выполнения программы: прислать скриншот
    Задание 5. Написать программу на C#, реализующую паттерн Prototype

    using System;

    namespace RefactoringGuru.DesignPatterns.Prototype.Conceptual{

    public class Person {

    public int Age;

    public DateTime BirthDate;

    public string Name;

    public IdInfo IdInfo;

    public Person ShallowCopy() {

    return (Person) this.MemberwiseClone(); }

    public Person DeepCopy() {

    Person clone = (Person) this.MemberwiseClone();

    clone.IdInfo = new IdInfo(IdInfo.IdNumber);

    clone.Name = String.Copy(Name);

    return clone; } }

    public class IdInfo {

    public int IdNumber;

    public IdInfo(int idNumber) {

    this.IdNumber = idNumber; } }

    class Program {

    static void Main(string[] args) {

    Person p1 = new Person();

    p1.Age = 21;

    p1.BirthDate = Convert.ToDateTime("2000-01-01");

    p1.Name = "Иван Петров";

    p1.IdInfo = new IdInfo(36);

    // Выполнить поверхностное копирование p1 и присвоить её p2.

    Person p2 = p1.ShallowCopy();

    // Сделать глубокую копию p1 и присвоить её p3.

    Person p3 = p1.DeepCopy();

    // Вывести значения p1, p2 и p3.

    Console.WriteLine("Original values of p1, p2, p3:");

    Console.WriteLine(" p1 instance values: ");

    DisplayValues(p1);

    Console.WriteLine(" p2 instance values:");

    DisplayValues(p2);

    Console.WriteLine(" p3 instance values:");

    DisplayValues(p3);

    // Изменить значение свойств p1 и отобразить значения p1, p2 и p3.

    p1.Age = 30;

    p1.BirthDate = Convert.ToDateTime("1991-11-09");

    p1.Name = "Илья Сергеев";

    p1.IdInfo.IdNumber = 78;

    Console.WriteLine("\nValues of p1, p2 and p3 after changes to p1:");

    Console.WriteLine(" p1 instance values: ");

    DisplayValues(p1);

    Console.WriteLine(" p2 instance values (reference values have changed):");

    DisplayValues(p2);

    Console.WriteLine(" p3 instance values (everything was kept the same):");

    DisplayValues(p3); }

    public static void DisplayValues(Person p) {

    Console.WriteLine(" Name: {0:s}, Age: {1:d}, BirthDate: {2:MM/dd/yy}",

    p.Name, p.Age, p.BirthDate);

    Console.WriteLine(" ID#: {0:d}", p.IdInfo.IdNumber); } }}
    Результат выполнения программы: прислать скриншот
    Задание 6. Используя средства языка C# и возможности паттерна Builder разработать программу для генерирования объектов, являющихся массивами случайных чисел. Массивы случайных чисел представлены следующими классами:

    • ArrayRandomInt — массив из целых чисел. Для данного массива указывается диапазон;

    • ArrayRandomChar — массив случайных символов от ‘A’ до ‘Z’.


    Задание 7. Используя средства языка C# и паттерна FactoryMethod разработать программу для работы  менеджера по найму. Невозможно одному человеку провести собеседования со всеми кандидатами на все вакансии. В зависимости от вакансии он должен распределить этапы собеседования между разными людьми.


    написать администратору сайта