2015-09-11 38 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)如何做数据抽象不同于封装

正如我所理解的数据抽象只是hidi来自其他类的一些成员数据。

回答

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] 

过程抽象是关于从用户隐藏程序的实施细节。在上面的例子中,你并不需要知道内部使用的排序算法0​​方法,只是假设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

谢谢魔杖。所以我们在不知不觉中做抽象 –

+0

我认为我们知道抽象,它是良好的设计必不可少的。 –

+0

对不起,但我的关注是,假设我做了一个函数来计算factorial,并且用户将它作为fact(num)来调用它。那么我们可以说它是抽象的。 –

0

'Abstraction'的定义:处理意见而不是事件的质量。

参考这个答案difference between abstraction and encapsulation?和我的了解,我发现,在你的代码的方法my_sort充分证明了Encapsulation因为它封装了与任何single dimension数组排序behavior。然而它缺少abstraction,因为方法my_sort知道它要处理的数据的类型。

如果它不知道/关心通过params进入的数据的类型,它会证明Abstraction。换句话说,它应该对任何进入的对象进行排序,无论它是否是列表FixnumString或其他sortable datatypes

封装

我们通常使用访问修饰符(publicprivate,..)来区分将被暴露于clients和将被使用的internally数据/行为。公开接口(暴露给客户)不会随时改变。但是,private是可以更改的行为,不应在任何情况下影响clients依赖的代码的预期行为。
此外,我们将敏感数据/行为分为私有/受保护以防止意外修改/滥用。这使得客户端不会依赖可能频繁更改的代码部分。

  • 所以人们总是需要将core logic分隔为private范围。

抽象

示例: 在教堂里的情况下,存在的confessorfather/priest之间的abstraction。忏悔者不应该知道priest的名称或任何细节,反之亦然。不管他/她犯了多大的错误/犯罪,任何人都可以坦白并隐藏自己的身份。

+1

伟大的! 很好的解释,但你错过了我的第二个问题,请你盖上这一个。 –