【问题标题】:Is it a good idea to use Factory constructors extensively?广泛使用工厂构造函数是个好主意吗?
【发布时间】:2020-04-17 10:04:00
【问题描述】:

我的问题是关于在处理相对复杂的不可变对象时如何正确使用工厂构造函数。假设我想返回一个更改了某些属性的类的实例。

示例

@immutable
class SomeObject {
  final int id;
  final String name;
  final int upvote;
  final int downvote;
  final int favorite;

  SomeObject({this.id, this.name, this.upvote, this.downvote, this.favorite});

  factory SomeObject.upvoted() {
    return SomeObject(
      upvote: this.upvote + 1 // apparently can't use this keyword here, wrong syntax
    );
  }
  SomeObject.upvoted(SomeObject ref) {
    id = ref.id;
    // cant change an immutable type
  }

  SomeObject upvoted() {
    return SomeObject(
      upvote: upvote + 1,
      //... other properties are null, bad idea?
    );
  }

  SomeObject upvotedWithDefaultConstructorUsingReference(SomeObject ref) {
    // works but seems like an overkill, especially considering more number of properties
    return SomeObject(
      id: ref.id,
      name: ref.name,
      upvote: upvote + 1,
      downvote: ref.downvote,
      favorite: ref.downvote
    );
  }
}

SomeObject.upvoted() 将是同一类的一个实例,但它的 upvoted 属性比引用的属性多 +1。还会有更多类似 downvoted()、withNameChanged() 或 copyWith()。

前 2 个是构造函数,其他只是返回 SomeObject 类实例的方法。这里应该采用什么方法?当类不可变时如何使用工厂构造函数?我也不确定这 4 个例子的区别。

我已经阅读了this 问题的答案,但它似乎没有回答我的问题。

【问题讨论】:

    标签: oop flutter dart constructor


    【解决方案1】:

    看起来你想要一个copyWith 类型模式:

    class SomeObject {
      final int id;
      final String name;
      final int upVote;
      final int downVote;
      final int favorite;
    
      SomeObject({this.id, this.name, this.upVote, this.downVote, this.favorite});
    
      SomeObject copyWith({
        int id,
        String name,
        int upVote,
        int downVote,
        int favorite,
      }) {
        return SomeObject(
          id: id ?? this.id,
          name: name ?? this.name,
          upVote: upVote ?? this.upVote,
          downVote: downVote ?? this.downVote,
          favorite: favorite ?? this.favorite,
        );
      }
    }
    

    您可以以任何您喜欢的方式进行调整:upVoted 复制,upVote 递增,其余部分保持不变,或允许更改。

      SomeObject upVoted() {
        return SomeObject(
          id: id, // no need for 'this' here
          name: name,
          upVote: upVote + 1,
          downVote: downVote,
          favorite: favorite,
        );
      }
    

    将两者结合起来,您可以想出无穷无尽的变化:

      SomeObject upVoted() => copyWith(upVote: upVote + 1);
      SomeObject downVoted() => copyWith(downVote: downVote + 1);
      SomeObject upVoteRetracted() => copyWith(upVote: upVote - 1);
    

    ... 这让你开始怀疑为什么这个类是不可变的。让它保持和改变它的状态似乎更有意义,而不是制作具有不同值的多个副本。

    【讨论】:

    • 是的,copyWith() 类型的方法对于 Flutter 小部件也非常常见。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 2013-09-16
    • 2015-06-04
    • 2011-04-05
    • 1970-01-01
    相关资源
    最近更新 更多