• JavaScript 设计模式之组合模式


    组合模式

    在我们日常中肯呢个会将一个表单用这种模式来创建

    1. const Car = function () { }
    2. Car.prototype.getName = function () {
    3. throw new Error("需要重写该方法")
    4. }
    5. Car.prototype.getPrice = function () {
    6. throw new Error("需要重写该方法")
    7. }
    8. const Benz = function () { }
    9. // 继承Car
    10. Benz.prototype = new Car()
    11. // 重写getName方法
    12. Benz.prototype.getName = function () {
    13. return 'Benz'
    14. }
    15. const b = new Benz()
    16. console.log(b.getName()) // Benz
    17. console.log(b.getPrice()) // 需要重写该方法

    先写一个基类,再继承该基类

    1. const Benz = function (name, price) {
    2. Car.call(this)
    3. this.name = name
    4. this.price = price
    5. }
    6. Benz.prototype = new Car
    7. Benz.prototype.getPrice = function () {
    8. return this.price
    9. }
    10. Benz.prototype.getName = function () {
    11. return this.name
    12. }
    13. const benz = new Benz('奔驰', 50)
    14. console.log(benz.getName()) // 输出:奔驰
    15. console.log(benz.getPrice()) // 输出:50
    16. const bmw = new Benz('宝马', 100)
    17. console.log(bmw.getPrice()) // 输出:100

    构建一个 Form 表单

    首先我们创建一个基类

    定义

    1. const Base = function () {
    2. this.children = []
    3. this.element = null
    4. }
    5. Base.prototype = {
    6. init: function () {
    7. throw new Error('必须重写该方法')
    8. },
    9. add: function () {
    10. throw new Error('必须重写该方法')
    11. },
    12. remove: function () {
    13. throw new Error('必须重写该方法')
    14. },
    15. get: function () {
    16. throw new Error('必须重写该方法')
    17. }
    18. }

    接下来创建一个容器

    1. const FormItem = function (id,parent) {
    2. Base.call(this)
    3. this.id = id
    4. this.parent = parent
    5. this.init()
    6. }
    7. FormItem.prototype = new Base()
    8. FormItem.prototype.init = function () {
    9. this.element = document.querySelector('#form')
    10. this.element.id = this.id
    11. }
    12. FormItem.prototype.add = function (child) {
    13. this.children.push(child)
    14. this.element.appendChild(child.getDom())
    15. return this
    16. }
    17. FormItem.prototype.getDom = function () {
    18. return this.element
    19. }
    20. FormItem.prototype.show = function () {
    21. this.parent.appendChild(this. Element)
    22. }

    注意,这里的 show 方法就是用来将所有的 dom 追加到页面上

    下面创建一系列的 form 相关 item 及一些dom

    1. const FieldsetItem = function (selector, label) {
    2. Base.call(this)
    3. this.selector = selector
    4. this.label = label
    5. this.init()
    6. }
    7. FieldsetItem.prototype = new Base()
    8. FieldsetItem.prototype.init = function () {
    9. this.element = document.createElement('fieldset')
    10. const legend = document.createElement('legend')
    11. legend.innerHTML = this.label
    12. this.element.appendChild(legend)
    13. }
    14. FieldsetItem.prototype.add = function (child) {
    15. this.children.push(child)
    16. this.element.appendChild(child.getDom())
    17. return this
    18. }
    19. FieldsetItem.prototype.getDom = function () {
    20. return this. Element
    21. }
    22. const Group = function () {
    23. Base.call(this)
    24. this.init()
    25. }
    26. Group.prototype = new Base()
    27. Group.prototype.init = function () {
    28. this.element = document.createElement('div')
    29. this.element.className = 'group'
    30. }
    31. Group.prototype.add = function (child) {
    32. this.children.push(child)
    33. this.element.appendChild(child.getDom())
    34. return this
    35. }
    36. Group.prototype.getDom = function () {
    37. return this.element
    38. }
    39. const LabelItem = function (name, label) {
    40. Base.call(this)
    41. this.name = name
    42. this.label = label
    43. this.init()
    44. }
    45. LabelItem.prototype = new Base()
    46. LabelItem.prototype.init = function () {
    47. this.element = document.createElement('label')
    48. this.element.innerHTML = this.label
    49. this.element.htmlFor = this.name
    50. }
    51. LabelItem.prototype.add = function (child) {
    52. // 这里不需要添加,因为label后面直接跟输入框
    53. return this
    54. }
    55. LabelItem.prototype.getDom = function () {
    56. return this.element
    57. }
    58. const InputItem = function (name) {
    59. Base.call(this)
    60. this.name = name
    61. this.init()
    62. }
    63. InputItem.prototype = new Base()
    64. InputItem.prototype.init = function () {
    65. this.element = document.createElement('input')
    66. this.element.name = this.name
    67. this.element.style.marginLeft = '5px'
    68. }
    69. InputItem.prototype.add = function (child) {
    70. // 这里不需要添加,因为输入框后面直接跟标签
    71. return this
    72. }
    73. InputItem.prototype.getDom = function () {
    74. return this.element
    75. }
    76. const CheckboxItem = function (name, value, label) {
    77. Base.call(this)
    78. this.name = name
    79. this.value = value
    80. this.label = label
    81. this.init()
    82. }
    83. CheckboxItem.prototype = new Base()
    84. CheckboxItem.prototype.init = function () {
    85. const span = document.createElement('span')
    86. this.element = document.createElement('label')
    87. const input = document.createElement('input')
    88. input.type = 'checkbox'
    89. span.innerHTML = this.label
    90. input.value = this.value
    91. input.style.marginRight = '5px'
    92. this.element.appendChild(input)
    93. this.element.appendChild(span)
    94. }
    95. CheckboxItem.prototype.add = function (child) {
    96. }
    97. CheckboxItem.prototype.getDom = function () {
    98. return this.element
    99. }
    100. const SpanItem = function (name) {
    101. Base.call(this)
    102. this.name = name
    103. this.init()
    104. }
    105. SpanItem.prototype = new Base()
    106. SpanItem.prototype.init = function () {
    107. this.element = document.createElement('span')
    108. this.element.innerHTML = this.name
    109. this.element.style.marginLeft = '5px'
    110. }
    111. SpanItem.prototype.add = function (child) {
    112. // 这里不需要添加,因为span前面直接跟输入框
    113. return this
    114. }
    115. SpanItem.prototype.getDom = function () {
    116. return this. Element
    117. }

    使用 

    假使页面中存在 dom 

    1. <form id="form">form>
    2. <div id="content">div>

    js

    1. var form = new FormItem('form', document.querySelector('#content'))
    2. form.add(new FieldsetItem('account', '账号').add(
    3. new Group().add(
    4. new LabelItem('user_name', '用户名:')
    5. ).add(
    6. new InputItem('user_name')
    7. ).add(new SpanItem('4 到 6 位数字或字母'))
    8. ).add(
    9. new Group().add(
    10. new LabelItem('user_pwd', '密 码:')
    11. ).add(
    12. new InputItem('user_pwd')
    13. ).add(new SpanItem('6 到 12 位数字或字母'))
    14. ).add(
    15. new Group().add(
    16. new CheckboxItem('remember', true, '是否记住')
    17. )
    18. ))
    19. .show()

    效果

    总结 

    组合模式能够给我们提供一个清晰的组成结构。组合对象类通过继承同一个父类使其具有统一的方法,这样也方便了我们统一管理与使用,当然此时单体成员与组合体成员行为表现就比较一致了,这也模糊了简单对象与组合对象的区别

  • 相关阅读:
    MySQL实现的一点总结(五)
    VS创建的aspx文件下没有设计-拆分-源 并且工具箱中的控件为灰色
    【软考软件评测师】第三十二章 数据库系统基础知识
    神经网络NLP基础 循环神经网络 LSTM
    .NET 程序读取当前目录避坑指南
    no permission 这种问题的解决方法
    WPF绘图(图形的效果与变形)
    验证 Vue Props 类型,你这几种方式你可能还没试用过
    前后端开发接口联调对接参数
    IDEA 打包MapReduce程序到集群运行的两种方式以及XShell和Xftp过期的解决
  • 原文地址:https://blog.csdn.net/u010279990/article/details/136186100