简单工厂模式
场景:鼠标工厂,专业生产鼠标,给参数0,生产戴尔鼠标,给参数1,生产惠普鼠标。
uml类图:
代码:
鼠标接口,跟两个厂商鼠标类:
public interface IMouse {
void sayHi();
}
class DellMouse implements IMouse {
@Override
public void sayHi(){
System.out.println("DellMouse");
}
}
class HpMouse implements IMouse {
@Override
public void sayHi(){
System.out.println("HpMouse");
}
}
鼠标工厂类:
public class MouseFactory {
public static IMouse createMouse(int type){// 0 dell 1 hp
IMouse mouse=null;
switch (type){
case 0:
mouse= new DellMouse();
break;
case 1:
mouse= new HpMouse();
break;
}
return mouse;
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
IMouse mouse1 = MouseFactory.createMouse(0);
mouse1.sayHi();
IMouse mouse2 = MouseFactory.createMouse(1);
mouse2.sayHi();
}
}
- 优点:实现起来很简单,对于一些本身就很简单的系统没有必要使用复杂的模式
- 缺点:如果增加其他品牌鼠标,需要更改MouseFactory的代码,耦合性高,违反了开闭原则
工厂方法模式
场景同上
uml类图:
代码:
鼠标接口,跟两个厂商鼠标类:
public interface IMouse {
void sayHi();
}
class DellMouse implements IMouse {
@Override
public void sayHi(){
System.out.println("DellMouse");
}
}
class HpMouse implements IMouse {
@Override
public void sayHi(){
System.out.println("HpMouse");
}
}
工厂接口,以及两个厂商工厂类:
interface IMouseFactory{
IMouse createMouse();
}
class DellMouseFactory implements IMouseFactory{
@Override
public IMouse createMouse(){
return new DellMouse();
}
}
class HpMouseFactory implements IMouseFactory {
@Override
public IMouse createMouse(){
return new HpMouse();
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
IMouseFactory dellFactory = new DellMouseFactory();
dellFactory.createMouse().sayHi();
IMouseFactory hpFactory = new HpMouseFactory();
hpFactory.createMouse().sayHi();
}
}
- 优点:遵循开闭原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现(如果需要增加一个华硕鼠标,只需要增加一个华硕鼠标类和华硕鼠标工厂类即可,不会影响之前代码,耦合性降低)
- 缺点:如果产品类过多,我们就要生成很多的工厂类。
抽象工厂模式
场景:
抽象工厂模式也就是不仅生产鼠标,同时生产键盘。
也就是PC厂商是个父类,有生产鼠标,生产键盘两个接口。
戴尔工厂,惠普工厂继承它,可以分别生产戴尔鼠标+戴尔键盘,和惠普鼠标+惠普键盘。
创建工厂时,由戴尔工厂创建。
后续工厂.生产鼠标()则生产戴尔鼠标,工厂.生产键盘()则生产戴尔键盘。
uml图:
代码:
鼠标接口以及2个厂商鼠标类:
public interface IMouse {
void sayHi();
}
class DellMouse implements IMouse {
@Override
public void sayHi(){
System.out.println("DellMouse");
}
}
class HpMouse implements IMouse {
@Override
public void sayHi(){
System.out.println("HpMouse");
}
}
键盘接口以及2个厂商键盘类:
public interface IKeybo {
void sayHi();
}
class DellKeybo implements IKeybo {
@Override
public void sayHi(){
System.out.println("DellKeybo");
}
}
class HpKeybo implements IKeybo {
@Override
public void sayHi(){
System.out.println("HpKeybo");
}
}
工厂接口,以及2个厂商的工厂类:
interface IPCFactory{
IMouse createMouse();
IKeybo createKeybo();
}
class DellFactory implements IPCFactory {
@Override
public IMouse createMouse(){
return new DellMouse();
}
@Override
public IKeybo createKeybo() {
return new DellKeybo();
}
}
class HpFactory implements IPCFactory {
@Override
public IMouse createMouse(){
return new HpMouse();
}
@Override
public IKeybo createKeybo() {
return new HpKeybo();
}
}
client:
public class Client {
public static void main(String[] args) {
IPCFactory dellFactory = new DellFactory();
dellFactory.createMouse().sayHi();
dellFactory.createKeybo().sayHi();
IPCFactory hpFactory = new HpFactory();
hpFactory.createMouse().sayHi();
hpFactory.createKeybo().sayHi();
}
}
增加一个厂商场景:
假设我们增加华硕工厂,则我们需要增加华硕工厂,和戴尔工厂一样,继承PC厂商。
之后创建华硕鼠标,继承鼠标类。创建华硕键盘,继承键盘类。即可。
uml变化图:
增加一个产品场景:
假设我们增加耳麦这个产品,则首先我们需要增加耳麦这个父类,再加上戴尔耳麦,惠普耳麦这两个子类。
之后在PC厂商这个父类中,增加生产耳麦的接口。最后在戴尔工厂,惠普工厂这两个类中,分别实现生产戴尔耳麦,惠普耳麦的功能。
uml变化图:
前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
使用抽象工厂模式一般要满足以下条件。
- 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
- 系统一次只可能消费其中某一族产品,即同族的产品一起使用。
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下:
- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当增加一个新的产品族时不需要修改原代码,满足开闭原则。
其缺点是:
- 当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。
总结
根据不同场景使用不同的工厂模式:
- 在简单场景下使用简单工厂;
- 一类产品的生产情景下使用工厂方法;
- 产品族的情境下使用抽象工厂;