当前位置: 首页 > news >正文

网站开发模板做个网页大概多少钱

网站开发模板,做个网页大概多少钱,网站网络推广策略和电子商务,如何做网站信息文章目录 生成器模式生成器代码生成 本文用生成器模式作为例子#xff0c;来演示如何用代码生成代码。 生成器模式 熟悉 Java 开发的同学都知道#xff0c;lombok 有一个著名的注解 Builder #xff0c;只要加在类上面#xff0c;就可以自动生成 Builder 模式的代码。如下… 文章目录 生成器模式生成器代码生成 本文用生成器模式作为例子来演示如何用代码生成代码。 生成器模式 熟悉 Java 开发的同学都知道lombok 有一个著名的注解 Builder 只要加在类上面就可以自动生成 Builder 模式的代码。如下所示 Builder public class DetectionQuery {private String uniqueKey;private Long startTime;private Long endTime; }然后就可以这样使用 return DetectionQuery.builder().uniqueKey(uniqueKey).startTime(startTime).endTime(endTime).build();是不是很爽 不过 Go 可没有这样好用的注解。Go 你得自己手写。假设我们要造一辆车车有车身、引擎、座位、轮子。Go 的生成器模式的代码是这样子的 package modelimport fmttype ChinaCar struct {Body stringEngine stringSeats []stringWheels []string }func newChinaCar(body string, engine string, seats []string, wheels []string) *ChinaCar {return ChinaCar{Body: body,Engine: engine,Seats: seats,Wheels: wheels,} }type CarBuilder struct {body stringengine stringseats []stringwheels []string }func ChinaCharBuilder() *CarBuilder {return CarBuilder{} }func (b *CarBuilder) Build() *ChinaCar {return newChinaCar(b.body, b.engine, b.seats, b.wheels) }func (b *CarBuilder) Body(body string) *CarBuilder {b.body bodyreturn b }func (b *CarBuilder) Engine(engine string) *CarBuilder {b.engine enginereturn b }func (b *CarBuilder) Seats(seats []string) *CarBuilder {b.seats seatsreturn b }func (b *CarBuilder) Wheels(wheels []string) *CarBuilder {b.wheels wheelsreturn b }func main() {car : ChinaCharBuilder().Body(More advanced).Engine(Progressed).Seats([]string{good, nice}).Wheels([]string{solid, smooth}).Build()fmt.Printf(%v, car) }生成器模式怎么写遵循三步即可 1 先构造一个对应的生成器这个生成器与目标对象有一样的属性 2 对于每一个属性有一个方法设置属性然后返回生成器的引用本身 3 最后调用生成器的 Build 方法这个方法会调用目标对象的构造器来生成目标对象。 为啥不直接调用目标对象的构造器要这么拐弯抹角呢因为生成器模式一般用于复杂对象的构造。这个复杂对象的每一个组件都需要逐步构造比如每一个Set方法中可能都有一些对于属性的校验或者其他业务逻辑而不是简单的给属性赋值就行。必须等所有组件都正确构造完成后才能返回一个可用的目标对象。像 CarBuilder 这种才算是生成器模式的合理使用。而 DetectionQuery 的 builder 模式只是为了享受链式调用的畅感。 生成器代码生成 用代码生成代码嗯其实不算稀奇。代码也只是一种普通的可读文本而已。 模板是用于动态生成文本的常用技术。虽然看上去不算特别高明的方式但也很管用。咱们使用 Go template 来实现它。 思路与实现 首先要分析哪些是固定的文本哪些是动态的文本。 红框框出来的都是动态文本。事实上除了几个关键字和括号是静态的以外其它基本都是动态生成的。这些文本通常是根据业务对象类型和业务对象的属性名及属性类型来推理出来的。 先根据最终要生成的代码把模板文件给定义出来这里可以用自然语言先填充再替换成技术实现 func New{{ 目标对象类型 }}(逗号分隔的属性名 属性类型列表)) *{{ 目标对象类型 }} {return {{ 目标对象类型 }}{每一行都是 属性名 属性名 属性名小写} }type {{ 生成器类型 }} struct {每一行都是 属性名 属性类型属性名小写 }func {{ 生成器方法名 }}() *{{ 生成器类型 }} {return {{ 生成器类型 }}{} }func (b *{{ 生成器类型 }}) Build() *{{ 目标对象类型 }} {return New{{ 目标对象类型 }}(逗号分隔的 b.属性名 列表 }// 对于每一个属性遍历做如下动作func (b *{{ 生成器类型 }}) {{ 属性名 }}({{ 属性名小写 }} {{ 属性类型 }}) *{{ 生成器类型 }} {b.{{ 属性名小写 }} {{ 属性名小写 }}return b }然后抽象出用来填充动态文本的填充对象即要传给模版的参数对象存储了在模板中需要用的动态信息 type BuilderInfo struct {BuilderMethod stringBuilderClass stringBizClass stringAttrs []Attr }type Attr struct {Name stringType string }func newAttr(Name, Type string) Attr {return Attr{Name: Name, Type: Type} }接下来要根据具体的模板语言来填充上面的自然语言同时从目标对象中生成填充对象来填充这些动态文本和自定义函数。 如下代码所示 builder_tpl 就是生成器模式的代码模板文本。我们先用具体的值填充把模板调通然后再把这些具体的值用函数替换。 func LowercaseFirst(s string) string {r, n : utf8.DecodeRuneInString(s)return string(unicode.ToLower(r)) s[n:] }func MapName(attrs []Attr) []string {return util.Map[Attr, string](attrs, func(attr Attr Attr, string) string { return b. LowercaseFirst(attr.Name) }) }func MapNameAndType(attrs []Attr) []string {return util.Map[Attr, string](attrs, func(attr Attr Attr, string) string { return LowercaseFirst(attr.Name) LowercaseFirst(attr.Type) }) }func autoGenBuilder(builder_tpl string) {t1 : template.Must(template.New(test).Funcs(template.FuncMap{lowercaseFirst: LowercaseFirst, join: strings.Join, mapName: MapName, mapNameAndType: MapNameAndType,}).Parse(builder_tpl))bi : BuilderInfo{BuilderMethod: QueryBuilder,BuilderClass: CarBuilder,BizClass: ChinaCar,Attrs: []Attr{newAttr(Body, string), newAttr(Engine, string),newAttr(Seats, []string), newAttr(Wheels, []string)},}t1.ExecuteTemplate(os.Stdout, test, bi) }func main() {builder_tpl : func New{{ .BizClass }}({{- join (mapNameAndType .Attrs) , }})) *{{ .BizClass }} {return {{ .BizClass }}{{{ range .Attrs }}{{ .Name }}: {{ lowercaseFirst .Name }},{{ end }}} }type {{ .BuilderClass }} struct {{{ range .Attrs }}{{ lowercaseFirst .Name }} {{ .Type }} {{ end }} }func {{ .BuilderMethod }}() *{{ .BuilderClass }} {return {{ .BuilderClass }}{} }func (b *{{ .BuilderClass }}) Build() *{{ .BizClass }} {return New{{ .BizClass }}({{- join (mapName .Attrs) , }}) }{{- range .Attrs }} func (b *{{ $.BuilderClass }}) {{ .Name }}({{ lowercaseFirst .Name }} {{ .Type }}) *{{ $.BuilderClass }} {b.{{ lowercaseFirst .Name }} {{ lowercaseFirst .Name }}return b } {{- end }}car : model.ChinaCar{}//autoGenBuilder(builder_tpl)autoGenBuilder2(builder_tpl, car) }这里基本上概括了Go template 的常用语法 {{ . }} 表示顶层作用域对象也就是你从如下方法传入的 bi 对象。 {{ .BuilderClass }} 就是取bi.BuilderClass , {{ .Attrs }} 就是取 bi.Attrs t1.ExecuteTemplate(os.Stdout, test, bi)这有个 range 循环 取 Attrs 里的每一个元素进行循环。注意到range 里面的 {{ .Name }} 的.表示的是Attrs里的每一个元素对象。 {{ range .Attrs }}{{ .Name }}: {{ lowercaseFirst .Name }},{{ end }}这里还传入了一个自定义函数 lowercaseFirst 可以通过如下方法传入 t1 : template.Must(template.New(test).Funcs(template.FuncMap{lowercaseFirst: LowercaseFirst, join: strings.Join, mapName: MapName, mapNameAndType: MapNameAndType,}).Parse(builder_tpl))还有一个技巧就是如何在 range 循环里引用顶层对象。这里要引用 BuilderClass 的值必须用 $.BuilderClass否则输出为空。 {{- range .Attrs }} func (b *{{ $.BuilderClass }}) {{ .Name }}({{ lowercaseFirst .Name }} {{ .Type }}) *{{ $.BuilderClass }} {b.{{ lowercaseFirst .Name }} {{ lowercaseFirst .Name }}return b } {{- end }}嗯多写写就熟了。通过实战来练习和掌握是一种高效学习之法。 注意一定要写 . 号。我最开始老是忘记写。然后就卡住没响应了。 go template 报错不太友好。分三种情况 直接卡住你也不知道到底发生了什么。比如 {{ .BuilderClass }} 写成 {{ BuilderClass }}直接报错地址引用错误。比如模板语法错误。不输出内容。比如引用不到内容。 进一步完善 接下来就要把写死的 BuilderMethod, BuilderClass, BizClass 和Attrs通过给定的业务类型来生成。 func GetBizClass(t any) string {qualifiedClass : fmt.Sprintf(%T, t)return qualifiedClass[strings.Index(qualifiedClass, .)1:] }func GetAttributes(obj any) []Attr {typ : reflect.TypeOf(obj)attrs : make([]Attr, typ.NumField())for i : 0; i typ.NumField(); i {field : typ.Field(i)attr : Attr{Name: field.Name,Type: field.Type.String(),}attrs[i] attr}return attrs }用 GetBizClass 和 GetAttributes 生成的值分别填充那几处硬写的值即可。 程序的主体本文已经都给出来了读者也可以将其拼接起来做一次完型填空。
http://www.hkea.cn/news/14453653/

