工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
PHP实现:
<?php
declare(strict_types = 1);
/**
* 业务接口
*/
interface Sender{
public function send(string $msg);
}
class MailSender implements Sender{
public function send(string $msg){
echo $msg;
}
}
class SmsSender implements Sender{
public function send(string $msg){
echo $msg;
}
}
/**
* 工厂接口
*/
interface Provider{
public function produce(): Sender;
}
class SendMailFactory implements Provider{
public function produce(): Sender{
return new MailSender();
}
}
class SendSmsFactory implements Provider{
public function produce(): Sender{
return new SmsSender();
}
}
$provider = new SendMailFactory();
$mailSender = $provider->produce();
$mailSender->send('This is mailsender!'."\n");
$provider = new SendSmsFactory();
$smsSender = $provider->produce();
$smsSender->send("This is smssender! \n");
Golang实现:
package main
import (
"fmt"
)
/**
* 业务接口
*/
type Sender interface {
send(msg string)
}
type MailSender struct {
}
type SmsSender struct {
}
func (s MailSender) send(msg string) {
fmt.Println(fmt.Sprintf("Mail msg: %s", msg))
}
func (s SmsSender) send(msg string) {
fmt.Println(fmt.Sprintf("Sms msg: %s", msg))
}
/**
* 工厂接口
*/
type Provider interface {
produce() Sender
}
type SendSmsFactory struct {
}
type SendMailFactory struct {
}
func (s SendMailFactory) produce() Sender {
return MailSender{}
}
func (s SendSmsFactory) produce() Sender {
return SmsSender{}
}
func main() {
x := make([]Sender, 2)
mailProvider := SendMailFactory{}
x[0] = mailProvider.produce()
smsProvider := SendSmsFactory{}
x[1] = smsProvider.produce()
for _, s := range x {
if x != nil {
s.send("Hello world!")
}
}
}
如果你现在想增加一个功能:则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。