Назад к вопросам
Middle
68
questionbank

Как избавиться от четырёх конструкторов в кастомном представлении (CustomView)?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Можно использовать фабричный метод или builder pattern вместо прямого использования конструкторов.

  • Фабричный метод: Позволяет создавать экземпляры представления, абстрагируя процесс создания и скрывая логику выбора нужного конструктора.

    class MyCustomView private constructor(
        context: Context,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : View(context, attrs, defStyleAttr, defStyleRes) {
    
        // Приватный конструктор для принудительного использования фабричных методов
    
        companion object {
            fun createDefault(context: Context): MyCustomView {
                // Логика инициализации для конструктора по умолчанию
                return MyCustomView(context, null, 0, 0)
            }
    
            fun createFromAttrs(context: Context, attrs: AttributeSet?): MyCustomView {
                // Логика инициализации с атрибутами
                return MyCustomView(context, attrs, 0, 0)
            }
    
            // Дополнительные фабричные методы для других комбинаций конструкторов
        }
    }
    
  • Builder pattern: Полезен, когда конструкторов много или они имеют множество опциональных параметров. Позволяет пошагово создавать объект представления.

    class MyCustomView private constructor(
        private val context: Context,
        private val attrs: AttributeSet?,
        private val defStyleAttr: Int,
        private val defStyleRes: Int
    ) : View(context, attrs, defStyleAttr, defStyleRes) {
    
        // Приватный конструктор
    
        class Builder(private val context: Context) {
            private var attrs: AttributeSet? = null
            private var defStyleAttr: Int = 0
            private var defStyleRes: Int = 0
    
            fun setAttrs(attrs: AttributeSet?) = apply { this.attrs = attrs }
            fun setDefStyleAttr(defStyleAttr: Int) = apply { this.defStyleAttr = defStyleAttr }
            fun setDefStyleRes(defStyleRes: Int) = apply { this.defStyleRes = defStyleRes }
    
            fun build(): MyCustomView {
                // Логика создания и инициализации представления на основе параметров
                return MyCustomView(context, attrs, defStyleAttr, defStyleRes)
            }
        }
    }
    
    // Использование Builder
    val myView = MyCustomView.Builder(context)
        .setAttrs(attrs)
        .build()
    

Выбор между фабричным методом и builder pattern зависит от сложности инициализации представления. Для более простых случаев достаточно фабричных методов. Для сложных с множеством опций предпочтительнее builder.