相关文章:

  • 沈营商环境建设监督局网站企业网站制作是什么
  • 北京威凯建设发展招聘网站去掉 wordpress.org
  • 商城网站建设合同范本百度指数数据分析平台入口
  • wordpress网站好慢做企业网站的步骤
  • 购物网站建设论文网上购物有哪些网站?
  • 丰都集团网站建设网站蜘蛛爬行记录
  • 网站建设进度及实过程上海企业网站seo
  • 上海公司网站建设电话马云做网站最早
  • 南宁世尊商贸网站建设微信自媒体怎么赚钱
  • 网站首页制作过程制作相册app
  • 门户网站开发文档完整网站设计
  • 旅游网站静态模版下载随州网站建设外包公司
  • 带数据库的网站做视频剪辑制作
  • 做淘宝客导购网站推广河间网站建设价格
  • 手机网站 等比缩放外贸soho网站建设
  • 成都 企业网站建设公司wordpress 购物车
  • 漯河网站建设zrgu高明网站设计服务
  • 公司网站必须做可信认证吗seo优化中商品权重主要由什么决定
  • 手机网站制作软件空调seo是什么意思
  • 做网站有没有免费空间分享经济网站怎么建设
  • 关于企业网站建设的提案wordpress博客 登录
  • 百度站长平台网站体检qq空间wordpress
  • 直播网站是怎么做的ip域名查询网站入口
  • 太仓seo网站优化软件介绍做网站的标题
  • 网站建设交流发言稿重庆app定制软件开发
  • seo网站推广专员招聘wordpress添加表格
  • 株洲网站建设服务网站集约化建设做法
  • nas 支持做网站网站建设相关推荐
  • 网站开发下人员配置巴顿品牌设计
  • 织梦 导航网站 模板设计素材网站永久