一.简单工厂模式
概念:建立一个工厂类,对实现了同一接口的一些类进行实例的创建。
实质:由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
示例代码:
创建产品(手机)接口:
interface Phone {
public void type();
}
创建具体的类实现手机接口(小米手机类):
public class XiaoMiPhone implements Phone {
@Override
public void type() {
System.out.println("小米手机");
}
}
创建具体的类实现手机接口(华为手机类):
public class HuaWeiPhone implements Phone {
@Override
public void type() {
System.out.println("华为手机");
}
}
简单工厂,既能买小米又能买华为:
public class PhoneFactory {
public static Phone buyPhone(String type) {
if ("xiaomi".equals(type)) {
return new XiaoMiPhone();
} else if ("huawei".equals(type)) {
return new HuaWeiPhone();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
测试类:
public class FactoryTest {
public static void main(String[] args) {
Phone phone = PhoneFactory.buyPhone("xiaomi");
phone.type();
}
}
特点:1.它是一个具体的类,非接口 抽象类。有一个重要的create()方法,方法里面利用if或者 switch创建产品并返回。
2.create()方法通常是静态的,所以也称之为静态工厂。
优点:客户端不需要再负责对象的创建,从而明确了各个类的职责。简单来说就是客户端只需要用就可以了,不用创建,由工厂来创建。
缺点:这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断地修改工厂类,不利于后期的维护
二、工厂方法模式
概念:定义一个用于创建对象的接口,但是让子类来决定到底创建哪一个实例。工厂方法模式让一个类的实例化延迟到其子类。简单理解就是为了解决简单工厂模式所出现的一些缺点而进行的改进。以上面的简单工厂为例,假如我们还需要加入一个vivo手机类。那我们是不是就要修改源代码,也就是修改工厂的源代码!添加一个业务逻辑,这显然不符合开闭原则,所以就有了工厂方法模式。提供一个抽象工厂方法模式,这样就可以避免新增的时候修改源代码,只要新建一个类来继承了工厂方法模式即可。
示例:
我们就以上面的简单工厂类例子接着改造!
创建产品(手机)接口:
interface Phone {
public void type();
}
创建具体的类实现手机接口(小米手机类):
public class XiaoMiPhone implements Phone {
@Override
public void type() {
System.out.println("小米手机");
}
}
创建具体的类实现手机接口(华为手机类):
public class HuaWeiPhone implements Phone {
@Override
public void type() {
System.out.println("华为手机");
}
}
接下来我们需要创建一个工厂类,既然每一个手机都有自己的工厂类,那是不是可以抽一个工厂接口呢!
工厂接口类:
public interface Factory {
Phone buyPhone();
}
创造小米的工厂类:
public class XiaoMiFactory implements Factory {
@Override
public Phone buyPhone() {
return new XiaoMiPhone();
}
}
创造华为的工厂类:
public class HuaWeiFactory implements Factory {
@Override
public Phone buyPhone() {
return new HuaWeiPhone();
}
}
测试:
public class FactoryTest {
public static void main(String[] args) {
Factory xiaoMiFactory = new XiaoMiFactory();
Phone buyXiaoMi = xiaoMiFactory.buyPhone();
buyXiaoMi.type();
Factory huaWeiFactory = new HuaWeiFactory();
Phone buyHuaWei = huaWeiFactory.buyPhone();
buyXiaoMi.type();
}
}
如果还有其他具体的手机类要加入,我们只需要再增加一个具体的手机类和具体的实现工厂类就行了!这就不用去改变我们的源代码了
可能大家从以上的编写的代码可以看到,工厂方法模式看起来要比起简单工厂要麻烦不少,一个产品类就要对应一个工厂类,要增加产品类时也要相应地增加工厂类,客户端的代码也增加了不少。确实,简单工厂是要简便点,所以它不适合应用在比较大的项目里,而且大部分情况下也是简单工厂常用。不过你得先事先考虑好简单工厂是否无法承受你的项目,如果不能承受,就应该考虑使用工厂方法模式吧。
三、抽象工厂模式
概念:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。简单来理解在工厂方法模式中,其实我们有一个潜在意识的意识。那就是我们生产的都是同一类产品。抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一种产品,而是可以创建一组产品。
示例:
我们就以上面的工厂模式类例子接着改造!
创建产品(手机)接口:
interface Phone {
public void type();
}
创建具体的类实现手机接口(小米手机类):
public class XiaoMiPhone implements Phone {
@Override
public void type() {
System.out.println("小米手机");
}
}
创建具体的类实现手机接口(华为手机类):
public class HuaWeiPhone implements Phone {
@Override
public void type() {
System.out.println("华为手机");
}
}
创建产品(数据线)接口:
public interface DataLine {
void type();
}
创建具体的类实现手机数据线接口(小米手机数据线类):
public class XiaoMiDataLine implements DataLine {
@Override
public void type() {
System.out.println("小米数据线");
}
}
创建具体的类实现手机数据线接口(华为手机数据线类):
public class HuaWeiDataLine implements DataLine {
@Override
public void type() {
System.out.println("华为数据线");
}
}
工厂接口类:同能能买手机数据线
public interface Factory {
Phone buyPhone();
DataLine buyDataLine();
}
创造小米的工厂类:
public class XiaoMiFactory implements Factory{
@Override
public Phone buyPhone() {
return new XiaoMiPhone();
}
@Override
public DataLine buyDataLine() {
return new XiaoMiDataLine();
}
}
创造华为的工厂类:
public class HuaWeiFactory implements Factory{
@Override
public Phone buyPhone() {
return new HuaWeiPhone();
}
@Override
public DataLine buyDataLine() {
return new HuaWeiDataLine();
}
}
测试:
public class FactoryTest {
public static void main(String[] args) {
Factory xiaoMiFactory=new XiaoMiFactory();
Phone buyXiaoMi = xiaoMiFactory.buyPhone();
DataLine buyXiaoMiDataLine = xiaoMiFactory.buyDataLine();
buyXiaoMi.type();
buyXiaoMiDataLine.type();
Factory huaWeiFactory=new HuaWeiFactory();
Phone buyHuaWei = huaWeiFactory.buyPhone();
DataLine buyHuaWeiDataLine = huaWeiFactory.buyDataLine();
buyHuaWei.type();
buyHuaWeiDataLine.type();
}
}
与工厂模式的区别:抽象工厂是生产一整套有产品的(至少要生产两个产品),这些产品必须相互是有关系或有依赖的,而工厂方法中的工厂是生产单一产品的工厂。