likes
comments
collection
share

Flutter设计模式(二)-Builder Pattern

作者站长头像
站长
· 阅读数 4

builder pattern(创建者模式)适用场景如下: 将复杂对象的组件实现与组件组合逻辑相互分离,允许用户创建不同组合逻辑,搭配不同产品风格

模式结构

主要由3个主要部分组成

Flutter设计模式(二)-Builder Pattern

  • 1,Director:主要通过builder函数来获取Product
  • 2,Product:通常是一个需要创建的复杂的对象。
  • 3,builder:创建器,通过一系列步骤,一步一步的创建所需要的对象。

PageRouteBuilder

flutter中,有多种创建器,例如自定义转场动画中,我们常用的PageRouteBuilder,用来创建Route对象

PageRouteBuilder({
  RouteSettings? settings,
  required this.pageBuilder,
  this.transitionsBuilder = _defaultTransitionsBuilder,
  this.transitionDuration = const Duration(milliseconds: 300),
  this.reverseTransitionDuration = const Duration(milliseconds: 300),
  this.opaque = true,
  this.barrierDismissible = false,
  this.barrierColor,
  this.barrierLabel,
  this.maintainState = true,
  bool fullscreenDialog = false,
})

在实际应用中,可以配合transitionsBuilder自定义转场动画

static Route route() {
  return PageRouteBuilder(
      reverseTransitionDuration: const Duration(milliseconds: 500),
      transitionDuration: const Duration(milliseconds: 500),
      opaque: false,
      pageBuilder: (context, animate, secondaryAnimation) {
        return const BuilderPatternPage();
      },
      transitionsBuilder: (context, animated, secondAnimated, widget) =>
          ScaleTransition(
            alignment: Alignment.bottomCenter,
            filterQuality: FilterQuality.high,
            scale: Tween<double>(begin: 0, end: 1).animate(animated),
            child: widget,
          ));
}

示例代码

接下来,我们通过创建一个hamburger builder,来展示这种设计模式:

Product

Ingredient是一个抽象类,用来定义汉堡的基础配料。

abstract class Ingredient {
  /// 过敏原
  @protected
  List<String>? allergens;
  
  /// 名字
  @protected
  String? name;

  List<String>? getAllergens() {
    return allergens;
  }

  String? getName() {
    return name;
  }
}

然后创建具体的Ingredient类: BigMacBun、RegularBun、BeefPatty、McChickenPatty、BigMacSauce 等来代表莫一种具体的配料。

/// 巨无霸面包
class BigMacBun extends Ingredient {
  BigMacBun() {
    name = 'Big Mac Run';
    allergens = ['Wheat'];
  }
}

/// 常规面包
class RegularBun extends Ingredient {
  RegularBun() {
    name = "Regular Bun";
    allergens = ['Wheat'];
  }
}

/// 牛肉饼
class BeefPatty extends Ingredient {
  BeefPatty() {
    name = 'Beef Patty';
    allergens = [];
  }
}

class McChickenPatty extends Ingredient {
  McChickenPatty() {
    name = 'McChicken Patty';
    allergens = ['Wheat', 'Cooked in the same fryer that we use...'];
  }
}

/// 巨无霸酱
class BigMacSauce extends Ingredient {
  BigMacSauce() {
    name = 'Big Mac Sauce';
    allergens = ['Egg', 'Soy', 'Wheat'];
  }
}

/// 番茄酱
class Ketchup extends Ingredient {
  Ketchup() {
    name = 'Ketchup';
    allergens = [];
  }
}

/// 蛋黄酱
class Mayonnaise extends Ingredient {
  Mayonnaise() {
    name = 'Mayonnaise';
    allergens = ['egg'];
  }
}

/// 芥末
class Mustard extends Ingredient {
  Mustard() {
    name = 'Mustard';
    allergens = [];
  }
}

/// 洋葱
class Onion extends Ingredient {
  Onion() {
    name = 'Onion';
    allergens = [];
  }
}

/// 奶油
class Cheese extends Ingredient {
  Cheese() {
    name = 'Cheese';
    allergens = ['Milk', 'Soy'];
  }
}

/// 烧烤调味料
class GrillSeasoning extends Ingredient {
  GrillSeasoning() {
    name = 'Grill Seasoning';
    allergens = [];
  }
}

/// 泡菜片
class PickleSlices extends Ingredient {
  PickleSlices() {
    name = 'Pickle Slices';
    allergens = [];
  }
}

/// 生菜丝
class ShreddedLettuce extends Ingredient {
  ShreddedLettuce() {
    name = 'Shredded Lettuce';
    allergens = [];
  }
}

Burger是一个普通的类,用来表示创建器创建的产品

/// Burger
class Burger {
  final List<Ingredient> _ingredients = [];
  double? _price;

  /// 添加配料
  void addIngredient(Ingredient ingredient) {
    _ingredients.add(ingredient);
  }

  /// 获取所有配料
  String getFormattedIngredients() {
    return _ingredients.map((e) => e.getName()).join('.');
  }

  /// 获取所有的过敏原
  String getFormattedAllergens() {
    var allergens = <String>{};
    for (var element in _ingredients) {
      allergens.addAll(element.getAllergens() ?? []);
    }
    return allergens.join('.');
  }

  /// 价格
  String getFormattedPrice() {
    return '$${_price?.toStringAsFixed(2)}';
  }

  void setPrice(double? price) {
    _price = price;
  }
}

Builder

BurgerBuilderBase 是一个抽象类,存储 burger 和 price属性。提供了创建,获取和设置burger价格的默认方法。 同时,也定义了一些抽象方法,需要由具体的生成器来实现这些方法

abstract class BurgerBuilderBase {
  @protected
  Burger? burger;

  @protected
  double? price;

  void createBurger() {
    burger = Burger();
  }

  Burger? getBurger() {
    return burger;
  }

  void setBurgerPrice() {
    burger?.setPrice(price);
  }

  void addBuns();
  void addCheese();
  void addPatties();
  void addSauces();
  void addSeasoning();
  void addVegetables();
}

创建两个具体的Builder,来创建不同类型的产品

class CheeseburgerBuilder extends BurgerBuilderBase {
    ......
}


class BigMacBuilder extends BurgerBuilderBase {
    ......
}

Director

使用BuyerMaker来管理产品的构建过程并返回构建结果。

class BurgerMaker {
  BurgerBuilderBase? burgerBuilder;
  BurgerMaker(this.burgerBuilder);

  void changeBurgerBuilder(BurgerBuilderBase burgerBuilder) {
    this.burgerBuilder = burgerBuilder;
  }

  Burger? getBurger() {
    return burgerBuilder?.getBurger();
  }

  void prepareBurger() {
    burgerBuilder?.createBurger();
    burgerBuilder?.setBurgerPrice();

    burgerBuilder?.addBuns();
    burgerBuilder?.addCheese();
    burgerBuilder?.addPatties();
    burgerBuilder?.addSauces();
    burgerBuilder?.addSeasoning();
    burgerBuilder?.addVegetables();
  }
}

整体的结构如图所示

Flutter设计模式(二)-Builder Pattern

通过 prepareBurger()getBurger方法我们就可以得到相对应的产品

通过切换不同的创建器我们可以得到不同类型的产品

Flutter设计模式(二)-Builder Pattern Flutter设计模式(二)-Builder Pattern

代码我已上传至Gitlab,可以自行下载本文的示例代码 flutter_design_patterns

如果觉得有收获请按如下方式给个 爱心三连:👍:点个赞鼓励一下。🌟:收藏文章,方便回看哦!。💬:评论交流,互相进步!