简单工厂模式又被称为静态模式,其实现简单,实现过程基本遵循如下过程:
但是严格意义来说,简单工厂模式并不算一个真正的"设计模式"。
The Simple Factory isn’t actually a Design Pattern; it’s more of a programing idiom. But it is commonly used, so we’ll give it a Head First Pattern Honorable Mention.
在Head First原书中,有上述的提及,说明简单工厂只是一种被开发人员所普遍使用的编程风格。
但是我们还是简单地介绍一下该模式,首先其类图如下:
从类图中我们可以看到,有一个产品接口,并派生了两个具体产品ProductA
及ProductB
,而工厂的职责便是负责生产这些产品,我们可以有如下的实现。
接口类:
public interface Product {
public void doSomeThing();
}
产品A类:
public class ProductA implements Pruduct {
public void doSomeThing() {
System.out.println("A do...");
}
}
产品B类:
public class ProductB implements Pruduct {
public void doSomeThing() {
System.out.println("B do...");
}
}
工厂类:
public ProductFactory {
public static Product produceProduct(String name) {
if ("A".equals(name)) {
return new ProductA();
} else if ("B".equals(name)) {
return new ProductB();
}
}
}
客户端类:
public class SimpleFactoryClient {
public static void main(String[] args) {
Product product = ProductFactory.produceProduct("A");
product.doSomeThing();
product = ProductFactory.produceProduct("B");
product.doSomeThing();
}
}
通过上述代码,即可使用工厂快速通过参数的不同,动态地获取到不同的产品,并使用产品的方法。
从实现中我们可以看出,对于产品类而言,其具体的创建过程交给了工厂,而客户端在获得产品时,不再需要手动地new
创建对象,而时根据产品名称动态地获取到所需要的产品,因此简单工厂能够将对象的创建过程和对象的使用过程隔离。
在Head First中,其使用了Pizza的例子,对简单工厂模式进行说明举例。
该例子也说明了简单工厂的具体模式,不同的是在该类图中依赖关系将其画到了SimplePizzaFactory
与Pizza
之间,但其意义相同。
public class DateFormateTest {
public static void main(String[] args) {
DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT);
String now = format.format(new Date());
System.out.println(now);
}
}
通过使用DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT);
可以快速获得一个DateFormat
对象,而只需要提供DateStyle
和TimeStyle
,这便是一个简单工厂模式的应用,在JDK中,DateFormat
为一个抽象类,而其子类有SimpleDateFormat
类,但通过使用简单工厂,仅需要指定style
即可获得格式化类,客户端无需关心具体的格式化类是什么。
不仅如此,在JDK加密算法的实现中,也使用了简单工厂。
public class CipherTest {
public static void main(String[] args) {
try {
KeyGenerator aes = KeyGenerator.getInstance("AES");
SecretKey secKey = aes.generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secKey);
byte[] encoded = cipher.doFinal("Hello World".getBytes("utf-8"));
System.out.println(new String(encoded, "utf-8"));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
优点:
缺点:
上述代码可访问Github获取。