设计模式四builder模式:边学边做个生成电子书的工具(python+dart)

139 阅读3分钟

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。 何时使用:一些基本部件不会变,而其组合经常变化的时候。 如何解决:将变与不变分离开。

根据我们的项目 按 有封面的书籍和没有封面的书籍两种情况来构建

python实现:


class Builder():
    """建造流程:封面 isbn"""
    def __init__(self):
        self.frontCover = None
        self.isbn = None

    def run(self):
        print('封面: %s | ISBN: %s' % (self.frontCover, self.isbn))


class BookWithFrontCover(Builder):
    """方案A,有封面"""
    def get_front_cover(self):
        self.frontCover = "封面"

    def get_isbn(self):
        self.isbn = "493589040405"


class BookWithoutFrontCover(Builder):
    """方案B,没有封面"""
    def get_front_cover(self):
        self.frontCover = None

    def get_isbn(self):
        self.isbn = None

#指挥者:请求组装,并返回成品
class Director:
    """调度:"""
    def __init__(self):
        self.programme = None

    def build(self):
        self.programme.get_front_cover()
        print("封面:{}".format(self.programme.frontCover))
        self.programme.get_isbn()
        print("isbn:{}".format(self.programme.isbn))
        self.programme.run()


if __name__ == '__main__':
    # 没有封面的书籍builder
    test = Director()
    test.programme = BookWithoutFrontCover()
    test.build()

    # 带有封面的书籍builder
    test = Director()
    test.programme = BookWithFrontCover()
    test.build()

执行结果截图:

image.png

dart实现(本文中没有按生成电子书的实现,收录了 经典的builder 模式,使用dart语言) :

/**
建造者模式(Builder Pattern)

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
何时使用:一些基本部件不会变,而其组合经常变化的时候。
如何解决:将变与不变分离开。
*/
main(List<String> args) {
  MealBuilder mealBuilder = new MealBuilder();

  Meal vegMeal = mealBuilder.prepareVegMeal();
  print("Veg Meal");
  vegMeal.showItems();
  print("Total Cost: ${vegMeal.getCost()}");

  Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
  print("\n\nNon-Veg Meal");
  nonVegMeal.showItems();
  print("Total Cost: ${nonVegMeal.getCost()}");
}

//////////////////////////////////////////////////////////////////

///
/// 创建一个表示 食物条目 的接口
///
abstract class Item {
  String name();
  Packing packing();
  double price();
}

///
/// 创建一个表示 食物包装 的接口
///
abstract class Packing {
  String pack();
}

///
/// 创建实现 Packing 接口的实体类
///
class Wrapper implements Packing {
  @override
  String pack() {
    return "Wrapper";
  }
}

class Bottle implements Packing {
  @override
  String pack() {
    return "Bottle";
  }
}

///
/// 创建实现 Item 接口的抽象类,该类提供了默认的功能
///
abstract class Burger implements Item {
  @override
  Packing packing() {
    return new Wrapper();
  }

  @override
  double price();
}

abstract class ColdDrink implements Item {
  @override
  Packing packing() {
    return new Bottle();
  }

  @override
  double price();
}

///
/// 创建扩展了 Burger 和 ColdDrink 的实体类
///
class VegBurger extends Burger {
  @override
  double price() {
    return 25.0;
  }

  @override
  String name() {
    return "Veg Burger";
  }
}

class ChickenBurger extends Burger {
  @override
  double price() {
    return 50.5;
  }

  @override
  String name() {
    return "Chicken Burger";
  }
}

class Coke extends ColdDrink {
  @override
  double price() {
    return 30.0;
  }

  @override
  String name() {
    return "Coke";
  }
}

class Pepsi extends ColdDrink {
  @override
  double price() {
    return 35.0;
  }

  @override
  String name() {
    return "Pepsi";
  }
}

///
/// 创建一个 Meal 类,带有上面定义的 Item 对象
///
class Meal {
  List<Item> _items = <Item>[];

  void addItem(Item item) {
    _items.add(item);
  }

  double getCost() {
    double cost = 0.0;
    for (Item item in _items) {
      cost += item.price();
    }
    return cost;
  }

  void showItems() {
    for (Item item in _items) {
      print("Item : ${item.name()}");
      print(", Packing : ${item.packing().pack()}");
      print(", Price : ${item.price()}");
    }
  }
}

///
/// 创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象
///
class MealBuilder {
  Meal prepareVegMeal() {
    Meal meal = new Meal();
    meal.addItem(new VegBurger());
    meal.addItem(new Coke());
    return meal;
  }

  Meal prepareNonVegMeal() {
    Meal meal = new Meal();
    meal.addItem(new ChickenBurger());
    meal.addItem(new Pepsi());
    return meal;
  }
}