设计模式的思考(四)

 看看这些模式都解决了哪些问题:

创建模式(5个):

// 创建一个个迷宫,某个地方将调用下面的代码

...
class Maze{
...
}
class Room{
...
}
class Door{
...
}
...
class Game{
...
//以下即为创建过程
   Maze CreateMaze(){
     Maze *aMaze=new Maze;//要修改
     Room *aRoom= new Room;//要修改
     Door *aDoor= new Door(aRoom);//要修改
   
     aMaze->AddRoom(aRoom);
   
     return aMaze;
  }
//以上即为创建过程
...
}
....
int  main(){
  ...
  Game *game=new Game();
  game->createMaze();
  ...
}

这段创建过程的代码的主要问题是不够灵活。如果改变了Room, Door这里的代码就要改变。比如说我们想把这个Room,改为EnchantedRoom呢?就要将第2行代码改掉,加入EnchantedRoom的定义。可能要考虑这里的实现逻辑,并添加新类。修改的地方太多。

工厂模式:想买一辆车或开发一辆新车,你肯定是找汽车制造厂,不会找服装厂。解决接口问题。

...
class Maze{
...
}
class Room{
...
}
class Door{
...
}
...
class Factory{
   ...
   Maze* makeMaze(){...};
   Room* makeRoom(){...};
   Door* makeDoor(){...};
   ...
}
//可以添加不同的工厂,每一个工厂可以制造不同的maze,room &door
//但是有可能要定义很多的类,但是采用工厂模式可以使得建造有统一的接口
clas Factory1:public Factory{
...
 Maze* makeMaze(){
    return new Maze();
 };
...
}
...
clas FactoryN:public Factory{
...
 Maze* makeMaze(){
    return new MazeN();
 };
...
}
//

class Game{
...
   Maze CreateMaze(){
     Factory *factory= new FactoryN();//可以修改,但是涉及到具体逻辑,且如果工厂很多,
                                    //有不同的风格他人难以使用,需要继续演化
     Maze *aMaze=factory->makeMaze();
     Room *aRoom=factory->makeRoom;
     Door *aDoor=factory->makeDoor(aRoom);
   
     aMaze->AddRoom(aRoom);
   
     return aMaze;
  }
...

}
....

int  main(){
  ...
  Game *game=new Game();
  game->createMaze();
  ...
}

可以定义新的方法来实现部件,而修改只有1处。

抽象工厂模式:当同类工厂比较多,比较复杂的时候,你要将他们继续分类和组合,一类工厂创建一类产品,抽象工厂就是总公司。一家人的衣服怎么收藏?假设有一个衣帽间,衣帽间里有3个衣橱,分别存爸爸的衣服,妈妈的,孩子的。解决风格问题。

...
class Maze{
...
}
class Room{
...
}
class Door{
...
}
...
class Factory{
   ...
   Maze* makeMaze(){...};
   Room* makeRoom(){...};
   Door* makeDoor(){...};
   ...
}
//可以添加不同的工厂,每一个工厂可以制造不同的maze,room &door
//但是有可能要定义很多的类,但是采用工厂模式可以使得建造有统一的接口
clas Factory1:public Factory{
...
 Maze* makeMaze(){
    return new Maze();
 };
...
}
...
clas FactoryN:public Factory{
...
 Maze* makeMaze(){
    return new MazeN();
 };
}
//抽象工厂将不同的风格进行了统一
class FactoryProducer{
  ...
  Factory getMazeFactory(){//可以修改
   //style1
     return factory1;
    .....
   //styleN
     return factoryN;
  }
  ...
}
class Game{
...
  Maze* CreateMaze(){
    Factory factory=FactoryProducer.getMazeFactory();
    Maze *aMaze=factory.makeMaze();
    Room *aRoom=factory.makeRoom;
    Door *aDoor=factory.makeDoor(aRoom);
   
    aMaze->AddRoom(aRoom);
   
    return aMaze;
  }
...
}
.....
int  main(){
  ...
  Game *game=new Game();
  game->createMaze();
  ...
}

单例模式:避免一个全局使用的类频繁地创建与销毁。比如GUI的画笔。FactoryProducer就可以采用单例。

class Singleton{
  ...
  static  Singleton Instance(){
    if(_instance==0){
       _instance=new Singleton();
    }
    return _instance;
  }
...
private;
 static Singleton * _instance;
  
}
...
Singleton:: _instance=0;

建造者模式:复杂对象的各个部分相对稳定,但是将它们组合在一起的算法却经常面临着剧烈的变化,但是又要统一管理,将稳定部分和非稳定部分分离,分别创建。建稳定部分与非稳定部分结合的是创建者。餐厅账单的项目是变化的,计算账单的总额方法是固定的。

