GoF定义:定义一个用于创建工具的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化推迟到其子类。
GoF类图
类图中的Product为产品类图中的Creator为创建者创建者父类有一个抽象的FactoryMethod()工厂方法所有创建者子类须要实现这个工厂方法,返回对应的详细产品创建者父类可以有一个AnOperation()操作方法,直接返回product,可以利用FactoryMethod()去返回,这样外部只须要统一调用AnOperation()
代码实现
首先是商品干系的接口和实现类,和大略工厂的类似:
//商品接口interfaceProduct{functionshow():void;}//商品实现类AclassConcreteProductAimplementsProduct{publicfunctionshow():void{echo"I'mA.\n";}}
接下来是创建者的抽象和实现类:
//创建者抽象类abstractclassCreator{//抽象工厂方法abstractprotectedfunctionFactoryMethod():Product;//操作方法publicfunctionAnOperation():Product{return$this->FactoryMethod();}}//创建者实现类AclassConcreteCreatorAextendsCreator{//实现操作方法protectedfunctionFactoryMethod():Product{returnnewConcreteProductA();}}
这里和大略工厂就有了实质的差异,我们去掉了恶心的switch,让每个详细的实现类来进行商品工具的创建。没错,单一和封闭,每个单独的创建者子类只在工厂方法中和一个商品有耦合,有没有其他商品和其他的工厂来跟客户互助过这个子类完备不知道。
同样还是拿手机来比喻:我是一个卖手机的批发商(客户Client,业务方),我须要一批手机(产品ProductA),于是我去让富X康(工厂Creator)来帮我生产。我跟富士康解释了需求,富士康说好的,让我的衡阳工厂(ConcreteCreatorA)来搞定,不须要总厂上,你这小单子,洒洒水啦。然后过了一阵我又须要另一种型号的手机(产品ProductB),富士康看了看后又让郑州富士康(ConcreteCreatorB)来帮我生产。反正不管怎么样,他们总是给了我对应的手机。而且郑州工厂并不知道衡阳工厂生产过什么或者有没有跟我互助过,这统统只有我和总工厂知道。
完全代码:工厂方法模式
实例场景:光说不练假把式,把上回的短信发送改造改造,我们依然还是利用上回的那几个短信发送商。毕竟大家已经很熟习了嘛,不过往后要改换也说不定,阛阓如沙场,大家还是利益为先。这样的话,我们通过工厂方法模式来进行解耦,就可以方便的添加修正短信供应商咯。
短信发送类图
短信发送工厂方法
代码实现
<?phpinterfaceMessage{publicfunctionsend(string$msg);}classAliYunMessageimplementsMessage{publicfunctionsend(string$msg){//调用接口,发送短信//xxxxxreturn'阿里云短信(原阿里大鱼)发送成功!
短信内容:'.$msg;}}classBaiduYunMessageimplementsMessage{publicfunctionsend(string$msg){//调用接口,发送短信//xxxxxreturn'百度SMS短信发送成功!
短信内容:'.$msg;}}classJiguangMessageimplementsMessage{publicfunctionsend(string$msg){//调用接口,发送短信//xxxxxreturn'极光短信发送成功!
短信内容:'.$msg;}}abstractclassMessageFactory{abstractprotectedfunctionfactoryMethod();publicfunctiongetMessage(){return$this->factoryMethod();}}classAliYunFactoryextendsMessageFactory{protectedfunctionfactoryMethod(){returnnewAliYunMessage();}}classBaiduYunFactoryextendsMessageFactory{protectedfunctionfactoryMethod(){returnnewBaiduYunMessage();}}classJiguangFactoryextendsMessageFactory{protectedfunctionfactoryMethod(){returnnewJiguangMessage();}}//当前业务须要利用百度云$factory=newBaiduYunFactory();$message=$factory->getMessage();echo$message->send('您有新的短,请查收');
完全源码:短信发送工厂方法
解释
和类图完备同等,基本不须要什么解释了吧,把稳工厂方法模式的特点,实现推迟到了子类!!
业务调用的时候须要耦合一个Factory子类。确实是这样,如果你想一个统一的出口来调用,请在表面加一层大略工厂就好啦,这就当成一道思考题吧不拘泥于目前的形式,可以不用抽象类,直接用一个接口来定义工厂方法,摒弃掉getMessage()方法,外部直接调用公开的模板方法(factoryMethod)即可下期看点
抽象工厂模式,老大哥即将登场。压轴的总是最刁悍的,让我们看看老大哥的本事!