工厂方法模式(Factory Method):通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例。

1 广告的展现

“咱们有一批广告需要投放,关于计算机培训的。一批是 Java 的,用绿色字体。还有一批是 PHP 的,要用黄色字体,红色背景。”

  1. // 创建 Java 学科类
  2. var Java = function(content) {
  3. this.content = content;
  4. // 创建对象,通过闭包,直接执行
  5. (function(content){
  6. var div = document.createElement('div');
  7. div.innerHtml = content;
  8. div.style.color = 'green';
  9. document.getElementById('container').appendChild(div);
  10. })(content);
  11. }
  12. // 创建 PHP 学科类
  13. var PHP = function(content) {
  14. this.content = content;
  15. // 创建对象,通过闭包,直接执行
  16. (function(content){
  17. var div = document.createElement('div');
  18. div.innerHtml = content;
  19. div.style.color = 'yellow';
  20. div.style.background = 'red';
  21. document.getElementById('container').appendChild(div);
  22. })(content);
  23. }

“又来了一批广告,关于 JavaScript 的,要求背景粉色……”

  1. // 使用简单工厂模式
  2. var Java = function(content) {
  3. // ...
  4. }
  5. var PHP = function(content) {
  6. // ...
  7. }
  8. // 创建 JavaScript 学科
  9. var JavaScript = function(content) {
  10. this.content = content;
  11. // 创建对象,通过闭包,直接执行
  12. (function(content){
  13. var div = document.createElement('div');
  14. div.innerHtml = content;
  15. div.style.background = 'pink';
  16. document.getElementById('container').appendChild(div);
  17. })(content);
  18. }
  19. // 学科类工厂
  20. function SubjectFactory = function(type, content) {
  21. switch(type) {
  22. case 'java':
  23. return new Java(content);
  24. case 'php':
  25. return new PHP(content);
  26. case 'javascript':
  27. return new JavaScript(content);
  28. }
  29. }

“小白,又来了一批 UI 学科,红色边框……”
“需求总在变,不知道用那种解决方式更好。开始需求简单就创建对象,后来需求多了,就用简单工厂模式重构。而现在又变了,不仅要加类,还要修改工厂函数。”

2 安全的工厂方法

安全模式类是说可以屏蔽使用者对类的错误使用造成的错误。比如实例化时,忘记加 new 关键字。

  1. // 安全模式创建的工厂类
  2. var Factory = function(type, content) {
  3. if (this instanceof Factory) {
  4. var subject = new this[type](content); // 实例化原型对象上的类
  5. return subject;
  6. } else {
  7. return new Factory(type, content);
  8. }
  9. }
  10. // 工厂原型中设置创建所有类型数据对象的基类
  11. Factory.prototype = {
  12. Java: function(content) {
  13. // ...
  14. },
  15. PHP: function(content) {
  16. // ...
  17. },
  18. JavaScript: function(content) {
  19. // ...
  20. },
  21. UI: function(content) {
  22. this.content = content;
  23. // 创建对象,通过闭包,直接执行
  24. (function(content){
  25. var div = document.createElement('div');
  26. div.innerHtml = content;
  27. div.style.border = '1px solid red';
  28. document.getElementById('container').appendChild(div);
  29. })(content);
  30. }
  31. }

“这样我们以后想添加其他类时,是不是只需写在 Factory 这个工厂类的原型里面就可以了?”

通过工厂方法模式我们可以轻松创建多个类的实例对象,这样工厂方法对象在创建对象的方式也避免了使用者与对象类之间的耦合,用户不必关心该对象的具体类,只需调用工厂方法