для инкапсуляции.
-121--4585674-Это все объекты, все время. Ключ заключается в том, связано ли с возвращаемыми объектами поведение. Это прекрасно:
def read_first_and_last_name(data_source)
[data_source.read_string, data_source.read_string]
end
Но в тот момент, когда вы обнаружите, есть поведение, связанное с этими предметами данных...
def print_name(first_name, last_name)
puts "#{first_name} #{last_name}"
end
def read_and_print_name
first_name, last_name = read_first_and_last_name(data_source)
print_name(first_name, last_name)
end
... тогда они должны быть классом:
class FullName
def FullName.read(data_source)
FullName.new(data_source.read_string, data_source.read_strng)
end
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
def print
puts "#{@first_name} #{@last_name}"
end
end
С поведением имени красиво инкапсулирован, использование становится таким же простым, как:
def read_and_print_name
FullName.read(data_source).print
end
-121--3357730- инкапсулировать, и что путь вы делаете как вы храните данные в своем классе детали реализации . Если в вашем классе есть средство получения/установки:
private string _mystring = string.Empty;
public string SomeValue
{
get
{
return _mystring;
}
}
Это позволяет изменить способ управления «SomeValue» в будущем. Например, вы можете решить, что вместо того, чтобы хранить его в последовательности, он на самом деле будет Guid под капотом. Теперь вы можете перейти к:
private Guid _myguid= Guid.NewGuid();
public string SomeValue
{
get
{
return _myguid.ToString();
}
}
В любом месте, где используется ваш класс и доступ к свойству «SomeValue» останется неизменным.
Проверка
Можно также проверить переданное значение, так что в другом примере
private string _mystring = "My Value";
public string SomeValue
{
get
{
return _mystring;
}
set
{
if (string.IsNullOrEmpty(value))
{
throw new InvalidArgumentException();
}
else
{
_myString = value;
}
}
}
Чтобы убедиться, что сохранённый ряд никогда не набор нулевому / пустому ряду
Чтобы ограничить доступ к внутреннему состоянию объекта.
Рассмотрим классический пример класса геометрических фигур. Скажем, объект Circle. Когда вы устанавливаете радиус, вы можете захотеть автоматически вычислить площадь (которая будет свойством только для чтения)
class Circle
{
float radius;
public float Radius
{
get { return radius; }
set { radius = value; area = Math.Pi * radius * radius;}
}
float area;
float Area
{
get { return area;}
}
}
Если вы разрешили прямой доступ к элементу данных «radius», вы не сможете обновить область
когда он изменился. Кроме того, если вы разрешили прямой доступ к области
, пользователи могли бы изменить его волей-неволей, не обращая внимания на радиус
.
One причина в том, чтобы обеспечить более единообразный интерфейс для объекта на некоторых языках - вам больше не нужно иметь дело с синтаксической разницей между полями и методами; вы всегда имеете дело с методами.
Вторая причина заключается в том, что вы скрываете реализацию объекта, позволяя изменять его внутренне, не затрагивая его клиентов. Классическим примером является одна из координат - если у вас есть координата, представленная через декартовы координаты, и переключите внутреннее представление на полярное, если вы использовали геттеры и сеттеры, ваша программа все равно будет работать, даже если поля x и y отсутствуют. Это также позволяет использовать полиморфизм - два объекта, представляющих одну и ту же абстракцию, но каждый с разной реализацией своего состояния.
Доступ к состоянию через методы также позволяет добавлять такие вещи, как синхронизация.
Если вы сделаете поле закрытым и настроите геттер и сеттер для доступа к нему, тогда весь другой код должен пройти через эти методы, чтобы добраться до этого данные. Тогда у вас будет больше контроля.
Вы получаете те же преимущества и внутри класса, если строго используете геттер и сеттер для доступа к полю. Так что для многих людей это то, чем они занимаются постоянно.
Геттеры и сеттеры изначально не выглядят так хорошо, потому что они кажутся слишком большими. Но такие IDE, как Eclipse, могут автоматически создавать для вас геттеры и сеттеры, если хотите. Такие языки, как Objective-C и Ruby, тоже могут это делать, используя сокращенный синтаксис. C # может заключать геттеры и сеттеры в «свойства», которые используются в коде точно так же, как поля, но под капотом он вызывает геттеры и сеттеры, которые вы пишете.
Итак, есть много причин использовать геттеры и сеттеры, а также множество средств, чтобы сделать это менее болезненным.
Пакет наборов данных
входит в базовый R. Выполните эту команду, чтобы увидеть полный список:
library(help="datasets")
Кроме того, существует много пакетов, которые могут извлекать данные, и много других, которые содержат важные данные. Начнем с пакета HistData , который «предоставляет набор небольших наборов данных, которые интересны и важны в истории статистики и визуализации данных».
Для финансовых данных пакет quantmod
предоставляет общий интерфейс для извлечения данных временных рядов из google, yahoo, FRED и других:
library(quantmod)
getSymbols("YHOO",src="google") # from google finance
getSymbols("GOOG",src="yahoo") # from yahoo finance
getSymbols("DEXUSJP",src="FRED") # FX rates from FRED
FRED ( Федеральная резервная система Сент-Луиса ) действительно является наземной миной свободных экономических данных.
Многие пакеты R объединяются с данными, специфичными для их цели. Таким образом, если вы заинтересованы в генетике, многоуровневых моделях и т.д., соответствующие пакеты часто будут иметь канонический пример для этого анализа. Кроме того, пакеты книг обычно поставляются с данными, необходимыми для воспроизведения всех примеров.
Вот несколько примеров соответствующих пакетов:
для инкапсуляции.