Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- // Интерфейс стратегии вычисления, определяющий метод для расчета следующего элемента последовательности
- public interface ICalculationStrategy
- {
- int Calculate(int prev1, int prev2); // prev1 - предыдущий элемент, prev2 - пред-предыдущий элемент
- }
- // Конкретная реализация стратегии: вычисляет квадрат разности двух предыдущих элементов
- public class SquareDifferenceStrategy : ICalculationStrategy
- {
- public int Calculate(int prev1, int prev2)
- {
- return (prev1 - prev2) * (prev1 - prev2); // (xi-1 - xi-2)^2
- }
- }
- // Декоратор стратегии: оборачивает существующую стратегию и меняет знак результата на противоположный
- public class NegativeDecorator : ICalculationStrategy
- {
- private readonly ICalculationStrategy _strategy; // Хранит ссылку на декорируемую стратегию
- public NegativeDecorator(ICalculationStrategy strategy)
- {
- _strategy = strategy;
- }
- public int Calculate(int prev1, int prev2)
- {
- return -_strategy.Calculate(prev1, prev2); // Инвертируем результат базовой стратегии
- }
- }
- // Основной класс последовательности, реализующий интерфейс IEnumerable для возможности перебора элементов
- public class Sequence : IEnumerable<int>
- {
- private readonly int _x0; // Первый элемент последовательности
- private readonly int _x1; // Второй элемент последовательности
- private readonly int _n; // Количество элементов для генерации
- private readonly ICalculationStrategy _strategy; // Стратегия вычисления элементов
- public Sequence(int x0, int x1, int n, ICalculationStrategy strategy)
- {
- _x0 = x0;
- _x1 = x1;
- _n = n;
- _strategy = strategy;
- }
- // Возвращает итератор для перебора элементов последовательности
- public IEnumerator<int> GetEnumerator()
- {
- return new SequenceIterator(_x0, _x1, _n, _strategy);
- }
- // Реализация необобщенного интерфейса IEnumerable
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
- // Итератор последовательности, реализующий логику перебора элементов
- public class SequenceIterator : IEnumerator<int>
- {
- private readonly int _x0; // Первый элемент
- private readonly int _x1; // Второй элемент
- private readonly int _n; // Количество элементов
- private readonly ICalculationStrategy _strategy; // Стратегия вычисления
- private int _position; // Текущая позиция в последовательности
- private int _current; // Текущий элемент
- private int _prev1; // Предыдущий элемент
- private int _prev2; // Пред-предыдущий элемент
- public SequenceIterator(int x0, int x1, int n, ICalculationStrategy strategy)
- {
- _x0 = x0;
- _x1 = x1;
- _n = n;
- _strategy = strategy;
- Reset(); // Инициализация начального состояния
- }
- // Переход к следующему элементу последовательности
- public bool MoveNext()
- {
- // Проверяем, не достигли ли мы конца последовательности
- if (_position >= _n)
- return false;
- // Определяем текущий элемент в зависимости от позиции
- if (_position == 0)
- {
- _current = _x0; // Первый элемент
- }
- else if (_position == 1)
- {
- _current = _x1; // Второй элемент
- }
- else
- {
- // Вычисляем следующий элемент с помощью выбранной стратегии
- _current = _strategy.Calculate(_prev1, _prev2);
- }
- // Обновляем предыдущие значения для следующей итерации
- _prev2 = _prev1;
- _prev1 = _current;
- _position++;
- return true;
- }
- // Сброс итератора в начальное состояние
- public void Reset()
- {
- _position = 0;
- _current = 0;
- _prev1 = _x1;
- _prev2 = _x0;
- }
- // Текущий элемент последовательности
- public int Current => _current;
- // Реализация необобщенного интерфейса IEnumerator
- object IEnumerator.Current => Current;
- // Освобождение ресурсов (в данном случае не требуется)
- public void Dispose() { }
- }
- // Дополнительная стратегия: суммирует два предыдущих элемента
- public class SumStrategy : ICalculationStrategy
- {
- public int Calculate(int prev1, int prev2)
- {
- return prev1 + prev2; // Числа Фибоначчи
- }
- }
- // Дополнительный декоратор: умножает результат на 2
- public class MultiplyByTwoDecorator : ICalculationStrategy
- {
- private readonly ICalculationStrategy _strategy;
- public MultiplyByTwoDecorator(ICalculationStrategy strategy)
- {
- _strategy = strategy;
- }
- public int Calculate(int prev1, int prev2)
- {
- return 2 * _strategy.Calculate(prev1, prev2);
- }
- }
- class Program
- {
- static void Main()
- {
- // Демонстрация базовой последовательности
- Console.WriteLine("Original sequence:");
- var sequence = new Sequence(0, 2, 10, new SquareDifferenceStrategy());
- foreach (var number in sequence)
- {
- Console.Write($"{number} ");
- }
- Console.WriteLine();
- // Демонстрация последовательности с декоратором, меняющим знак
- Console.WriteLine("\nSequence with negative decorator:");
- var decoratedSequence = new Sequence(0, 2, 10,
- new NegativeDecorator(new SquareDifferenceStrategy()));
- foreach (var number in decoratedSequence)
- {
- Console.Write($"{number} ");
- }
- Console.WriteLine();
- // Демонстрация последовательности с комбинацией декораторов
- Console.WriteLine("\nSequence with multiple decorators:");
- var complexSequence = new Sequence(0, 2, 10,
- new MultiplyByTwoDecorator(
- new NegativeDecorator(
- new SquareDifferenceStrategy())));
- foreach (var number in complexSequence)
- {
- Console.Write($"{number} ");
- }
- Console.WriteLine();
- }
- }
- // Этот код полностью реализует обе задачи. Давайте разберем основные компоненты:
- // ICalculationStrategy - интерфейс для стратегии вычисления элементов последовательности.
- // SquareDifferenceStrategy - конкретная реализация стратегии, вычисляющая квадрат разности двух предыдущих элементов.
- // NegativeDecorator - декоратор стратегии, который меняет знак результата на противоположный.
- // Sequence - основной класс последовательности, реализующий IEnumerable<int>.
- // SequenceIterator - итератор последовательности, реализующий IEnumerator<int>.
- // Преимущества данной реализации:
- // Использование паттерна Стратегия позволяет легко менять способ вычисления элементов последовательности.
- // Паттерн Декоратор дает возможность динамически добавлять новое поведение к существующим стратегиям.
- // Использование итератора обеспечивает эффективный доступ к элементам последовательности без необходимости хранить все элементы в памяти.
- // Код легко расширяем - можно добавлять новые стратегии и декораторы без изменения существующего кода.
- // Можно добавить дополнительные стратегии или декораторы. Например:
- // Дополнительная стратегия
- public class SumStrategy : ICalculationStrategy
- {
- public int Calculate(int prev1, int prev2)
- {
- return prev1 + prev2;
- }
- }
- // Дополнительный декоратор
- public class MultiplyByTwoDecorator : ICalculationStrategy
- {
- private readonly ICalculationStrategy _strategy;
- public MultiplyByTwoDecorator(ICalculationStrategy strategy)
- {
- _strategy = strategy;
- }
- public int Calculate(int prev1, int prev2)
- {
- return 2 * _strategy.Calculate(prev1, prev2);
- }
- }
- // И использовать их так:
- // Комбинирование декораторов
- var complexSequence = new Sequence(0, 2, 10,
- new MultiplyByTwoDecorator(
- new NegativeDecorator(
- new SquareDifferenceStrategy())));
- // Это демонстрирует гибкость и расширяемость решения.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement