工厂模式
工厂模式,顾名思义,属于创建型模式,在一个项目中也是经常被使用的一种模式。工厂模式分为简单工厂、工厂方法、抽象工厂三种模式。工厂模式可以使客户通过简单的调用方法来获取相关联或者继承同一父类的子类对象,方便了程序的扩展性,将客户代码与对象的创建进行解耦,客户代码不必关系对象创建的逻辑就可以直接获取自己想要的对象。
简单工厂模式
简单工厂模式体现在简单二字,即一个工厂类就可以构造出客户所需要的对象,通过根据客户传入的条件实参来构建相对应的子类对象。代码如下:
interface IMessage {
public void sendMsg();
}
class RequsetMessage implements IMessage {
public void sendMsg() {
System.out.println("this is request message!");
}
}
class ResponseMessage implements IMessage {
public void sendMsg() {
System.out.println("this is reponse message!");
}
}
// Simple factory
class MessageFactory {
public static IMessage getMessage(int nMessageType) {
IMessage message = null;
switch (nMessageType) {
case 0:
message = new RequsetMessage();
break;
case 1:
message = new ResponseMessage();
break;
default:
break;
}
return message;
}
}
简单工厂模式在子类过多时,条件语句也会随之变多,这个时候我们可以使用表驱动的方式进行对象的构建。
工厂方法
我们在简单工厂中发现,客户代码虽然不去关注构建对象的逻辑,但是需要关注类的标识符(工厂类中静态方法的形参),同时我们需要增加一个类的时候,需要新增case,这种情况是破环了设计上的开闭原则(一般情况下可以舍弃这个原则)。所以工厂方法便解决了上面所说的。工厂方法是将一个工厂变成多个工厂,每个工厂之负责自己的类对象的构建,保持单一职责,且新增一个子类的时候,我们只需要新增一个工厂类即可。
// Factory method
interface IMessageFactory {
public IMessage createMessage();
}
class RequestMessageFactory implements IMessageFactory {
public IMessage createMessage() {
return new RequsetMessage();
}
}
class ResponseMessageFactory implements IMessageFactory {
public IMessage createMessage() {
return new ResponseMessage();
}
}
如上,工厂方法就是将工厂抽象话,然后让各个工厂各司其职,对自己负责的类进行构建,当对象的初始化需要过多的逻辑、复杂程度过高时,工厂方法的优势就有所体现。当构建一个子类对象只需要一条简单的new语句的话,一般建议使用简单工厂就可以了。
抽象工厂
抽象工厂是工厂方法的特殊模式,它的使用一般适用于产品族的概念,它适用于的一般情况是:继承不同父类的子类,但是这些子类又同属于一个管理池或者产品池中。可见它的使用一般适合业务相关的。
举个例子,一家文具公司有两个产品线:分别是星辰和青春系列的文具,那么文具中都有铅笔和橡皮,两者属于不同的产品风格,但是星辰铅笔和青春铅笔又继承同一个接口铅笔,同理橡皮也是,那么在这种业务情况下我们将同一产品下的文具归属到同一个工厂中是合理的,这种抽象到具体业务的工厂更加适合在当前业务中对该产品线的统一管理,从而保证了上层客户对产品线的切换,方便了客户代码的重用。
// Abstract factory
interface IPencil {
public void write();
}
interface IRubber {
public void erase();
}
class StarPencil implements IPencil {
public void write() {
System.out.println("This is the pencil of the Star product line.");
}
}
class StarRubber implements IRubber {
public void erase() {
System.out.println("This is the rubber of the Star product line.");
}
}
class YouthPencil implements IPencil {
public void write() {
System.out.println("This is the pencil of the Youth product line.");
}
}
class YouthRubber implements IRubber {
public void erase() {
System.out.println("This is the rubber of the Youth product line.");
}
}
interface IStationeryFactory {
public IPencil createPencil();
public IRubber createRubber();
}
class StarStationeryFactory implements IStationeryFactory {
public IPencil createPencil() {
return new StarPencil();
}
public IRubber createRubber() {
return new StarRubber();
}
}
class YouthStationeryFactory implements IStationeryFactory {
public IPencil createPencil() {
return new YouthPencil();
}
public IRubber createRubber() {
return new YouthRubber();
}
}
如上,我们将统一产品线的文具放到一个工厂中,提供不同的获取方法,方便客户代码获取不同产品线下的文具对象。
客户代码
以下是客户代码,分别对三种工厂模式的使用:
public static void main(String[] args) {
// TODO Auto-generated method stub
IMessage sampleMessage = MessageFactory.getMessage(0);
sampleMessage.sendMsg();
IMessageFactory messageFactory = new ResponseMessageFactory();
IMessage methodMessage = messageFactory.createMessage();
methodMessage.sendMsg();
IStationeryFactory stationeryFactory = new StarStationeryFactory();
IPencil abstractPencil = stationeryFactory.createPencil();
abstractPencil.write();
IRubber abstractRubber = stationeryFactory.createRubber();
abstractRubber.erase();
}
说明
对于一些简单或者经常使用的入门级设计模式,这里就不去花费太多的时间贴出UML设计类图了,必要时,再后续的设计模式总结种会有类图来加强理解。
当然,设计模式本质上学起了不难,主要是如何将其体现在项目种,发挥出其作用才是其关键,有时单独列出一些简单的实例是看不出来它的作用,但是结合项目的上下文,变通的将其融入到项目中,对我们的代码、架构设计能力都是有很大的帮助的。