Чтобы усечь очень большие файлы на самом деле, у нас есть команда truncate
. Он не знает о строках, но tail
+ wc
может преобразовывать строки в байты:
file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file
Существует очевидное условие гонки, если файл записывается в одно и то же время. В этом случае может быть лучше использовать head
- он подсчитывает байты от начала файла (mind disk IO), поэтому мы всегда будем усекать на границе строки (возможно, больше строк, чем ожидалось, если файл активно написан):
truncate -s $(head -n -$lines $file | wc -c) $file
Handy one-liner, если вы не ввели попытку входа в систему, поставив пароль вместо имени пользователя:
truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure
Для меня одна из главных причин использовать МОК (и использовать внешнюю конфигурацию) вокруг двух областей:
Тестирование
, Если Вы разделяете свое тестирование на 3 сценария (который довольно нормален в крупномасштабной разработке):
, Что Вы захотите сделать, для последних двух сценариев тестирования (Интеграция & Черный квадрат), не, перекомпилировали любую часть приложения.
, Если какой-либо из Ваших сценариев тестирования требует, чтобы Вы изменили конфигурацию (т.е.: используйте другой компонент, чтобы подражать банковской интеграции или сделать загрузку производительности), это может быть легко обработано (это действительно прибывает под преимуществами конфигурирования стороны DI МОК все же.
Дополнительно, если Ваше приложение используется любой на нескольких сайтах (с различным сервером и конфигурацией компонента) или имеет изменяющуюся конфигурацию на продуктивной среде, можно использовать более поздние этапы тестирования, чтобы проверить, что приложение обработает те изменения.
Производство
Как разработчик Вы не делаете (и не должен) иметь контроль над продуктивной средой (в особенности, когда Ваше приложение распределяется нескольким клиентам или отдельным сайтам), это мне - реальная выгода использования и МОК и внешняя конфигурация, как это до поддержки инфраструктуры/производства, чтобы настроить и скорректировать продуктивную среду, не имея необходимость возвращаться к разработчикам и через тест (более высокая стоимость, когда все, что они хотят сделать, переместить компонент).
Сводка
основные преимущества, что внешняя конфигурация МОК прибывает из предоставления другим (неразработчикам) питания настроить Ваше приложение, по моему опыту, это только полезно под ограниченным стечением обстоятельств:
На практике я нашел, что, разрабатывая что-то, что Вы действительно управляете средой, на ней будут работать, со временем лучше дать кому-то еще возможности изменить конфигурацию:
Примечание: Приложение относится к полному решению (не только исполняемый файл), таким образом, все файлы, требуемые для приложения работать .
Ваш случай очень прост и поэтому не нуждается в МОК (Инверсия Управления) контейнер как Spring. С другой стороны, когда Вы "программа к интерфейсам, не реализации" (который является хорошей практикой в ООП), у Вас может быть код как это:
IService myService;
// ...
public void doSomething() {
myService.fetchData();
}
(отмечают, что тип myService является IService - интерфейс, не конкретная реализация). Теперь может быть удобно позволить Вашему контейнеру МОК автоматически обеспечить корректный конкретный экземпляр IService во время инициализации - когда у Вас есть много интерфейсов и много реализаций, это может быть громоздким, чтобы сделать это вручную. Основные преимущества контейнера МОК (платформа внедрения зависимости):
Spring также имеет загрузчик свойств. Мы используем этот метод для установки переменных, которые являются иждивенцем на среде (например, разработка, тестирование, принятие, производство...). Это могло быть, например, очередью для слушания.
, Если бы нет никакой причины, почему свойство изменилось бы, нет также никакой причины настроить его таким образом.
В мире.NET большинство платформ МОК обеспечивает и XML и конфигурацию Кода.
StructureMap и Ninject, например, используют быстрые интерфейсы для конфигурирования контейнеров. Вы больше не вынуждаетесь использовать конфигурационные XML-файлы. Spring, который также существует в.NET, в большой степени полагается на XML-файлы, так как это - его исторический основной интерфейс конфигурирования, но все еще возможно настроить контейнеры программно.
Простота объединяющиеся частичные конфигурации в финал завершает конфигурацию.
, Например, в веб-приложениях, модель, представление и контроллеры обычно определяются в отдельных конфигурационных файлах. Используйте декларативный подход, можно загрузиться, например:
UI-context.xml
Model-context.xml
Controller-context.xml
Или загрузка с различным UI и несколькими дополнительными контроллерами:
AlternateUI-context.xml
Model-context.xml
Controller-context.xml
ControllerAdditions-context.xml
, Чтобы сделать то же в коде требует инфраструктуры для объединения частичных конфигураций. Не невозможный сделать в коде, но конечно легче сделать использование платформы МОК.
Вы не должны перекомпилировать свой код каждый раз, когда Вы изменяете что-то в конфигурации. Это упростит развертывание программы и обслуживание. Например, можно подкачать один компонент с другим со всего 1 изменением в файле конфигурации.
Причина использования контейнера DI состоит в том, что у Вас не должен быть миллиарда свойств, предварительно сконфигурированных в Вашем коде, которые являются просто методами get и методами set. Вы действительно хотите к hardcode все те с новым X ()? Несомненно, у Вас может быть значение по умолчанию, но контейнер DI позволяет создание одиночных элементов, которое чрезвычайно легко и позволяет Вам фокусироваться на деталях кода, не разной задаче инициализации его.
, Например, Spring позволяет Вам реализовывать интерфейс InitializingBean и добавлять afterPropertiesSet метод (можно также определить "init-метод", чтобы не связывать код с Spring). Эти методы позволят Вам удостоверяться, что любой интерфейс, определенный как поле в Вашем экземпляре класса, настроен правильно после запуска, и затем у Вас больше нет к пустой проверке своих методов get и методов set (предполагающий, что Вы действительно позволяете Вашим одиночным элементам оставаться ориентированными на многопотоковое исполнение).
, Кроме того, намного легче сделать сложные инициализации с контейнером DI вместо того, чтобы делать их самостоятельно. Например, я помогаю с использованием XFire (не CeltiXFire, мы только используем Java 1.4). Приложение использовало Spring, но это, к сожалению, использовало механизм конфигурации services.xml XFIRE. Когда Набор элементов должен был объявить, что имел НУЛЬ или больше экземпляров вместо Одного или нескольких экземпляров, я должен был переопределить часть обеспеченного кода XFire для этого конкретного сервиса.
существуют определенные значения по умолчанию XFire, определенные в его бобовой схеме Spring. Так, если мы использовали Spring для конфигурирования сервисов, бобы, возможно, использовались. Вместо этого что произошло, был то, что я должен был предоставить экземпляр определенного класса в файле services.xml вместо того, чтобы использовать бобы. Чтобы сделать это, я должен был предоставить конструктору и настроить ссылки, объявленные в конфигурации XFire. Реальное изменение, которое я должен был делать требуемым, что я перегружаю единый класс.
, Но, благодаря файлу services.xml, я должен был создать четыре новых класса, установив их значения по умолчанию согласно их значениям по умолчанию в конфигурационных файлах Spring в их конструкторах. Если бы мы были в состоянии использовать конфигурацию Spring, я, возможно, просто заявил:
<bean id="base" parent="RootXFireBean">
<property name="secondProperty" ref="secondBean" />
</bean>
<bean id="secondBean" parent="secondaryXFireBean">
<property name="firstProperty" ref="thirdBean" />
</bean>
<bean id="thirdBean" parent="thirdXFireBean">
<property name="secondProperty" ref="myNewBean" />
</bean>
<bean id="myNewBean" class="WowItsActuallyTheCodeThatChanged" />
Вместо этого это походило больше на это:
public class TheFirstPointlessClass extends SomeXFireClass {
public TheFirstPointlessClass() {
setFirstProperty(new TheSecondPointlessClass());
setSecondProperty(new TheThingThatWasHereBefore());
}
}
public class TheSecondPointlessClass extends YetAnotherXFireClass {
public TheSecondPointlessClass() {
setFirstProperty(TheThirdPointlessClass());
}
}
public class TheThirdPointlessClass extends GeeAnotherXFireClass {
public TheThirdPointlessClass() {
setFirstProperty(new AnotherThingThatWasHereBefore());
setSecondProperty(new WowItsActuallyTheCodeThatChanged());
}
}
public class WowItsActuallyTheCodeThatChanged extends TheXFireClassIActuallyCareAbout {
public WowItsActuallyTheCodeThatChanged() {
}
public overrideTheMethod(Object[] arguments) {
//Do overridden stuff
}
}
, Таким образом, конечный результат состоит в том, что четыре дополнительных, главным образом бессмысленных класса Java должны были быть добавлены к кодовой базе для достижения влияния что один дополнительный класс и некоторая простая достигнутая информация о контейнере зависимости. Это не "исключение, которое доказывает правило", это - правило... обрабатывающее причуды в коде, является намного более чистым, когда свойства уже обеспечиваются в контейнере DI, и Вы просто изменяете их для удовлетворения специальной ситуации, которая происходит, как правило.
Одна из самых привлекательных причин" голливудский принцип ": не звоните нам, мы позвоним Вам. Компонент не требуется, чтобы делать поиски к другим компонентам и услуги сам; вместо этого их предоставляют ему автоматически. В Java это означает, что больше не необходимо сделать поиски JNDI в компоненте.
Это - также партии, легче к модульному тесту компонент в изоляции: вместо того, чтобы дать ему фактическая реализация компонентов, в которых это нуждается, Вы просто, использует (возможно автоматический сгенерированный) насмешки.
Это - определенный загруженный вопрос, но я склонен соглашаться, что огромные суммы конфигурации XML действительно не составляют много преимущества. Мне нравится, когда мои приложения максимально легки на зависимостях, включая значительные платформы.
Они упрощают код много времен, но у них также есть издержки в сложности, которая делает разыскивание проблем довольно трудным (я видел такие проблемы на собственном опыте и прямой Java, я был бы намного более удобным контактом с).
я предполагаю, что это зависит от стиля немного, и чем Вы довольны..., Вам нравится управлять Вашим собственным решением и обладать преимуществом очень хорошо знания его или полагаться на существующие решения, которые могут оказаться трудными, когда конфигурация не является просто правильной? Это - весь компромисс.
Однако конфигурация XML является определенным моим главным объектом неприязни... Я стараюсь избегать его любой ценой.
Внедрение зависимости является стилем кодирования, который имеет его корни в наблюдении, что объектная делегация обычно является более полезным шаблоном разработки, чем объектное наследование (т.е. объект имеет - отношения более полезны, чем объект - отношения). Еще один компонент необходим однако для DI для работы, то из создания интерфейсов объекта. Объединение этих двух мощных разработчиков программного обеспечения шаблонов разработки быстро поняло, что они могли создать гибкий слабо связанный код, и таким образом понятие Внедрения зависимости родилось. Однако, только когда объектное отражение стало доступным на определенных высокоуровневых языках, DI действительно взлетел. Отражательный компонент является ядром к большинству сегодняшних систем DI сегодня, потому что действительно прохладные аспекты DI требуют способности программно выбрать объекты и настроить и ввести их в другие объекты с помощью системы, внешней и независимой к самим объектам.
язык А должен оказать хорошую поддержку и для обычного объекта Ориентированные методы программирования, а также поддержка интерфейсов объекта и возразить отражению (например, Java и C#). В то время как можно создать программы с помощью шаблонов DI в системах C++, его отсутствие отражательной поддержки в надлежащем языке предотвращает его от серверов другого приложения и других платформ DI и следовательно ограничивает выразительность шаблонов DI.
Преимущества системы, созданной с помощью шаблонов DI:
Определенно код DI кажется более громоздким, недостатки наличия всех тех XML-файлов, которые настраивают объекты, которые будут введены в другие объекты, кажется трудным. Это - однако, точка систем DI. Ваша способность к объектам кода смешивания и подгонки как серия параметров конфигурации позволяет Вам создавать сложные системы с помощью стороннего кода с минимальным кодированием с Вашей стороны.
пример, обеспеченный в вопросе просто, затрагивает поверхность выразительного питания, которое может обеспечить правильно учтенная библиотека объектов DI. С некоторой практикой и большим количеством из сам дисциплинируют большинство практиков DI, находят, что они могут системы сборки, которые имеют 100%-е тестовое покрытие кода приложения. Одна только эта точка экстраординарна. Это не 100%-е тестовое покрытие небольшого приложения нескольких сотен строк кода, но 100%-е тестовое покрытие приложений, включающих сотни тысяч строк кода. Я в замешательстве способности описать любой другой шаблон разработки, который обеспечивает этот уровень тестируемости.
Вы корректны в этом приложение, простые 10-е строк кода легче понять, чем несколько объектов плюс серия конфигурационных XML-файлов. Однако как с большинством мощных шаблонов разработки, усиления найдены, в то время как Вы продолжаете добавлять новые опции к системе.
Короче говоря, крупномасштабные основанные на DI приложения и легче отладить и легче понять. В то время как конфигурация XML не является 'временем компиляции, проверенным' все прикладные службы, о которых знает этот автор, предоставит разработчику сообщения об ошибках, если они попытаются ввести объект, имеющий несовместимый интерфейс в другой объект. И большинство обеспечивает функцию 'проверки', которая покрывает все известные конфигурации объектов. Это легко и быстро сделано путем проверки что введенный будущим образом объект реализации интерфейс, требуемый объектом B для всех настроенных объектных инжекций.
Можно вставить в новой реализации для подруги. Таким образом, новая розетка может быть введена, не перекомпилировав Ваш код.
<bean id="jane" class="foo.bar.HotFemale">
<property name="age" value="19"/>
</bean>
<bean id="mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="john" class="foo.bar.Male">
<property name="girlfriend" ref="jane"/>
</bean>
(Вышеупомянутое принимает, Розетка и HotFemale реализуют тот же интерфейс GirlfFriend)
Каждый раз, когда вы можете изменить свой код на данные, вы делаете шаг в правильном направлении.
Кодирование что-либо как данные означает, что сам ваш код является более общим и пригодным для повторного использования. Это также означает, что ваши данные могут быть указаны на языке, который подходит именно им.
Кроме того, XML-файл может быть считан в GUI или какой-либо другой инструмент и легко прагматично манипулировать. Как бы вы сделали это с примером кода?
Я постоянно делаю то, что большинство людей реализуют в виде кода, в данные, что делает код более чистым. Я считаю непостижимым, что люди будут создавать меню в коде, а не в виде данных - должно быть очевидно, что делать это в коде просто неправильно из-за шаблона.
Часто важным моментом является то, кто изменяет конфигурацию после написания программы. При использовании конфигурации в коде вы неявно предполагаете, что человек, изменяющий ее, обладает теми же навыками и доступом к исходному коду и т.д., что и автор оригинала.
В производственных системах очень практично извлекать некоторое подмножество настроек (например, возраст в вашем примере) в XML файл и позволять, например, системному администратору или сотруднику службы поддержки изменять значение, не давая им полной власти над исходным кодом или другими настройками - или просто изолировать их от сложностей.