В случае Fragment
s:
В соответствии с исходным кодом класса Fragment
на android.googlesource.com , где определен конструктор по умолчанию, мы видим, что:
Каждый фрагмент должен иметь пустой конструктор, чтобы его можно было создать при восстановлении состояния его активности. Настоятельно рекомендуется, чтобы у подклассов не было других конструкторов с параметрами, поскольку эти конструкторы не будут вызываться при повторном создании фрагмента; вместо этого вызывающая сторона может предоставлять аргументы с помощью setArguments и позже извлекается фрагментом с помощью getArguments .
Приложения, как правило, не должны реализовывать конструктор. Вместо этого предпочитайте onAttach (Context) . Это первое место, где код приложения может выполняться там, где фрагмент готов к использованию - точка, где фрагмент фактически связан с его контекстом. Некоторые приложения могут также захотеть реализовать onInflate для извлечения атрибутов из ресурса макета, хотя обратите внимание, что это происходит, когда фрагмент прикреплен.
Ссылаясь на вышеуказанную причину, добавление конструкторов не по умолчанию в Fragment
означает ЗАПРЕЩЕНО !!!
После этого с использованием setArguments
и getArguments
Методы - это альтернативный способ избежать добавления дополнительных конструкторов. Код B , написанный под вопросом, использует эти два подхода одновременно. Вы должны использовать один из них , то есть , как Код A . (Потому что, когда вы передаете параметр в конструктор, вы можете получить к нему доступ в классе. Поэтому шаблон [set/get]Arguments
не нужен)
Однако, если мы хотим переписать код B без использования аргументов ( Отказ от ответственности: я подчеркиваю, что этот подход неверен ), мы можем сделать это следующим образом:
class UIFragmentPhoto internal constructor(private val image: File?) : Fragment() {
constructor() : this(null)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?) = ImageView(context)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val resource = image ?: R.drawable.ic_photo
Glide.with(view).load(resource).into(view as ImageView)
}
}
В общем:
Мы все знаем, что объект создается путем вызова метода конструктора класса в Java / Kotlin. Например:
val obj = MyClass()
Когда вы хотите создать объект, нет необходимости заключать вызов конструктора в другую функцию, если только природа объекта не должна быть изменена в соответствии с характером программы. Потому что это приводит к бремени одного дополнительного вызова функции для создания объекта без каких-либо преимуществ.
В случае изменения объектов в соответствии с характером программы, мы должны получить помощь шаблонов проектирования. для обеспечения более общего и гибкого подхода (, например: Фабричный метод, Абстрактная фабрика, и т. д. Шаблоны).
Вывод:
Когда вы имеете дело с созданием объекта из Fragment
классов, Код A стиль должен быть использован. (По причине, описанной в android.googlesource.com )
Когда вы имеете дело с созданием объекта из non- Fragment
классы, стиль Code B лучше использовать. (Из-за отказа от дополнительного вызова функции, который не имеет никакого преимущества)