Loading...
墨滴

狼丶宇先森

2021/05/27  阅读:25  主题:姹紫

①【创建型设计模式】简单工厂模式

一、写在前面

简单工厂模式(Simple Factory):又叫静态工厂方法,由一个工厂对象决定创建某一种产品对象的实例。主要用来创建同一类对象。关注公众号“笔优站长”可阅读全部文章哟。

二、一个小场景

有这样的一个场景,假如我们要做一个登录模块,需求如下:

用户名输入框的地方,如果用户输入的内容不符合规范就自定义个警示框警示一句“用户名不能多于16个字母或者数字”。

大多数的情况下会这样写

var LoginAlert = function (text){
 this.content = text;
}
LoginAlert.show = function (){
 //显示警示框
}

//调用
var userNameAlert = new LoginAlert('用户名不能多于16个字母或者数字');
userNameAlert.show();

你以为就完了?

现在又增加了一个需求,就是当用户输入的密码错误时也需要提示一句“输入的密码不正确”的一个提示文案。你暗自窃喜,以前的那个类还可以用。

你还是按以前的逻辑来写,于是乎

//调用
var passwordAlert = new LoginAlert('输入的密码不正确');
passwordAlert.show();

产品又说,用户登录时如果用户名不存在就提示一句“您的用户名不存在,请重新输入”,当你暗自窃喜刚刚创建的那个类还可以用时,产品又说:这里的需求有些变化,就是要在警示框中添加一个注册按钮。

这个时候你可能有点傻眼了:添加一个按钮……,以前的功能还怎么复用呀,这有的创建一个类了。。。

若你还是按以前的逻辑来写。。。

var LoginConfirm = function (text){
 this.text = text;
}
LoginConfirm.prototype.show = function (){
 //显示确认框
}

var loginConfirm = new LoginConfirm('您的用户名不存在,请重新输入');
loginConfirm.show();

当你刚刚把这个功能写好后,需求又来了。。。登录成功后,给出一个自定义提示框,除了有确认取消按钮之外,也提示一句“欢迎回来,请输入您今天的心情吧”。

到这里你的心态是否已经有点崩了呢?

不过需求还是得完成,于是接着乎

var LoginPrompt = function (text){
 this.text = text;
}
LoginPrompt.prototype.show = function (){
 //显示确认框
}

花了半天的时候,终于把这些需求搞定了。。。

三、举个小栗子,如果类太多,那么提供一个

以上面的小场景为原型,写个简单工厂。

那么,什么是简单工厂呢?

简单工厂是一种设计模式,简单的来说就是把上面举例的几个类封装在一个函数里,然后只需要记住这个函数,后面需要用到的时候就可以通过这个函数创建需要的对象,使用这些对象的人就不需要关注这些对象到底依赖于哪个基类了,只需要知道这个函数就可以了。这个函数通常也被称为工厂函数,这种模式就叫简单工厂模式,它是工厂模式中最简单的一种形式。

如果上面的都还没看懂呢,请接着看。

假如说你需要买一些体育用品,例如篮球、足球等。你首先想到的便是去找一个体育用品专卖店之类的吧。然后你只需要找到这个专卖店,然问这个专卖店的店员,篮球在哪里?他便会告诉你或者直接给你。现在有这样的一个思维了吗?

再往下看个例子:

//篮球基类
var Basketball = function (){
 this.intro = '篮球盛行于美国';
}
Basketball.prototype = {
 getMember(){
  console.log('每个队伍需要5名队员');
 },
 getBallSize(){
  console.log('篮球很大');
 } 
}

//足球基类
var Football = function (){
 this.intro = '世界杯足球很出名';
}
Football.prototype = {
 getMember(){
  console.log('每个队伍需要11名队员');
 },
 getBallSize(){
  console.log('足球很大');
 } 
}

//网球基类
var Tennis = function (){
 this.intro = '到处都在打网球';
}
Tennis.prototype = {
 getMember(){
  console.log('每个队伍需要1名队员');
 },
 getBallSize(){
  console.log('网球很小');
 } 
}

//运动工厂
var SportsFactory = function (name){
 switch (name){
  case 'NBA':
   return new Basketball();
  case 'wordCup':
   return new Football();
  case 'FrenchOpen':
   return new Tennis();
 }
}

上面的例子就写好了,假如你要和你的小伙伴踢足球,只需要告诉店员买个足球即可,你使用这个运动工厂的时候,只需要记住SportsFactory这个工厂对象就好,然后它就可以给你找到你需要的。

//为世界杯创建一个足球,也只需记住这个SportsFactory运动工厂,然后调用并创建
var football = SportsFactory('wordCup');
console.log(football);
console.log(football.intro);
football.getMember();

是不是很简单呢。

但是呢,写完发现了什么不一样的呢?是的,这三个类有很多地方都是相同的,是可以抽象提取出来共用的,也是可以使用简单工厂来实现它们。

四、再举个小栗子,一个对象有时也可以代替许多类

简单工厂模式的理念就是创建对象,像上面那种方式是对不同的类实例化,不过也还可以用来创建相似的对象。如第二段小场景中的对象,有很多地方相似,如关闭按钮,都有提示文案等。所以可以将这些相似的地方提取出来,不相似的地方针对性处理即可。

首先抽象相同的属性如:this.content 和 原型的共有方法show 等。当然也有不同点,比如确认框与提示框的确定按钮,还有提示框的用户输入框等等,所以就可以像下面这样创建了。

function createPop (type,text){
 //创建一个对象,并对对象拓展属性和方法。
 var o = new Object();
 o.content = text;
 o.show = function (){
  //todo 显示方法
 }
 if(type === 'alert'){
  //警示框差异部分
 }
 if(type === 'prompt'){
  //提示框差异部分
 }
 if(type === 'confirm'){
  //确认框差异部分
 }
 //将对象返回
 return o;
}

//创建一个警示框
var userNameAlert = createPop('alert','用户名只能是字母和数字');

到这里呢,我相信你对简单工厂模式也有一定的认知了。上面举例的2种创建模式也是有一定的区别的:“第一种是通过类实例化对象创建的,第二种是通过创建一个新对象然后包装增强其属性和功能来实现的。它们之间的差异性也造成前面通过类创建的对象,如果这些类继承同一个父类,那么他们的父类原型上的方法是可以共用的。而后面寄生方式创建的对象都是一个新的个体,所以他们的方法就不能共用了。当然选择哪种工厂方式来实现你的需求还要看你是如何分析你的需求的。”

五、总结

团队项目开发不同于个人开发,其对全局变量的限制很大,所以我们要尽量少地创建全局变量。对于同一类对象在不同需求中的重复性使用,很多时候不需要重复创建,代码复用是面向对象编程的一条准则。通过对简单工厂来创建一些对象,可以让这些对象共用一些资源而又私有一些资源,这是一种很不错的实践。不过对于简单工厂模式,它的使用场合通常也就限制在创建单一对象。

六、写在后面

上面就是创建型设计模式中的简单工厂模式全部内容了,加油,快动手试试吧。

有问题请留言或者@博主,谢谢支持o( ̄︶ ̄)o~

感谢您的阅读,如果此文章或项目对您有帮助,请扫个二维码点个关注吧,若可以的话再给个一键三连吧!

GitHub有开源项目,需要的小伙伴可以顺手star一下!

GitHub: https://github.com/langyuxiansheng

更多信息请关注公众号: “笔优站长”

笔优站长
笔优站长
扫码关注“笔优站长”,支持站长

狼丶宇先森

2021/05/27  阅读:25  主题:姹紫

作者介绍

狼丶宇先森