Главная страница

Рабочая программа по дисциплине Цели и задачи освоения дисциплины Дисциплина Объектноориентированный анализ и программирование


Скачать 339.98 Kb.
НазваниеРабочая программа по дисциплине Цели и задачи освоения дисциплины Дисциплина Объектноориентированный анализ и программирование
Дата12.10.2022
Размер339.98 Kb.
Формат файлаdocx
Имя файлаobektno-orientirovannyj_analiz_i_programmirovanie_161021.docx
ТипРабочая программа
#730141
страница11 из 14
1   ...   6   7   8   9   10   11   12   13   14
private Finder SlowFinder;

private int.. data;

FastFinder(int size, Finder SlowFinder) { data = new int[size;; this.s_owFinder = SlowFinder;

public int getData(int key) {

if(key >= 0 && key < data.length)

return data[key];

else

return SlowFinder.getData(key);

}

public void add(int key, int data) {

if (key >= 0 && key < this . data . .length)

this.data.key. = data;

else

SlowFinder.add(key, data);

public class Client {

public static void main(String args) { Finder ff new FastFinder(1000, new SiowFinder()); ff.add(10, 1); ff.add(100, 2); ff.adddOOO, 3); ff.adddOOOO, 4) ;

for(int i = 10; i <= 10000; i = i * 10)

System.out.printin(ff.getData(i) ) ;

System.out.flush() ;

В данном примере классы SiowFinder и FastFinder реализуют интерфейс Finder. Первый класс использует для хранения данных коллекцию HashMap, что позволяет хранить пары ключ-значение для широкого диапазона ключей. Класс FastFinder использует для хранения пар линейный массив и является «точкой входа» в цепочку. Операция доступа к элементам HashMap более трудоемкая, чем операция обращения к элементу массива, поэтому при условии, что большая часть запросов будет обрабатываться экземпляром класса FastFinder, предлагаемая цепочка позволит значительно сократить время, затрачиваемое в среднем на поиск одного значения.

Важными преимуществами «цепочки ответственности» являются, во-первых, ослабление связности (клиентскому объекту нет нужды знать что-либо об объектах, обслуживающих его запрос; достаточно только иметь ссылку на точку входа), а во-вторых, дополнительная гибкость при распределении обязанностей (цепочка классов-обработчиков может быть модифицирована с минимальными затратами). Однако необходимо помнить, что само по себе наличие цепочки не гарантирует обработку запроса (запрос может пройти через всю цепочку объектов и при этом не быть обработанным).

Итератор

Практически все современные реализации коллекций на большинстве языков программирования позволяют работать с итераторами. Итератор — это способ последовательного (в общем случае) перебора элементов. Например, стандартная реализация итератора для вектора элементов позволяет обращаться к первому, последнему, следующему и предыдущему элементам. Осуществляется это благодаря использованию одноименного шаблона.

«Итератор» — поведенческий шаблон, предоставляющий доступ ко всем элементам составного объекта, не раскрывая его внутреннего представления. Чаще всего «итератор» применяется, когда необходимо организовать несколько активных обходов одного и того же объекта или требуется поддержка единообразного интерфейса с целью взаимодействия с составными структурами разной природы.

Пример использования шаблона представлен ниже.

import java.util.Vector;

public class Vertex implements Comparable {

private int key;

private int data;

Vertex(int key, int data) {
this.key = key;


this.setData(data) ;

public int getDataO { return data;

public void setData(int data) {
this.data = data;


public int compareTo(Vertex argO) { if(this.key < argO.key)

return -1;

if(this.key > argO.key) return 1;

return 0;

public abstract class Enumerator { protected int position = 0; protected Heap heap;

Enumerator(Heap heap) { this.heap = heap;

public Vertex current() {

return heap.getVertex(position);

public void first() { position = 0;

public void last() {

position - heap.size() - 1;

public boolean isFirstO {

return position == 0 ? true : false;

public boolean isEnd() {

return position < heap.size() ? false : true; }

}

public class Heapiterator extends Enumerator {

Heapiterator(Heap heap) { super(heap);

}

public void leftchild() { position = ((position + 1) << 1) - 1;

}

public void rightchild() { position = (position + 1) << 1; } }

public interface Iteration {

public Enumerator createlterator() ; }

public class Heap implements Iteration { private Vector data;

public int size() {

return data.size();

data new Vector();

}

public void add(Vertex argO) {

//В этом методе выполняется добавление узла к куче }

public void remove(int key) {

//В этом методе выполняется удаление узла из кучи }

public void clear() {

//В этом методе выполняется очистка кучи

}

private void upheap(int position) {

//В этом методе осуществляется подъем элемента вверх }

private void downheap(int position) {

//В этом методе осущетсвпяется спуск элемента вниз

protected Vertex getVertex(int position) { if (position < data.sizeO)

return data.elementAt(position);

else

return null;

public Enumerator createlterator() { return new Heapiterator(this); }

В предлагаемом примере частично реализован итератор для структуры данных «куча». Отличительной особенностью этой разновидности бинарного дерева является то, что значение элемента-предка всегда не меньше, чем значение его элементов-потомков. Класс Heap является абстракцией «кучи». Для хранения элементов используется вектор. Heap реализует интерфейс Iteration и, соответственно, декларируемый в нем метод getlteratorQ. Класс Hcapltcrator расширяет абстрактный класс Enumerator, в котором описаны методы перемещения по вершинам дерева.

Хранитель

Простым, но чрезвычайно полезным поведенческим шаблоном является «хранитель». Назначение этой структуры — фиксация и вынесение за пределы объекта его внутреннего состояния с целью его дальнейшего восстановления. «Хранитель» необходим для мгновенного создания «снимка» объекта в тех случаях, когда прямое получение такого «снимка» раскрывает детали реализации объекта и нарушает принцип инкапсуляции. Иными словами, «хранитель» помогает выдерживать границы инкапсуляции и упростить структуру класса-хозяина за счет того, что ему не приходится хранить внутри себя резервные внутренние состояния.

Пример «хранителя» представлен ниже.

import java.util.Random

public class Originator { private int .. data;

Originator(int size) { data = new int[size]; for(int i = 0; i < size; i++) data[i] = i + 1;

public inti] getData() {

return data.c.one();

int tmp = data.posl.;

data.posl ( = data[pos2];

data.pos2. = tmp;

public void permutation() {

Random rnd new Random();

for(int i = 0; i < 3 * data.length; i++) { int posl = rnd.nextint(data._ength); int pos2 = rnd.nextlnt(data._ength); swap(posl, pos2);

public Memento getStateO {

return new Memento(data.clone());

public void setstate(Memento state) { data = state.restore();

public class Memento {

private int .. data;




Memento(int

argO) {



data = argO;

public int[J restore() {

return data.clone();

В примере класс Originator предоставляет метод для генерации перестановки чисел. Внутреннее состояние класса (текущая перестановка) может быть сохранено с помощью метода getStateO как экземпляр класса Memento. Если в процессе работы с классом Originator возникнет необходимость, то «снимок» может быть использован для восстановления «удачной» перестановки ( метод setStateQ).

Хотя использование «хранителя» чревато появлением значительных издержек при работе с программной системой, его использование просто необходимо во многих случаях (например, для создания контрольных точек восстановления системы).

Шаблонный метод

Одним из фундаментальных приемов повторного использования кода является «шаблонный метод» — поведенческий шаблон, который определяет основу алгоритма и позволяет подклассам переопределять некоторые шаги алгоритма. Наиболее значимое применение данный шаблон нашел в библиотеках классов, так как он предоставляет возможность вынести общее поведение в отдельную сущность.

Структуру и принцип построения этого шаблона проще всего рассмотреть на следующем примере.

public abstract class Sort { private int Г j data;

public abstract boolean compare(int x, int y) ;

private void swap(int posl, int pos2) { int tmp - data.posl.;

data.posl. = data pos2_;

data.pos2. = tmp;

public int.. sort(int.. argO) {
data = argO.clone();
boolean isSorted = false;
while
(!isSorted) {
isSorted true;
for(int i = 0; i < data._ength - 1; i++)
if(compare(data.i., data.i +1])) {
isSorted = false;
swap(i, i + 1);


return data;

public class AscendingSort extends Sort {

public boolean compare(int x, int y) { if(x <= y)

1   ...   6   7   8   9   10   11   12   13   14


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