Значение возражает по сравнению с ассоциативными массивами в PHP

(Этот вопрос использует PHP в качестве контекста, но не ограничивается PHP только. например, Любой язык с созданным в хеше также релевантен),

Давайте посмотрим на этот пример (PHP):

function makeAFredUsingAssoc()
{
    return array(
        'id'=>1337,
        'height'=>137,
        'name'=>"Green Fred");
}

По сравнению с:

class Fred
{
    public $id;
    public $height;
    public $name;

    public function __construct($id, $height, $name)
    {
        $this->id = $id;
        $this->height = $height;
        $this->name = $name;
    }
}

function makeAFredUsingValueObject()
{
    return new Fred(1337, 137, "Green Fred");
}

Метод № 1 является, конечно, более кратким, однако он может легко привести к ошибке такой как

$myFred = makeAFredUsingAssoc();
return $myFred['naem']; // notice teh typo here

Конечно, можно было бы обсудить это $myFred->naem одинаково приведет к погрешности, которая истинна. Однако наличие формального класса просто чувствует себя более твердым мне, но я не могу действительно выровнять по ширине его.

Каковы были бы профессионалы/недостатки к использованию каждого подхода и когда люди должны использовать который подход?

38
задан kizzx2 13 January 2010 в 13:56
поделиться

6 ответов

Под поверхностью два подхода эквивалентны. Тем не менее, вы получаете большую часть стандартных преимуществ OO при использовании класса: инкапсуляция, наследование и т. Д.

Кроме того, посмотрите на следующие примеры:

$arr['naem'] = 'John';

совершенно действует и может быть сложной ошибкой для поиска.

С другой стороны,

$class->setNaem('John');

никогда не будет работать.

27
ответ дан 27 November 2019 в 03:28
поделиться

Позволить мне поставить этот вопрос вам:

, Что является настолько особенным в создании опечатки как $myFred ['naem'] и создании опечатки как $myFred-> naem? Та же проблема все еще существует в обоих случаях и они оба ошибка.

мне нравится использовать KISS (сохраните его простым, глупым), когда я программирую.

  • при простом возврате подмножества запроса из метода, просто возвратить массив.
  • , Если бы вы храните данные как общедоступный/частный/статичный/защищать переменная в одном из ваших классов, было бы лучше сохранить его как stdClass.
  • , Если вы собираетесь позже передать это другому методу класса, вы могли бы предпочесть строгий ввод класс Fred , т.е. государственная функция acceptsClass ($fredObj Fred)

, Вы, возможно, создали так же легко стандартный класс в противоположность массиву, если это должно использоваться как возвращаемое значение. В этом случае вы могли заботиться меньше о строгом вводе.

$class = new stdClass();
$class->param = 'value';
$class->param2 = 'value2';
return $class;
3
ответ дан 27 November 2019 в 03:28
поделиться

Я сделал некоторые игры и, наконец, придумал использование overLIB , смотрите мой блог для получения полной информации

-121--4482084-

Я предпочитаю иметь жестко закодированные свойства, как во втором примере. Я чувствую, что он более четко определяет ожидаемую структуру класса (и все возможные свойства класса). В отличие от первого примера, который сводится к тому, чтобы просто всегда помнить использовать одни и те же имена ключей. Со вторым можно всегда вернуться и посмотреть на класс, чтобы получить представление о свойствах, просто посмотрев в верхней части файла.

Вам лучше знать, что вы делаете что-то не так со вторым - если вы попытаетесь echo $ this- > donnt Exist , вы получите ошибку, в то время как если вы попытаетесь echo массив ['donnntExist'] вы не будете.

-121--1242911-

Если возвращаемое значение представляет сущность в приложении, следует использовать объект, так как это назначение ООП. Если вы просто хотите вернуть группу несвязанных значений, то это не так ясно вырезать. Однако, если это часть открытого API, то объявленный класс по-прежнему является лучшим способом.

1
ответ дан 27 November 2019 в 03:28
поделиться

Я предпочитаю жестко закодированные свойства, как во втором примере. Мне кажется, что это более четко определяет ожидаемую структуру класса (и все возможные свойства класса). В отличие от первого примера, который сводится к тому, чтобы всегда помнить об использовании одних и тех же имен ключей. Со вторым вы всегда можете вернуться назад и посмотреть на класс, чтобы получить представление о свойствах, просто посмотрев на верхнюю часть файла.

Вам лучше знать, что вы делаете что-то не так со вторым - если вы попробуете echo $this->doesntExist вы получите ошибку, а если вы попробуете echo array['doesntExist'] вы не получите.

0
ответ дан 27 November 2019 в 03:28
поделиться

Для простых представленных чехов вы бы окончательно лучше с решением, представленным Roger Pate .

То, что вам нужно для общего решения MetaProgramming Type_traits . Вы можете использовать их из повышения, либо поставляемых с вашим STL, если достаточно современно.

namespace detail {

  template < class T >
  T trim_impl(T &val, const std::tr1::true_type& )
  {
    if (val < 0)
    {
      val = 0;
    }
    return (val);
  }

  template < class T >
  T trim_impl(T &val, const std::tr1::false_type& )
  {
    return (val);
  }  

} // end namespace detail

template < class T >
T trim(T &val)
{
  return detail::trim_impl( val, std::tr1::is_signed<T>() );
}

Обратите внимание, однако IS_Signed IS_Signed false_type для чисел плавающих точек (не спрашивайте почему). Чтобы сделать вышеуказанный код работы с плавающими точками, вам нужно будет типировать еще одну черту, например,

typedef std::tr1::integral_constant< bool, 
            std::tr1::is_signed<T>::value || 
            std::tr1::is_floating_point<T>::value > has_sign;

... и да, глубже вы попадаете в MetaProgramming UUGLIER, он получает так ... игнорировать это решение и перейти с простым, перечисленным Roger: P.

-121--4213573-

в зависимости от упрещей, которую я мог бы использовать, либо. Преимущество класса состоит в том, что я могу использовать его как тип и использование типа подсказки на методах или любых методах саморегуления. Если я просто хочу пройти какой-то случайный набор данных от запроса или что-то, я, вероятно, использовал массив. Так что я думаю, пока Фреда имеет особое значение в моей модели, я бы использовал класс.

на Sidenote:
ValueObjects должны быть неизменными. По крайней мере, если вы ссылаетесь на определение Эрика Эвана в домене, управляемый доменом. В Peaea Peaeal ValueObjects не обязательно должны быть неизменными (хотя рекомендуется), но они не должны иметь личность, что ясно в случае с Фред .

6
ответ дан 27 November 2019 в 03:28
поделиться

Pro для хеша: он способен обрабатывать комбинации значений имени, которые неизвестны по времени проектирования.

2
ответ дан 27 November 2019 в 03:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: