此文将工厂模式和抽象工厂模式整理在一起,因静态工厂模式涉及到"是否应该代替构造器"等很多其他的问题,故本文将静态工厂模式单独拿出,以后另起一篇详细讲解.
工厂模式按模式类型分为三种:
1. 简单工厂模式
2. 工厂方法模式
3. 抽象工厂模式
1.简单工厂模式:创建一个工厂类,对实现了同一接口的一些类进行实例的创建.
有些说法认为简单工厂模式仅仅只是用来创建对象的一个类,并不算23种设计模式之一.
请看下例:
创建一个共同的接口
public interface Phone {//工厂方法产生的对象,返回值全部由此接口接收
public void call();
}
其次,创建实现类:
public class Ipone/* 生产苹果手机的工厂 */ implements Phone {
{// 我们只关心工厂是否创建对象,所以通过代码块来测试,下文不使用对象具体的功能(方法)
System.out.println("make a Ipone!");// 生产一个苹果手机
}
@Override
public void call() {
System.out.println("用苹果打电话");
}
}
public class Huawei/* 生产华为手机的工厂 */ implements Phone {
{
System.out.println("make a Huawei!");// 生产了一个华为手机
}
@Override
public void call() {
System.out.println("用华为打电话");
}
}
最后,建工厂类:
public class PhoneFactory_Simple {
public Phone producePhone(String phoneType/* 手机类型 */) {
if ("Ipone".equals(phoneType)) {
return new Ipone();
} else if ("Huawei".equals(phoneType)) {
return new Huawei();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
我们来测试下:
public class Test01 {
public static void main(String[] args) throws Exception {
PhoneFactory_Simple factor = new PhoneFactory_Simple();
Phone Huawei = factor.producePhone("Huawei");
Phone Ipone = factor.producePhone("Ipone");
factor.producePhone("Xiaomi");
}
}
结果:
make a Huawei!
make a Ipone!
请输入正确的类型!
2.工厂方法模式:是对简单工厂模式的功能的增强与解耦,在简单工厂模式中,如果传递的字符串出错,则不能正确创建对象,而工厂方法模式是直接提供多个工厂方法,直接调用方法创建对象,不需传递参数,而且产品的种类没有限制.
下面我们新建一个电脑接口:
public interface Computer {
public void play();
}
创建一个Lenova实现类
public class Lenova implements Computer {
{
System.out.println("make a Lenova!");
}
@Override
public void play() {
System.out.println("用联想玩游戏!");
}
}
那么改写之后的工厂类代码如下:
public class Factory {
public static Phone produceIpone()/* 生产苹果 */ {
return new Ipone();
}
public static Phone produceHuawei()/* 生产华为 */ {
return new Huawei();
}
public static Computer produceLenova()/* 生产联想 */ {
return new Lenova();
}
}
测试代码如下:
public class Test02 {
public static void main(String[] args) throws Exception {
Factory factory = new Factory();
Phone huawei = factory.produceHuawei();
Phone ipone = factory.produceIpone();
Computer lenova = factory.produceLenova();
}
}
结果:
make a Huawei!
make a Ipone!
make a Lenova!
3.抽象工厂模式(Abstract Factory)
工厂方法模式有一个问题,类的创建依赖工厂类,如果想要拓展程序,必须对工厂类进行修改,这就违背了开闭原则(Open Closed Principle),从设计角度考虑,为解决此问题就需要用到抽象工厂模式,将工厂也抽象化,这样一旦需要增加新的功能,直接增加新的工厂类实现抽象工厂接口就可以了,不需要修改之前的代码,在工厂方法模式的基础上进一步增强了功能和解耦.
请看下例:
提供一个生产手机和一个生产电脑的接口,将工厂抽象化,需要生产商品的时候实例化相应接口建造一个工厂即可
public interface PhoneFactor {
public Phone producePhone();
}
public interface ComputerFactor {
public Computer produceComputer();
}
想生产什么类型的东西,只需要实现对应的工厂接口即可
下面我们创建一个生产Mac的工厂和一个生产小米的工厂,为避免文章冗余,Mac和小米的具体类就不写了
生产Mac的工厂
public class HuaweiFactor implements PhoneFactor {
@Override
public Phone produce() {
return new Huawei();
}
}
生产小米的工厂
public class MacFactor implements ComputerFactor {
@Override
public Computer produceComputer() {
return new Mac();
}
}
测试代码:
public class Test03 {
public static void main(String[] args) throws Exception {
XiaoMiFactor xiaoMiFactor = new XiaoMiFactor();
Phone phone = xiaoMiFactor.producePhone();
MacFactor macFactor = new MacFactor();
Computer computer = macFactor.produceComputer();
}
}
结果:
make a XiaoMi !
make a Mac!
总结
工厂模式适合在需要大量创建对象的时候使用,从简单工厂模式到工厂方法模式,再到抽象工厂模式是一个功能扩展和解耦的过程,下面举例说明:
1.简单工厂模式:小作坊,只能生产某一类产品(实现了同一接口)且种类有限,还得你提供材料(传入参数),功能有限.
2. 工厂方法模式:已经升级为大工厂,想造什么直接来选(直接调用空参方法,可根据方法名来辨识),在简单工厂模式的基础上功能已经有所扩展,但是工厂类还是固定的,想要生产其他产品就必须改造此工厂(继承此工厂类增加新方法),产品与工厂之间的耦合性还是太高.
3. 抽象工厂模式:工厂是抽象的,我已经不是clearlove了,你想造什么告诉我,我先根据需求造一个工厂出来(实现对应的工厂接口),不用改造已存在工厂(改代码),扩展性强,耦合性低.
网友评论