文/杨加康,CFUG 街道社区核心成员,《Flutter 合作开发之旅柘溪》译者,华为技师在紧紧围绕设计商业模式的热门话题中,厂房那个词频密出现,从单纯厂房商业模式到厂房方式商业模式,再到抽象化厂房商业模式。厂房中文名称涵义是锻造产品的轻工业娱乐场所,应用领域在面向第一类中,理所当然的成为了较为众所周知的建立型商业模式。“从方式上讲,厂房能是两个回到他们想第一类的两个方式/表达式,即能作为缺省的一类抽象化。”责任编辑,就带我们采用 Dart 认知它的各别的同时实现,以及它之间的亲密关系。单纯厂房& factory URL单纯厂房商业模式无此23种 GoF 设计商业模式中,看似他们最常采用的一类程式设计方式。其中主要牵涉到两个特定的方式,专门针对用以提供他们想的示例对象(第一类厂房),他们能将那个方式放在两个原则上的类 SimpleFactory 中,如下表所示:classSimpleFactory{///厂房方式static Product createProduct(int type){if (type ==1){return ConcreteProduct1();}if (type ==2){return ConcreteProduct2();}return ConcreteProduct();}}他们认为该方式要建立的第一类同为两个 Product 类(tcsh),并通过模块 type 选定要建立具体内容的第一类类别。Dart 不全力支持 interface URL,但他们能采用 abstract 以tcsh的方式表述USB,接着各具体内容的类别承继同时实现它方可:///tcshabstractclassProduct{String? name;}///同时实现类classConcreteProductimplementsProduct{@overrideString? name =ConcreteProduct;}///同时实现类1classConcreteProduct1implementsProduct{@overrideString? name =ConcreteProduct1;}///同时实现类2classConcreteProduct2implementsProdu个第一类被优先选择的具体内容方法论:void main(){final Product product = SimpleFactory.createProduct(1);print(product.name);// ConcreteProduct1}这就是单纯厂房商业模式。说到这里,就不得已提及 Dart 中独有的 factory URL了。factory URL能用以润色 Dart 类的缺省,意为厂房构造表达式,它能让类 的缺省纯天然具有厂房的机能,采用方式如下表所示:classProduct{///厂房缺省(润色 create 缺省)factory Product.createFactory(int type){if (type ==1){return Product.product1;} elseif (type ==2){return Product.concrete2();}return Product.concrete();}///重新命名缺省 Product.concrete(): name =concrete;///重新命名缺省1 Product.concrete1(): name =concrete1;///重新命名缺省2 Product.concrete2(): name =concrete2;String name;}factory 润色的缺省需要回到两个现阶段类的第一类示例,他们能根据模块初始化相关联的缺省,回到相关联的第一类示例。void main(){ Product product = Product.createFactory(1);print(product.name);// concrete1}除此之外,厂房缺省也并不要求他们每天都要聚合捷伊第一类,他们也能在类中事先表述一些第一类供厂房缺省采用,这样每天在采用反之亦然的模块构筑第一类时,回到的会是同两个第一类,在单例商业模式[1]的章节中他们已经介绍过:classProduct{///厂房缺省factory Product.create(int type){if (type ==1){return product1;} elseif (type ==2){return product2();}return Product.concrete();}staticfinal Product product1= Product.concrete1();staticfinal Product product2= Product.concrete2();}factory 除了能润色重新命名缺省外,也能润色默认的非重新命名缺省,classProduct{factory Product(int type){return Product.concrete();}String? name;}到这里为止,厂房缺省的两个缺点已经凸显了出来,即采用者并不能直观的感觉到自己正在采用的是厂房表达式。厂房缺省的采用方式和普通缺省没有区别,但那个缺省生产的示例相当于是一类单例:void main(){ Product product = Product(1);print(product.name);// concrete1}这样的用法很容易造成采用者的困扰,因此,他们应当尽量采用特定的重新命名构造表达式作为厂房缺省(如上面示例中的 createFactory)。厂房方式商业模式厂房方式商业模式反之亦然也是他们程式设计中最常用到的一类手段。抽象化厂房 UML,图源:refactoring.guru在单纯厂房中,它主要服务的第一类是客户,而厂房方式的采用者与厂房本身的类并不相干,而厂房方式商业模式主要服务自身的父类,如下表所示的 ProductFactory(类比 UML 中的 Creator):///抽象化厂房abstractclassProductFactory{///抽象化厂房方式 Product factoryMethod();///业务代码void dosomthing(){ Product product = factoryMethod();print(product.name);}}在 ProductFactory 类中,厂房方式 factoryMethod 是抽象化方式,每个子类都要重写那个方式并返回相关联不同的 Product 第一类,在 dosomthing()方式被初始化时,就能根据回到的第一类做出不同的响应。具体内容采用方式如下表所示:///具体内容厂房classProductFactory1extendsProductFactory{///具体内容厂房方式1@override Product factoryMethod(){return ConcreteProduct1();}}classProductFactory2extendsProductFactory{///具体内容厂房方式2@override Product factoryMethod(){return ConcreteProduct2();}}///采用main(){ ProductFactory product = ProductFactory1(); product.dosomthing();// ConcreteProduct1}在 Flutter 中,抽象化方式有两个非常实用的应用领域场景。他们在采用 Flutter 合作开发多端应用领域时通常需要考虑到多平台的适配,即在多个平台中,反之亦然的操作有时会产生不同的结果/样式,他们能将这些不同结果/样式聚合的方法论放在厂房方式中。如下表所示,他们表述两个 DialogFacory,用作聚合不反之亦然式 Dialog 的厂房:abstractclassDialogFacory{ Widget createDialog(BuildContext context); Future show(BuildContext context) async {final dialog = createDialog(context);return showDialog( context: context, builder:(){return dialog;},);}}接着,针对 Android 和 iOS 两个平台,就能建立两个不反之亦然式的 Dialog 了:/// Android 平台classAndroidAlertDialogextendsDialogFactory{@override Widget createDialog(BuildContext context){return AlertDialog( title: Text(getTitle()), content: const Text(This is the material-style alert dialog!), actions:[ TextButton( onPressed:(){ Navigator.of(context).pop();}, child: const Text(Close),),],);}}/// iOS 平台classIOSAlertDialogextendsDialogFactory{@override Widget createDialog(BuildContext context){return CupertinoAlertDialog( title: Text(getTitle()), content: const Text(This is the cupertino-style alert dialog!), actions:[ CupertinoButton( onPressed:(){ Navigator.of(context).pop();}, child: const Text(Close),),],);}}现在,他们就能像这样采用相关联的 Dialog 了:Future showCustomDialog(BuildContext context) async {final dialog = AndroidAlertDialog();// final dialog = IOSAlertDialog();await selectedDialog.show(context);}抽象化厂房抽象化厂房商业模式,相较于单纯厂房和 厂房方式最大的不同是:这两种商业模式只生产一类第一类,而抽象化工厂生产的是一系列第一类(第一类族),而且聚合的这一系列第一类一定存在某种联系。比如 Apple 会生产手机、平板等多个产品,这些产品都属于 Apple 那个品牌。如下表所示面那个抽象化的厂房类:abstractclassElectronicProductFactory{ Product createComputer(); Product createMobile(); Product createPad();//…}对于 Apple 来说,我就是生产这类电子产品的厂房,于是能承继那个类,同时实现其中的方式生产各类产品:classAppleextendsElectronicProductFactory{@override Product createComputer(){return Mac();}@override Product createMobile(){return IPhone();}@override Product createPad(){return IPad();}//…}反之亦然地,对于华为、华为等电子产品厂商也能采用相同的方式表示,这就是抽象化厂房商业模式。在合作开发 Flutter 应用领域中,他们也能充分利用抽象化厂房商业模式做切合应用领域的适配,他们能表述如下表所示那个抽象化厂房,用于生产 widget:abstractclassIWidgetsFactory{ Widget createButton(BuildContext context); Widget createDialog(BuildContext context);//…}他们的应用领域通常需要针对各平台展示不同风格的 widget。因此针对每两个平台,他们都能同时实现相关联的同时实现厂房,如下表所示:/// Material 风格组件厂房classMaterialWidgetsFactoryextendsIWidgetsFactory{@override Widget createButton( BuildContext context, VoidCallback? onPressed, String text){return ElevatedButton( child: Text(text), onPressed: onPressed,);}@override Widget createDialog(BuildContext context, String title, String content){return AlertDialog(title: Text(title), content: Text(content));}///…}/// Cupertino 风格组件厂房classCupertinoWidgetsFactoryextendsIWidgetsFactory{@override Widget createButton( BuildContext context, VoidCallback? onPressed,String text,) {return CupertinoButton( child: Text(text), onPressed: onPressed,);}@override Widget createDialog(BuildContext context, String title, String content){return CupertinoAlertDialog( title: Text(title), content: Text(content),);}//…}这样,在 Android 平台上他们采用 MaterialWidgetsFactory,在 iOS 平台上采用 CupertinoWidgetsFactory,就能采用相关联平台的 widget,想适配更多平台只需要再承继 IWidgetsFactory 同时实现相关联平台的厂房类方可。至此,他们能发现,作为建立型商业模式,这三类厂房商业模式主要工作就是以不同的方式建立第一类,但他们各有特点:单纯厂房商业模式抽象化的是生产第一类,厂房方式商业模式抽象化的是类方式,厂房方式商业模式抽象化的则是生产第一类的厂房,如何采用就见仁见智了。拓展阅读百度百科:厂房方式商业模式[2]百度百科:抽象化厂房商业模式[3]Mangirdas Kazlauskas:Flutter Design Patterns: Abstract Factory[4]关于本系列文章Flutter / Dart 设计商业模式柘溪(简称 Flutter 设计商业模式)系列内容预计两周发布一篇,着重向合作开发者介绍 Flutter 应用领域合作开发中常见的设计商业模式以及合作开发方式,旨在推进 Flutter / Dart 语言特性的普及,以及帮助合作开发者更高效地合作开发出高质量、可维护的例商业模式: https://flutter.cn/community/tutorials/singleton-pattern-in-flutter-n-dart[2]百度百科:厂房方式商业模式: http://baike.baidu.com/l/JAsmKIAk[3]百度百科:抽象化厂房商业模式: http://baike.baidu.com/l/j5yzRvW[4] Mangirdas Kazlauskas:Flutter Design Patterns: Abstract Factory: https://medium.com/flutter-community/flutter-design-patterns-11-abstract-factory-7098112925d8