JAVA SCRIPT设计模式--创建型设计模式之生成器

Posted 火柴盒zhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA SCRIPT设计模式--创建型设计模式之生成器相关的知识,希望对你有一定的参考价值。

         JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代表全部的正确,特此声明。若读者需要了解设原则、设计变化方向,环境相关等信息请查看设计模式开篇

        所有JAVA SCRIPT设计模式快捷连接:

              创建型:(1)  抽象工厂 (2) 生成器 (3) 工厂方法 (4) 原型  (5) 单例

              结构型:(6) 适配器  (7) 桥接  (8) 组合 (9) 装饰 (10) 外观 (11) 享元 (12) 代理​

              行为型:(13) ​职责链 (14) ​命令 (15) ​解释器 (16) ​迭代器 (17) ​中介者 (18) ​备忘录 (119) ​观察者 (20) ​状态​ (21) ​策略 (22) ​模板方法 (23) 访问者​


一、UML类图

参与者:

1.1 Builder

  • 为创建一个Product对象的各个部件指定抽象接口。 

1.2 ConcreteBuilder

  • 实现Builder的接口以构造和装配该产品的各个部件。
  • 定义并明确它所创建的表示。
  •  提供一个检索产品的接口(例如,GetASCIIText和GetTextWidget)。

1.3 Director

  • 构造一个使用Builder接口的对象。 

1.4 Product

  • 表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。
  • 包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

1.5 交互图

二、意图

      将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

三、适用性

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。

四、示例代码一(推荐示例代码二)

4.1  动机

       一个RTF(Rich Text Format)文档交换格式的阅读器应能将RTF转换为多种正文格式。 该阅读器可以将RTF文档转换成普通ASCII文本或转换成一个能以交互方式编辑的正文窗口组 件。但问题在于可能转换的数目是无限的。因此要能够很容易实现新的转换的增加,同时却不改变RTF阅读器。

        一个解决办法是用一个可以将 RTF转换成另一种正文表示的 TextConverter对象配置这个RTFReader类。当RTFReader对RTF文档进行语法分析时,它使用TextConverter去做转换。无论何时RTFReader识别了一个RTF标记token(或是普通正文或是一个RTF控制字),它都发送一个请求给TextConverter去转换这个标记token。TextConverter对象负责进行数据转换以及用特定格式表示该标记,TextConverter objects are responsible both for performing the data conversion and for representing the token in a particular format.

         TextConvert的子类对不同转换和不同格式进行特殊处理。例如,一个ASCIIConverter只负责转换普通文本(representation one),而忽略其他转换请求。另一方面,一个TeXConverter将会为实现对所有请求的操作,以便生成一个获取正文中所有风格信息的TEX表示(representation two)。一个TextWidgetConverter将生成一个复杂的用户界面对象以便用户浏览和编辑正文(representation three)。

        每种转换器类将获取这种机制来创建和装配一个复杂对的对象,并把他放置到抽象接口之后。Each kind of converter class takes the mechanism for creating and assembling a complex object and puts it behind an abstract interface。转换器独立于阅读器,阅读器负责对一个RTF文档进行语法分析。The converter is separate from the reader, which is responsible for parsing an RTF document.

        Builder模式描述了所有这些关系。每一个转换器类在该模式中被称为生成器(builder),而阅读器则称为导向器(director)。本例子中,Builder模式将分析文本格式的算法(即RTF文档的语法分析程序)与描述怎样创建和表示一个转换后格式的算法分离开来(Applied to this example, the Builder pattern separates the algorithm for interpreting a textual format (that is, the parser for RTF documents) from how a converted format gets created and represented. )。这使我们可以重用RTFReader的语法分析算法,根据RTF文档创建不同的正文表示仅需使用不同的TextConverter的子类配置该RTFReader即可

 

4.2  示例UML

目录结构:

4.3 Builder(TextConverter)

  • 为创建一个Product对象的各个部件指定抽象接口。
export default  class TextConverter 
    constructor() 
    
    ConverCharacter(char)      
    
    ConverFontchage(Font)      
    
	ConverParagraph(Para) 
	
	
  