...
class Maze{
...
}
class Room{
...
}
class Door{
...
}
...
class Factory{
   ...
   Maze* makeMaze(){...};
   Room* makeRoom(){...};
   Door* makeDoor(){...};
   ...
}
//可以添加不同的工厂,每一个工厂可以制造不同的maze,room &door
//但是有可能要定义很多的类,但是采用工厂模式可以使得建造有统一的接口
clas Factory1:public Factory{
...
}
...
clas FactoryN:public Factory{
...
}
//抽象工厂将不同的风格进行了统一
class FactoryProducer{
  ...
  Factory getMazeFactory(){//可以修改
   //style1
     return factory1;
    .....
   //styleN
     return factoryN;
  }
  ...
}
//新加入,可以采用统一的方式进行管理
class MazeBuilder{
     List itemList=new List;
     ....
     BuildMaze(){...};
     BuildRoom(){...};
     BuildDoor(){...};
     ...
     GetMaze(){};
     ....
}
...
class Game{
...
  Maze* CreateMaze(){
    Builder builder= new MazeBuilder();
    builder.BuildMaze();
    builder.BuildRoom(1);
    builder.BuildDoor(1)
    return builder.GetMaze();
   }
...
}
int  main(){
  ...
  Game *game=new Game();
  game->createMaze();
  ...
} 
  

 原型模式:利用已有对象进行克隆,使一个系统独立于它的产品创建、构成和表示,减少类的数目。

