2015-09-11 3 views
6

Я новичок в Ruby. Я изучаю принцип абстракции в ruby. Как я понял, процедурная абстракция скрывает детали реализации от пользователя или просто концентрируется на основных принципах и игнорирует детали.Процедурная абстракция данных в рубине

Меня беспокоит то, как реализовать его

1) Является ли это простая функция вызова, как эта

# function to sort array 
# @params array[Array] to be sort 

def my_sort(array) 
    return array if array.size <= 1 

    swapped = false 
    while !swapped 
    swapped = false 
    0.upto(array.size-2) do |i| 
     if array[i] > array[i+1] 
     array[i], array[i+1] = array[i+1], array[i] 
     swapped = true 
     end 
    end 
    end 

    array 
end 

и вызов, как этот

sorted_array = my_sort([12,34,123,43,90,1]) 

2) Как абстракцию данных отличается от Encapsulation

Как я понял Абстракция данных - это просто hidi ng некоторые данные члена из других классов.

ответ

3

Вы возвращаете массив из метода. Структуры данных - это детали реализации. Если вы измените структуру данных, используемую в методе, вы нарушите код клиента. Таким образом, ваш пример не скрывает детали реализации. Он не инкапсулирует проектные решения, так что клиент изолирован от внутренних деталей реализации.

3

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

Класс Ruby Array является примером абстракции данных. Он обеспечивает механизм управления массивом объектов и предоставляет операции, которые могут выполняться в этом массиве, без необходимости заботиться о том, как он организован.

arr = [1,3,4,5,2,10] 
p arr.class # Prints Array 
p arr.sort # Prints [1,2,3,4,5,10] 

Процедурные абстракции о скрытии деталей реализации процедуры от пользователя. В приведенном выше примере вам не нужно знать, какой метод сортировки использует метод sort, вы просто используете его, полагая, что хорошие люди в команде Ruby Core выбрали для вас лучший вариант.

В то же время Ruby может и не знать, как сравнивать два элемента, присутствующих в Array. Например, ниже код не будет работать, поскольку Ruby не знает, как сравнивать строки и числа.

[1,3,4,5,"a","c","b", 2,10].sort 
#=> `sort': comparison of Fixnum with String failed (ArgumentError) 

Это позволяет подключить к реализации и помощь сравнения, несмотря на то, лежащий в основе алгоритма сортировки остается таким же (как она абстрагируется от пользователя)

[1,3,4,5,"a","c","b", 2,10].sort { |i,j| 
    if i.class == String and j.class == String 
     i <=> j 
    elsif i.class == Fixnum and j.class == Fixnum 
     i <=> j 
    else 
     0 
    end 
} 
#=> [1, 3, 4, 5, 2, 10, "a", "b", "c"] 

При написании кода для своих собственных проблем, процедурная абстракция может использоваться для обеспечения того, чтобы процедура часто нарушала ее проблему в подсубъекты и решает каждую проблему с использованием отдельной процедуры. Это позволяет, некоторые аспекты будут расширены позже (как в приведенном выше случае, сравнение может быть расширено - благодаря Ruby blocks это было намного проще). Template method pattern - хорошая техника для достижения этой цели.

+0

Спасибо Wand.So мы делаем абстракцию неосознанно –

+0

Я думаю, что мы делаем абстракцию сознательно, и это важно для хорошего дизайна. –

+0

Извините, но мое беспокойство в том, что. Предположим, что я сделал функцию для вычисления factorial.and пользователь вызывает его как факт (num). Тогда мы можем сказать, что это абстракция. –

0

Определение «Абстракция»: качество общения с идеями, а не событиями.

Ссылаясь на этот ответ difference between abstraction and encapsulation? и мое понимание я обнаружил, что в вашем коде метод my_sort полностью оправдывает Encapsulation, как он инкапсулирует behavior, связанные с сортировкой любого single dimension массива. Однако ему не хватает abstraction, так как метод my_sort знает тип данных, на которые он будет обрабатывать.

Было бы оправдано Abstraction, если бы он не знал/не заботился о типе данных, которые поступают через params. Другими словами, он должен был отсортировать любой объект, который приходит независимо от того, является ли он списком Fixnum или String или другим sortable datatypes.

Инкапсуляция:

Обычно мы используем модификаторы (public, private, ..) доступа, чтобы дифференцировать данные/поведения, которые должны быть подвержены clients и которые должны быть использованы internally. Публичный интерфейс (подверженный воздействию клиентов) не подлежит изменению, насколько это возможно. Однако private - это поведение, которое может измениться и ни в коем случае не должно влиять на ожидаемое поведение кода, на которое полагается clients.
Также мы разделяем конфиденциальные данные/поведение на частные/защищенные, чтобы предотвратить случайную модификацию/неправильное использование. Это заставляет клиента не полагаться на часть кода, которая может часто меняться.

  • Так что всегда нужно отделять core logic от private.

Абстракция:

Пример: В случае церкви есть abstraction между confessor и father/priest. Исповедник не должен иметь ни малейшего представления о названии или какой-либо детали priest и наоборот. Любой может признаться и все же скрывать свою личность независимо от того, какие большие ошибки/преступления он совершил.

+1

Отлично! Хорошее объяснение, но вы пропустили мой второй вопрос. Можете, пожалуйста, накрыть этот. –

Смежные вопросы