4.4 ConcreteBuilder(ASCIIConverter、TeXConverter)

  • 实现Builder的接口以构造和装配该产品的各个部件。
  • 定义并明确它所创建的表示。
  •  提供一个检索产品的接口(例如,GetASCIIText和GetTextWidget)。

  import   TextConverter   from '../TextConverter.js';
   import   ASSCIIText   from './Product/ASCIIText.js'; 
  
  export default class ASCLLConverter extends TextConverter 
	#asscillText;
    constructor() 
        super();
		this.#asscillText=new ASSCIIText();
    
    ConverCharacter(char) 
		this.#asscillText.SetTextDoc(char);
    
	GetASCLLText()
	
		return this.#asscillText;
	
  
 

import   TextConverter   from '../TextConverter.js';
import   TeXtext   from './Product/TeXtext.js'; 
  
  export default class TeXConverter extends TextConverter 
	#teXtext;
    constructor() 
        super();
		this.#teXtext=new TeXtext();
    
    ConverCharacter(char) 
		this.#teXtext.SetTextDoc(char);	 
    
	ConverFontchage(Font) 
		var fontFormatString='<font><size>'+ Font.size+'</size>...</font>\\n';
		this.#teXtext.SetTextDoc(fontFormatString);	 
	
	ConverParagraph(Para) 
		var paraFormatString='<Para><name>'+ Para.name+'</name>...</Para>\\n';
		this.#teXtext.SetTextDoc(paraFormatString);	
	
	
	GetTeXText()
	
		return this.#teXtext;
	
  
 

4.5 Director(RTFReader)

  • 构造一个使用Builder接口的对象。
import TextConverter  from './TextConverter/TextConverter.js';

  export default class RTFReader  
	#Reader=new TextConverter();  
    constructor(textConverter) 
        this.#Reader=textConverter
    
	Construct()
	
		//这里我们虚拟一个内存文档的结构对象
		let doc=[];
		let oneCharToken=
			type:'CHAR',
			Char:'test string 1\\n',
		;
		doc.push(oneCharToken);
		let oneFontToken=
			type:'Font',
			Font:
				size:'12',
				color:'red',
				fontFamily:'verdana'
			
		;
		doc.push(oneFontToken);
		let oneParaToken=
			type:'Para',
			Para:
				name:'abc.jpg',
				createTime:'20220919',
				BinaryContent:'101010101001',
			,
		;
		doc.push(oneParaToken);
		let anotheroneCharToken=
			type:'CHAR',
			Char:'test string 2\\n',
		;
		doc.push(anotheroneCharToken);
		for(let n=0;n<doc.length;n++)
		
			let t=doc[n];
			if(t.type=='CHAR')
			this.#Reader.ConverCharacter(t.Char);
			else if(t.type=='Font')
			this.#Reader.ConverFontchage(t.Font);
			else if(t.type=='Para')
			this.#Reader.ConverParagraph(t.Para);
		
		
	
  
 

4.6 Product(ASCIIText、TeXText)

  • 表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。
  • 包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
export default  class ASSCIIText 
    #textDoc="";
	constructor(char) 
		 
    
	SetTextDoc(char)
	

		this.#textDoc=this.#textDoc+char;
	
	GetASSCIIText()
	
		return this.#textDoc;
	
  
export default  class TeXtext 
    #teXtext="";
	constructor(char) 
		 
    
	SetTextDoc(char)
	
	 
		this.#teXtext=this.#teXtext+char;
	
	
	GetTeXtext()
	
		return this.#teXtext;
	
  

4.7 Client 

import ASCLLConverter from './TextConverter/impl/ASCIIConverter.js';
import TeXConverter from './TextConverter/impl/TeXConverter.js';
import TextConverter from './TextConverter/TextConverter.js';

import RTFReader from './RTFReader.js';
 
 
export default class Client
    main()
		let textConverter=new ASCLLConverter();
		let textreader=new RTFReader(textConverter);
	    textreader.Construct();
		let asscillText=textConverter.GetASCLLText();
		console.log('-----------ASCLLConverter------------------------');
		console.log(asscillText.GetASSCIIText());
		
		console.log('------------TeXConverter-------------------------');
		let teXConverter=new TeXConverter();
		let teXreader=new RTFReader(teXConverter);
		teXreader.Construct();
		let teXText=teXConverter.GetTeXText();
		console.log(teXText.GetTeXtext());
		 
		
     
 

 

