我应该摆脱大开关外壳吗?

发布于 2025-02-13 15:17:33 字数 1547 浏览 0 评论 0原文

我有一个工厂,其中包括许多HTML属性生成器,该生成器根据属性的类型返回其中一个,因此我想看看是否有更好的方法。

class AttributeHtmlGeneratorFactory {
    fun create(property: String): AttributeHtmlGenerator {
        when (property) {
            "animation" -> {
                return AnimationHtmlGenerator()
            }
            ...
            "left", "top" -> {
                return PositionHtmlGenerator()
            }
            ...
            "scaleX" , "scaleY", ... , "direction" -> {
                return UnusedAttributesHtmlGenerator()
            }

当开关中有20个开关案例时。

这是所有这些类都使用的界面

interface AttributeHtmlGenerator {
    fun generateHtml(member: KProperty1<HtmlComponentDataModel, *>, component: HtmlComponentDataModel ): String
}

,这是我在哪里以及如何使用所有这些界面:

        var result = ""

        HtmlComponentDataModel::class.memberProperties.forEach { member ->
            val generator = AttributeHtmlGeneratorFactory().create(member.name)
            result = result.plus(generator.generateHtml(member, component))
        }

        return result

此外,这是界面的简单实现:

class ButtonFillHtmlGenerator : AttributeHtmlGenerator {
    override fun generateHtml(member: KProperty1<HtmlComponentDataModel, *>, component: HtmlComponentDataModel): String {
        var result = ""

        member.get(component)?.let {
            result = result.plus("background-color:${it};")
        }

        return result
    }
}

无论如何是否有可以使情况变得更好?

I have a factory which includes many HTML attribute generators which returns one of them based on the type of attribute, so I wanted to see if there is a better way of doing this.

class AttributeHtmlGeneratorFactory {
    fun create(property: String): AttributeHtmlGenerator {
        when (property) {
            "animation" -> {
                return AnimationHtmlGenerator()
            }
            ...
            "left", "top" -> {
                return PositionHtmlGenerator()
            }
            ...
            "scaleX" , "scaleY", ... , "direction" -> {
                return UnusedAttributesHtmlGenerator()
            }

this when switch has like 20 switch cases in it.

this is the interface which all these classes are using

interface AttributeHtmlGenerator {
    fun generateHtml(member: KProperty1<HtmlComponentDataModel, *>, component: HtmlComponentDataModel ): String
}

and this is where and how I'm using all of these:

        var result = ""

        HtmlComponentDataModel::class.memberProperties.forEach { member ->
            val generator = AttributeHtmlGeneratorFactory().create(member.name)
            result = result.plus(generator.generateHtml(member, component))
        }

        return result

also, this is a simple implementation of the interface:

class ButtonFillHtmlGenerator : AttributeHtmlGenerator {
    override fun generateHtml(member: KProperty1<HtmlComponentDataModel, *>, component: HtmlComponentDataModel): String {
        var result = ""

        member.get(component)?.let {
            result = result.plus("background-color:${it};")
        }

        return result
    }
}

is there anyway to make this better?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

憧憬巴黎街头的黎明 2025-02-20 15:17:35

如果您只想重新格式化何时陈述,我建议您喜欢这样做:

fun create(property: String): AttributeHtmlGenerator = when (property)
{
    "animation" -> AnimationHtmlGenerator()
    "left", "top" -> PositionHtmlGenerator()
    "scaleX", "scaleY", "direction" -> UnusedAttributesHtmlGenerator()
    else -> error("No generator found for property $property")
}

如果要跨模块划分此逻辑,则使用 map

class AttributeHtmlGeneratorFactory {
    private val generatorMap = mutableMapOf<String, () -> AttributeHtmlGenerator>()

    init {
        assignGeneratorToProperties("animation") { AnimationHtmlGenerator() }
        assignGeneratorToProperties("left", "top") { PositionHtmlGenerator() }
    }

    fun create(property: String): AttributeHtmlGenerator {
        return generatorMap[property]?.invoke() ?: error("No generator found for property $property")
    }

    fun assignGeneratorToProperties(vararg properties: String, provider: () -> AttributeHtmlGenerator) {
        properties.forEach {
            generatorMap[it] = provider
        }
    }
}

这样,您可以在代码的一部分中调用godegeneratortoperties,从而将初始化逻辑分开。

在性能方面,当您有几种情况时,/if-else语句确实是表现的,但哈希图的表现要优于许多元素。您可以根据案件决定使用什么。

If you just want to reformat the when statement, I suggest you you do like this:

fun create(property: String): AttributeHtmlGenerator = when (property)
{
    "animation" -> AnimationHtmlGenerator()
    "left", "top" -> PositionHtmlGenerator()
    "scaleX", "scaleY", "direction" -> UnusedAttributesHtmlGenerator()
    else -> error("No generator found for property $property")
}

If you want to split this logic across modules, you would use a Map.

class AttributeHtmlGeneratorFactory {
    private val generatorMap = mutableMapOf<String, () -> AttributeHtmlGenerator>()

    init {
        assignGeneratorToProperties("animation") { AnimationHtmlGenerator() }
        assignGeneratorToProperties("left", "top") { PositionHtmlGenerator() }
    }

    fun create(property: String): AttributeHtmlGenerator {
        return generatorMap[property]?.invoke() ?: error("No generator found for property $property")
    }

    fun assignGeneratorToProperties(vararg properties: String, provider: () -> AttributeHtmlGenerator) {
        properties.forEach {
            generatorMap[it] = provider
        }
    }
}

This way you can call assignGeneratorToProperties in parts of the code and thus split the initialization logic.

Performance-wise, when/if-else statements are really performant when you have a few cases but a HashMap outperforms them for a lot of elements. You decide what to use depending on your case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文