Не думаю, что высота большого пальца основана на размере содержимого, вы можете изменить ширину внутри ::-webkit-scrollbar
, но высота всегда будет основана на содержании.
::-webkit-scrollbar { /* 1 */ }
::-webkit-scrollbar-button { /* 2 */ }
::-webkit-scrollbar-track { /* 3 */ }
::-webkit-scrollbar-track-piece { /* 4 */ }
::-webkit-scrollbar-thumb { /* 5 */ }
::-webkit-scrollbar-corner { /* 6 */ }
::-webkit-resizer { /* 7 */ }
Это довольно интересный вопрос - и ответы могут быть интересными также ^^
. Самый простой способ рассмотреть вещи может быть:
(Да, я признаю, действительно действительно слишком упрощен ...)
. Одна вещь о статических методах / классах заключается в том, что они не облегчают модульное тестирование (по крайней мере, в PHP, но, вероятно, и на других языках).
Другое дело о статических данных состоит в том, что только один экземпляр он существует в вашей программе: если вы установите где-то значение MyClass :: $ myData, оно будет иметь это значение и только оно, где угодно - говоря о пользователе, вы сможете иметь только одного пользователя - что это не так уж и больно?
Для системы блога, что я могу сказать? Не так много, я бы написал как статичный, на самом деле, я думаю; возможно, класс DB-access, но, вероятно, нет, в конце ^^
Основными двумя причинами против использования статических методов являются:
Наличие вызова статического метода внутри какого-либо другого метода на самом деле хуже, чем импорт глобальной переменной. В PHP классы являются глобальными символами, поэтому каждый раз, когда вы вызываете статический метод, вы полагаетесь на глобальный символ (имя класса). Это случай, когда глобальное зло. У меня были проблемы с подобным подходом с некоторыми компонентами Zend Framework. Существуют классы, которые используют статические вызовы (фабрики) для создания объектов. Мне не удалось поставить другую фабрику в этот экземпляр, чтобы вернуть настроенный объект. Решение этой проблемы состоит в том, чтобы использовать только экземпляры и внедрять методы и применять синглтоны и т. Д. В начале программы.
Мишко Хевери , который работает в качестве Agile Coach at Google, имеет интересную теорию или, скорее, советует, что мы должны отделить время создания объекта от времени использования объекта. Таким образом, жизненный цикл программы разделен на две части. Первая часть (например, метод [6]), которая заботится обо всех объектных проводках в вашем приложении и о части, которая выполняет фактическую работу.
Итак, вместо наличия:
class HttpClient
{
public function request()
{
return HttpResponse::build();
}
}
Мы должны сделать следующее:
class HttpClient
{
private $httpResponseFactory;
public function __construct($httpResponseFactory)
{
$this->httpResponseFactory = $httpResponseFactory;
}
public function request()
{
return $this->httpResponseFactory->build();
}
}
И затем, на странице индекса / главной страницы, мы сделали бы (это шаг проводки объекта или время для создания графика экземпляры, которые будут использоваться программой):
$httpResponseFactory = new HttpResponseFactory;
$httpClient = new HttpClient($httpResponseFactory);
$httpResponse = $httpClient->request();
Основная идея состоит в том, чтобы отделить зависимости от ваших классов. Таким образом, код гораздо более расширяемый и, что самое важное для меня, можно проверить. Почему важнее быть проверяемым? Потому что я не всегда пишу библиотечный код, поэтому расширяемость не так важна, но проверяемость важна, когда я делаю рефакторинг. В любом случае, проверяемый код обычно дает расширяемый код, поэтому он не является ни одной из ситуаций.
Miško Hevery также проводит четкое различие между синглтонами и синглтонами (с или без капитала S). Разница очень проста. Синглтоны с нижним регистром «s» выполняются проводкой в индексе / главной. Вы создаете экземпляр объекта класса, который не реализует шаблон Singleton, и следите за тем, чтобы вы передавали этот экземпляр только любому другому экземпляру, который ему нужен. С другой стороны, Синглтон с капиталом «S» является реализацией классического (анти) шаблона. В основном глобальная маскировка, которая мало использует в мире PHP. Я до сих пор не видел этого. Если вы хотите, чтобы одно соединение с БД использовалось всеми вашими классами, лучше сделать это следующим образом:
$db = new DbConnection;
$users = new UserCollection($db);
$posts = new PostCollection($db);
$comments = new CommentsCollection($db);
. Выполняя вышеизложенное, ясно, что у нас есть синглтон, и у нас также есть хороший способ чтобы ввести макет или заглушку в наши тесты. На удивление, как модульные тесты ведут к лучшему дизайну. Но это имеет смысл, если вы думаете, что тесты заставляют вас думать о том, как вы будете использовать этот код.
/**
* An example of a test using PHPUnit. The point is to see how easy it is to
* pass the UserCollection constructor an alternative implementation of
* DbCollection.
*/
class UserCollection extends PHPUnit_Framework_TestCase
{
public function testGetAllComments()
{
$mockedMethods = array('query');
$dbMock = $this->getMock('DbConnection', $mockedMethods);
$dbMock->expects($this->any())
->method('query')
->will($this->returnValue(array('John', 'George')));
$userCollection = new UserCollection($dbMock);
$allUsers = $userCollection->getAll();
$this->assertEquals(array('John', 'George'), $allUsers);
}
}
Единственная ситуация, в которой я буду использовать (и я использовал их для имитации объекта прототипа JavaScript в PHP 5.3). Статические члены - это когда я знаю, что соответствующее поле будет иметь одно и то же значение cross-instance. В этот момент вы можете использовать статическое свойство и, возможно, пару статических методов getter / setter. В любом случае, не забудьте добавить возможность переопределения статического члена членом экземпляра. Например, Zend Framework использует статическое свойство, чтобы указать имя класса адаптера DB, используемого в экземплярах Zend_Db_Table
. Прошло некоторое время с тех пор, как я использовал их, поэтому он больше не может быть релевантным, но вот как я его помню.
Статические методы, не относящиеся к статическим свойствам, должны быть функциями. PHP имеет функции, и мы должны их использовать.
Я хотел бы сказать, что определенно есть случай, когда мне нужны статические переменные - в приложениях с несколькими языками. У вас может быть класс, через который вы передаете язык (например, $ _SESSION ['language']), и он, в свою очередь, обращается к другим классам, которые сконструированы так:
Srings.php //The main class to access
StringsENUS.php //English/US
StringsESAR.php //Spanish/Argentina
//...etc
Использование строк :: getString ( «somestring») - отличный способ отвлечь ваше использование языка от вашего приложения. Вы можете сделать это, как вам угодно, но в этом случае, если каждый файл строк имеет константы со строковыми значениями, к которым обращается класс Strings, работает очень хорошо.
«Наличие вызова статического метода внутри какого-либо другого метода на самом деле хуже, чем импорт глобальной переменной». (определить «хуже») ... и «Статические методы, которые не имеют статических свойств, должны быть функциями».
Это оба довольно радикальные утверждения. Если у меня есть набор функций, связанных с предметом, но данные экземпляра совершенно неуместны, я бы скорее их определил в классе, а не в каждом из них в глобальном пространстве имен. Я просто использую механику, доступную в PHP5, чтобы
это всего лишь удобный способ обеспечить более высокую степень сцепления и более низкую связь.
И FWIW - нет такой вещи, по крайней мере в PHP5, как «статические классы»; методы и свойства могут быть статическими. Чтобы предотвратить создание экземпляра класса, можно также объявить его абстрактным.
У меня есть другой подход к большинству ответов здесь, особенно при использовании PHP. Я думаю, что все классы должны быть статическими, если у вас нет веских причин, почему бы и нет. Некоторые из причин «почему нет»:
Позвольте мне привести один пример. Поскольку каждый скрипт PHP создает HTML-код, в моей структуре есть класс html writer. Это гарантирует, что ни один другой класс не попытается написать HTML, поскольку это специализированная задача, которая должна быть сконцентрирована в одном классе.
Как правило, вы должны использовать класс html следующим образом:
html::set_attribute('class','myclass');
html::tag('div');
$str=html::get_buffer();
Каждый раз, когда вызывается get_buffer (), он сбрасывает все, чтобы запускался следующий класс для использования html-writer в известном состоянии.
Все мои статические классы имеют функцию init (), которую нужно вызвать до того, как класс будет использоваться в первый раз. Это скорее условность, чем необходимость.
Альтернатива статическому классу в этом случае беспорядочна. Вы бы не хотели, чтобы каждый класс должен был написать маленький бит html, чтобы управлять экземпляром html-записи.
Теперь я приведу вам пример того, когда не использовать статические классы. Мой класс формы управляет списком элементов формы, таких как текстовые входы, выпадающие списки и многое другое. Обычно он используется следующим образом:
$form = new form(stuff here);
$form->add(new text(stuff here));
$form->add(new submit(stuff here));
$form->render(); // Creates the entire form using the html class
Нет никакого способа сделать это со статическими классами, особенно учитывая, что некоторые из конструкторов каждого добавленного класса выполняют большую работу. Кроме того, цепочка наследования для всех элементов довольно сложна. Таким образом, это явный пример, когда статические классы не должны использоваться.
Большинство классов полезности, таких как строки преобразования / форматирования, являются хорошими кандидатами для статического класса. Мое правило прост: все статично в PHP, если нет одной причины, почему это не должно.
В общем, вы должны использовать переменные-члены и функции-члены, если это не обязательно должно быть разделено между всеми экземплярами или если вы не создаете одноэлемент. Использование данных членов и функций-членов позволяет повторно использовать ваши функции для нескольких разных частей данных, тогда как вы можете иметь только одну копию данных, на которых вы работаете, если используете статические данные и функции. Кроме того, хотя это не относится к PHP, статические функции и данные приводят к тому, что код не является реентерабельным, тогда как данные класса облегчают повторное размещение.
Если ваш класс является статичным, это означает, что вы не можете передавать его объект другим классам (так как нет экземпляра), так что все ваши классы будут напрямую использовать этот статический класс, что означает, что ваш код теперь тесно связан с классом.
Плотная связь делает ваш код менее многоразовым, хрупким и подверженным ошибкам. Вы хотите избежать статических классов, чтобы иметь возможность передать экземпляр класса другим классам.
И да, это только одна из многих других причин, о которых уже упоминалось.
Таким образом, в PHP статические могут быть применены к функциям или переменным. Нестатические переменные привязаны к определенному экземпляру класса. Нестатические методы действуют на экземпляр класса. Итак, создадим класс под названием BlogPost
.
title
будет нестационарным членом. Он содержит название этого блога. У нас также может быть метод, называемый find_related()
. Это не статично, потому что для этого требуется информация из определенного экземпляра класса post post.
Этот класс будет выглядеть примерно так:
class blog_post {
public $title;
public $my_dao;
public function find_related() {
$this->my_dao->find_all_with_title_words($this->title);
}
}
С другой стороны, использование статических функций , вы можете написать такой класс:
class blog_post_helper {
public static function find_related($blog_post) {
// Do stuff.
}
}
В этом случае, поскольку функция является статической и не действует на каком-либо конкретном блоге, вы должны перейти в сообщение в блоге в качестве аргумента.
По сути, это вопрос об объектно-ориентированном дизайне. Ваши классы - существительные в вашей системе, а функции, действующие на них, - это глаголы. Статические функции являются процедурными. Вы передаете объект функций в качестве аргументов.
Обновление: я бы также добавил, что решение редко встречается между методами экземпляра и статическими методами, и многое другое между использованием классов и использованием ассоциативных массивов. Например, в приложении для ведения блога вы либо читаете сообщения в блоге из базы данных и преобразуете их в объекты, либо оставляете их в наборе результатов и рассматриваете их как ассоциативные массивы. Затем вы записываете функции, которые принимают ассоциативные массивы или списки ассоциативных массивов в качестве аргументов.
В сценарии OO вы пишете методы в своем классе BlogPost
, которые действуют на отдельные сообщения, и вы пишете статические методы, которые действуют на коллекции сообщений.
Сначала спросите себя, что будет представлять этот объект? Экземпляр объекта хорош для работы с отдельными наборами динамических данных.
Хорошим примером может быть уровень абстракции ORM или базы данных. У вас может быть несколько соединений с базой данных.
$db1 = new Db(array('host' => $host1, 'username' => $username1, 'password' => $password1));
$db2 = new Db(array('host' => $host2, 'username' => $username2, 'password' => $password2));
Эти два соединения теперь могут работать независимо:
$someRecordsFromDb1 = $db1->getRows($selectStatement);
$someRecordsFromDb2 = $db2->getRows($selectStatement);
Теперь в этом пакете / библиотеке могут быть другие классы, такие как Db_Row и т. д., чтобы представить определенную строку, возвращаемую из инструкции SELECT. Если этот класс Db_Row был статическим классом, тогда предполагается, что у вас есть только одна строка данных в одной базе данных, и было бы невозможно сделать то, что мог бы сделать экземпляр объекта. С экземпляром теперь вы можете иметь неограниченное количество строк в неограниченном количестве таблиц в неограниченном количестве баз данных. Единственным ограничением является аппаратное обеспечение сервера;).
Например, если метод getRows объекта Db возвращает массив объектов Db_Row, вы можете теперь работать с каждой строкой независимо друг от друга:
foreach ($someRecordsFromDb1 as $row) {
// change some values
$row->someFieldValue = 'I am the value for someFieldValue';
$row->anotherDbField = 1;
// now save that record/row
$row->save();
}
foreach ($someRecordsFromDb2 as $row) {
// delete a row
$row->delete();
}
Хорошим примером статического класса будет то, что обрабатывает переменные реестра или переменные сеанса, поскольку для каждого пользователя будет только один реестр или один сеанс.
В одной части вашего application:
Session::set('someVar', 'toThisValue');
И в другой части:
Session::get('someVar'); // returns 'toThisValue'
Поскольку каждый сеанс только один раз будет за один сеанс, нет смысла создавать экземпляр для сеанса.
Надеюсь, это поможет вместе с другими ответами помочь разобраться. В качестве примечания обратите внимание на «сцепление » и « соединение ». Они описывают некоторые очень и очень хорошие практики, которые следует использовать при написании кода, применимого ко всем языкам программирования.
Все ли это стиль?
blockquote>Долгий путь, да. Вы можете писать совершенно хорошие объектно-ориентированные программы, не используя статические элементы. На самом деле некоторые люди утверждают, что статические члены - это, прежде всего, примесь. Я бы предположил, что - как новичок в oop - вы пытаетесь избежать статических членов вместе. Это заставит вас в направлении записи в объектно-ориентированном , а не в процедуре .