...
class Maze{
...
  clone(){...}//新添加
...
}
class Room{
...
  clone(){...}//新添加
...
}
class Door{
...
  clone(){...}//新添加
...
}
...
class Factory{
  Factory(Maze *m,Room*r,Door* d){
     __prototyMaze=m;
     __prototyRoom=r;
     __prototyDoor=d;
  }
  ...
  Maze* makeMaze(){return _prototyMaze->clone();}
  Room* makeRoom(){return _prototyRoom->clone();}
  Door* makeDoor({return _prototyDoor->clone();}
  ...
  Maze *_prototyMaze;//原型
  Room *_prototyRoom;//原型
  Door *_prototyDoor;//原型
  //初始化原型,也可以在构造函数中
  InitializePrototy(maze*,room*,door*){...}
}
//可以添加不同的工厂,每一个工厂可以制造不同的maze,room &door
//但是有可能要定义很多的类,但是采用工厂模式可以使得建造有统一的接口

//有太多的工厂类了,删除,用原型模式
//clas Factory1:public Factory{
//...
// Maze* makeMaze(){
//    p=_prototyMaze->clone();
//    //下面对原型进行改造
//    ...
//    return p;
// };
//...
//}
//...
//clas FactoryN:public Factory{
//...
// Maze* makeMaze(){
//    p=_prototyMaze->clone();
//    //下面对原型进行改造
//    ...
//    return p;
// };
//}

//抽象工厂将不同的风格进行了统一
class FactoryProducer{
  ...
  Factory getMazeFactory(){//可以修改
   //style1
     return new Factory(m1,r1,d1);
    .....
   //styleN
     return new Factory(mN,rN,dN);
}
//新加入,可以采用统一的方式进行管理
class MazeBuilder{
     List itemList=new List;
     ....
     BuildMaze(){...};
     BuildRoom(){...};
     BuildDoor(){...};
     ...
     GetMaze(){};
     ....
}
...
class Game{
...
  Maze* CreateMaze(){
    Builder builder= new MazeBuilder();
    builder.BuildMaze();
    builder.BuildRoom(1);
    builder.BuildDoor(1)
    return builder.GetMaze();
   }
...
}
int  main(){
  ...
  Game *game=new Game();
  game->createMaze();
  ...
} 
  

@@

想造汽车,太麻烦,找一家汽车厂给我造(工厂模式),轿车,卡车、公交车等等都要工厂来造,时间久了,各种车的型号、规格越来越多,汽车厂也搞不定了,汽车厂升级为汽车集团(抽象工厂模式),下设轿车、卡车、公交车等工厂。各种车的规格也不能有无限多个,典型的几种底盘、发动机、外形、内饰等进行组合,就可以生产出多种型号的汽车(建造者模式)。另外可能有时候有客户要定制汽车,其实也简单,汽车都是差不多的,先把旧车准备着,他的要求明确了(可能是查数据库等),在旧车上更改参数(原型模式)就可以了。改车时需要用到大铁锤,每个车间都要用,干嘛每次都是先写报告申请,每次都要填出库、入库单才能用?不如放到一个固定的位置,谁用谁拿,不要申请了,反正只需要一把(单例模式)!

其他类型的对象的创建照此办理。

@@

结构模式(7个):

适配器模式:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。比如现在笔记本电脑上一般没有串口了,只有USB口,怎么办?买一个usb转232,485等转接卡。还有网关等也是适配器模式。

桥接模式:相当于采购部。买什么由部门定,怎么买由采购部决定。买什么和怎么买分开,买和卖统合于采购部。每个人都可以买东西,但是并不需要知道如何买东西。

组合模式:相当于单位再划分各个业务部门管理所有员工。采用树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

外观模式:相当于打官司时的律师。律师按照你的要求帮你查资料、走流程,你把该有的资料交给他就可以了。也相当于单位的收发室。要是邮递员把每一封邮件都亲自交到收件人手里,那么邮递员要楼上楼下到处跑,把他累死了也搞不好,况且有些单位的信息你也不希望让外人知道。大家之间的关系也简单了。

装饰器模式:相当于审批盖章部门。盖过章的文件与原来的文件是不一样的,一般动态添加功能。装饰器模式主要是为了增强功能。

享元模式:每个领导都要配一部车,太浪费了,搞一个车队,需要时去申请,如果车不够了,再去买。

代理模式:相当于银行(或财务处)。为了安全的原因,你不能直接到金库中去钱,必须通过银行。代理模式主要是为了控制。

@@

你的老板是个老外,你和他交流必须通过翻译(适配器模式)。一天他准备给所有人配个usb转接卡,但是申请流程很复杂,他就交给你(中介,外观模式)来办。你打印了一份申请表,到各个部门审批(装饰器模式),最后要大领导审批,你将申请表寄到总部,总部收发处(享元模式)收到后将申请表交到秘书处,分管设备采购的领导秘书(过滤器模式)发现这份文件就将该文件取走,并在领导审批签字同意后转交给你。收到文件后你将申请表交给后勤处(代理模式),但是库房没有,所以后勤处让采购部门(桥接模式)去采购,购买回来,入库,然后通知将你所有转接卡领出来。你领出设备后,按照部门将转接卡发给各个部门负责人,由各个部门再将转接卡发给个人(组合模式)。

@@

过滤器(标准)模式:相当于秘书处。每天收到那么多的公文,这些公文都要交给谁审阅,一种方式是一个秘书对应所有领导,领导换了,他要重新确定领导权限;另一种方式是一个秘书对应一位领导,领导换了,只要换一位秘书,其他秘书工作量不变。

行为模式(11个)

策略模式:诸葛亮发的锦囊。外表一样,但是如何处理锦囊中的内容是不一样的。锦囊太多(大于4)考虑采用混合模式。

命令模式:领导命令下属部门办事,有两种方法:1直接找下面的职能部门;2交给秘书,让秘书通知通知相应职能部门。命令模式采用第2种方式,领导甚至不需要具体是哪个职能部门执行的命令。

观察者模式:传达室看门老大爷老是打瞌睡,人来了也不开门,怎么办?改成感应门,接近开关(观察者)一旦检测到有人自动开门。老大爷失业了。

中介者模式:100个人如何相互认识呢?两两相互介绍?太慢了!也太复杂了。找一个地方(中介者),每人上去自我介绍。网络状交互变为星型交互。中介把大家拉到一起(注意和外观模式区别,外观模式只对客户一方负责,中介对大家负责)。有了中介以后,大家不需要两两接触了。这也相当于单位的收发室。

访问者模式:相当于到档案室查询资料。查询本身不改变档案信息内容。

责任链模式:相当于工厂的流水线。工件到你面前了,你只管按螺丝,其他不管。

备忘录模式:事情太多,记不住忘了怎么办?用个小本本。

模板模式:写工作日志。每次都是从头写吗?可能每天都是差不多的工作,写一个模板,改改工件名称和数量,其他不变。甚至就是填一个表单。

解释器模式:很少用到。很像命令模式。但是当领导交代的命令非常复杂,甚至可能是涉及多部门的,这是对秘书(参谋)的要求就高了,领导不需要知道涉及那些部门(我只要知道结果),秘书可要知道,并且还要协调部门间的工作。领导只是说自己的一些习惯用语(黑话,只要内部人懂,但是沟通效率高)。秘书这时候就不仅仅是上传下达了。

迭代器模式:怎么样数部门人头?领导是不管的,也管不过来,部门太多,每个部门又太复杂,干脆专门安排一个人负责该工作。在领导面前,他希望看到的是大家都是站成一排,一个词:简单。这可苦了迭代器。

状态模式:类似流水线(状态机)。一个产品有多道工序,每个工序又有不同的处理。早期一个人干所有的事情,现在几个人(状态)干,每人干一道工序,并且每个人都知道怎么干,自己做好了下一道工序交给谁(状态转换)。要注意与策略模式相区别,策略模式是单线条,单方向,状态模式可能是环,甚至更复杂。

@@

很搞笑,诸葛亮命令他的三个手下(访客,观察者,中介者),按照他给的锦囊(策略)行事:每人手里拿一个小工具,另一只手拖一台大机器。三个小工具分别是:模板,备忘录,还有一个链子。三台大机器是:解释器、迭代器、状态机。

@@

你可能感兴趣的:(设计模式与软件架构,java,前端,html)