4.8 测试html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
 
 
 <script  type="module" >
 import Client  from './Client.js'; 
 
let cl=new Client();
cl.main()

 </script>
</head>
<body>

    
</body>
</html>

测试结果:

-----------ASCLLConverter------------------------
test string 1
test string 2

------------TeXConverter-------------------------
test string 1
<font><size>12</size>...</font>
<Para><name>abc.jpg</name>...</Para>
test string 2

 五、示例代码二

5.1  示例UML

目录结构:

5.2 Builder(TextConverter)

  export default class Builder 
	 
    constructor() 
    
    
	buildPartA()
		 
	
	
	buildPartB()
		 
	
	
	 
	getResult()
	
		 //return ComplexObject 
	
  
  
	 

5.3 ConcreteBuilder(Builder1 )

  
import   Builder   from '../Builder.js';
import   ComplexObject   from '../../Product/ComplexObject.js';
import   ProductA1   from '../../Product/impl/ProductA1.js';
import   ProductB1   from '../../Product/impl/ProductB1.js';

  export default class Builder1 extends Builder 
	 #complexObject
    constructor() 
        super();
		this.#complexObject=new ComplexObject();
    
    
	buildPartA()
		 
		console.log("Builder1: Creating and assembling ProductA1.");
		this.#complexObject.add( new ProductA1());
	
	
	buildPartB()
		 
		console.log("Builder1: Creating and assembling ProductB1.");
		this.#complexObject.add( new ProductB1()); 
	
	
	 
	getResult()
	
		
		 return this.#complexObject ;
	
  
  

5.4 Director(RTFReader)

import Builder  from './Builder/Builder.js';
import ComplexObject   from './Product/ComplexObject.js';

  export default class Director  
	#builder;  
	#complexObject;  
    constructor(builder) 
        this.#builder=builder
    
	Construct()
	
		console.log("Director: Delegating constructing a complex object to a builder object." )
		this.#builder.buildPartA();
		this.#builder.buildPartB();
		this.#complexObject = this.#builder.getResult();
		return "Hello World from " + this.#complexObject.getParts() + " objects!";
	
  
 

5.5 Product

export default  class Product 
    constructor() 
    
	getName()
		
	
  

5.6 ConcreteProduct


  import   Product   from '../Product.js'; 
  
  export default class ProductA1 extends Product 
	 
    constructor() 
        super();
    
	getName()
		return " ProductA1";
	
     
  
 

  import   Product   from '../Product.js'; 
  
  export default class ProductB1 extends Product 
	 
    constructor() 
        super();
    
	getName()
		return " ProductB1";
	
     
  
 

5.7 Client 

import Builder1 from './Builder/impl/Builder1.js';
import Director from './Director.js'; 


export default class Client
    main()
		// Creating a Director object
		 // and configuring it with a Builder1 object.
		  let director = new Director(new Builder1());
		  // Calling construct on the director.
		 console.log(director.Construct());
 
		 
     
 

 

5.8测试HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
 
 
 <script  type="module" >
 import Client  from './Client.js'; 
 
let cl=new Client();
cl.main()

 </script>
</head>
<body>

    
</body>
</html>

测试结果:

Director.js:12 Director: Delegating constructing a complex object to a builder object.
Builder1.js:16 Builder1: Creating and assembling ProductA1.
Builder1.js:22 Builder1: Creating and assembling ProductB1.
Client.js:11 Hello World from Complex Objetct made up of ProductA1 ProductB1 objects!

六、源代码下载

        下载链接:https://pan.baidu.com/s/1XuPqp84cccBNVkbnMY3sKw 
         提取码:q2ut

以上是关于JAVA SCRIPT设计模式--创建型设计模式之生成器的主要内容,如果未能解决你的问题,请参考以下文章

JAVA SCRIPT设计模式--行为型--设计模式之Strategy策略模式(21)

JAVA SCRIPT设计模式--行为型--设计模式之Command命令模式(14)

JAVA SCRIPT设计模式--行为型--设计模式之Strategy策略模式(21)

JAVA SCRIPT设计模式--行为型--设计模式之Iterator迭代器模式(16)

JAVA SCRIPT设计模式--行为型--设计模式之Responsibility职责链模式(13)

JAVA SCRIPT设计模式--行为型--设计模式之State状态者模式(20)