设计模式有很多种类型,见runoob上的分类。主要的三种设计模式:创建型模式、结构型模式、行为型模式,分别关注对象的创建、组合、通信,它们是实现业务的最基本的元素。
工厂模式
简述
使用工厂类创建产品对象时不会对外暴露创建逻辑。创建逻辑不见得仅仅是new
调用构造方法,还可能包括一些初始化操作,工厂模式适合于完成复杂对象的创建,简单对象(如new
直接创建的对象)不需要使用工厂模式,因为引入的工厂类会让系统变得复杂。
示例
产品接口
public interface Product {
//产品对象的某个行为
void action();
}
所有的产品类都实现这个产品接口,这是出于依赖倒置的考虑。
工厂类
public class ProductFactory {
//生产产品
public Product getProduct(String name){
if("A".equals(name))
return new ProductA();
else if("B".equals(name))
return new ProductB();
return null;
}
}
优势
使用工厂类,在创建具有同类行为的产品对象(用接口约定保证)时解除了对具体的产品实现类的耦合。还能屏蔽复杂对象的创建逻辑。
抽象工厂模式
简述
抽象工厂是对多个工厂模式的进一步抽象,当多个工厂生产同样的几类产品时,适合使用抽象工厂对创建产品对象的方法进一步抽象。不同的工厂有着自己对这类产品的一种或多种实现。
示例
程序接口
下面鼠标和键盘是IO设备产品接口,假设Dell和Acer两个工厂都可以生产IO设备类的产品;USB是插口设备产品的接口,假设Dell工厂也可以生产插口类产品。另外,每个工厂的同一种产品也可以有多种实现型号。
抽象工厂(以IOFactory为例)
Java是单继承的,不妨用接口而不用抽象类。
package org.lzh.factory;
import org.lzh.keyboard.Keyboard;
import org.lzh.mouse.Mouse;
public interface IOFactory {
Mouse getMouse(String version);//抽象工厂创建抽象的鼠标
Keyboard getKeybord(String version);//抽象工厂创建抽象的键盘
}
具体的工厂(以DellFactory为例)
一个工厂可以实现多个抽象工厂,以生产多种类别的产品。
package org.lzh.factory.imp;
import org.lzh.factory.IOFactory;
import org.lzh.factory.JackFactory;
import org.lzh.keyboard.Keyboard;
import org.lzh.keyboard.imp.KB_Dell_001;
import org.lzh.keyboard.imp.KB_Dell_002;
import org.lzh.mouse.Mouse;
import org.lzh.mouse.imp.MS_Dell_001;
import org.lzh.usb.USB;
import org.lzh.usb.imp.USB_Dell_30;
//Dell工厂既是IO外设抽象工厂的实现类,也是Jack插口工厂的实现类
public class DellFactory implements IOFactory,JackFactory {
@Override
public Mouse getMouse(String version) {
if (version.equals("001"))
return new MS_Dell_001();
return null;
}
@Override
public Keyboard getKeybord(String version) {
if (version.equals("001"))
return new KB_Dell_001();
else if (version.equals("002"))
return new KB_Dell_002();
return null;
}
@Override
public USB getUSB(String version) {
if (version.equals("30"))
return new USB_Dell_30();
return null;
}
}
产品接口(以Mouse为例)
和工厂模式一样,产品接口约定了产品的方法等,各个工厂生产的该种产品实现类对象都需要实现这些方法。
package org.lzh.mouse;
public interface Mouse {
void click(boolean which);
void doubleClick(boolean which);
}
产品的实现类(以MS_Acer_001为例)
package org.lzh.mouse.imp;
import org.lzh.mouse.Mouse;
public class MS_Acer_001 implements Mouse {
@Override
public void click(boolean which) {
System.out.println("使用Acer生产的001号鼠标对"+(which?"左":"右")+"键进行了单击");
}
@Override
public void doubleClick(boolean which) {
System.out.println("使用Acer生产的001号鼠标对"+(which?"左":"右")+"键进行了双击");
}
}
优势
当系统中有多于一种的产品族(如例子中的外设、插口),以及多种实现这些产品的工厂时,可以用抽象工厂将这一产品族的产品的生产抽象起来,而无需指明实现类,各个工厂只需要去实现抽象工厂对这些产品的生产方法就可以了。
注意
一个产品族对应了多个产品接口。产品族(这里即抽象工厂)的扩展是比较麻烦的,一旦在抽象工厂中加抽象方法,具体的实现了该工厂的类也都要改动。
参考阅读
[1] 抽象工厂模式-runoob