工厂模式
一、介绍:
1、 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
2、 主要解决的问题:主要解决接口选择的问题。
3、 何时使用:我们明确地计划不同条件下创建不同实例时。
4、 优点:
(1)一个调用者想创建一个对象,只要知道其名称就可以了。
(2)扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
(3)屏蔽产品的具体实现,调用者只关心产品的接口。
5、 缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,
同时也增加了系统具体类的依赖。
二、实现的方式:
问题一:以冰淇淋为例,不同口味的冰淇淋如何快速的生产出来
1、简单工厂模式:
第一步、定义一个冰激凌接口,里边只有一个方法,就是显示是哪种口味:
public interface IceCream {
public void taste();
}
第二步、 定义三个类:AppleIceCream、BananaIceCream、OrangeIceCream,并继承上面的接口,实现其中的方法。显示自己独特的口味
public class AppleIceCream implements IceCream {
public void taste(){
System.out.println("这是苹果口味的冰激凌");
}
}
public class BananaIceCream implements IceCream {
public void taste() {
System.out.println("这是香蕉口味的冰激凌");
}
}
public class OrangeIceCream implements IceCream{
public void taste(){
System.out.println("这是橘子口味的冰激凌");
}
}
第三步、 定义一个工厂类,用来制作不同口味的冰激凌
public class IceCreamFactory {
public static IceCream creamIceCream(String taste){
IceCream iceCream = null; // 这里我们通过switch来判断,具体制作哪一种口味的冰激凌
switch(taste){
case "Apple":
iceCream = new AppleIceCream();
break;
case "Orange":
iceCream = new OrangeIceCream();
break;
case "Banana":
iceCream = new BananaIceCream();
break;
default: break;
}
return iceCream;
}
}
第四步、测试,通过统一的工厂,传入不同参数调用生产冰激凌的方法去生产不同口味的冰激凌
public class Client {
public static void main(String[] args) {
IceCream appleIceCream = IceCreamFactory.creamIceCream("Apple");
appleIceCream.taste();
IceCream bananaIceCream = IceCreamFactory.creamIceCream("Banana");
bananaIceCream.taste();
IceCream orangeIceCream = IceCreamFactory.creamIceCream("Orange");
orangeIceCream.taste();
}
}
问题二:整个机器已经做成了,按钮数目为3也已经固定了,如果想要再添加一种口味,那么就要打开机器内部,往里边添加制作草莓味冰激凌的原料以及制作工艺,还要在机器外部再增加一个按钮。这可麻烦了,毕竟整个机器的布局什么的都固定下来了。
2、工厂方法模式
第一步、 和简单工厂模式一样,先定义一个接口。再定义AppleIceCream、BananaIceCream和OrangeIceCream去实现这个接口:
第二步、 定义工厂接口
public interface IceCreamFactory {
public IceCream createIceCream();
}
第三步、 再分别定义AppleIceCreamFactory、BananaIceCreamFactory、OrangeIceCreamFactory,继承刚刚定义的工厂接口:
public class AppleIceCreamFactory implements IceCreamFactory {
public IceCream createIceCream() {
return new AppleIceCream();
}
}
public class BananaIceCreamFactory implements IceCreamFactory {
public IceCream createIceCream() {
return new BananaIceCream();
}
}
public class OrangeIceCreamFactory implements IceCreamFactory{
public IceCream createIceCream() {
return new OrangeIceCream();
}
}
第四步、测试
public class Client {
public static void main(String[] args) {
//生产苹果味冰激凌
IceCreamFactory appleFactory = new AppleIceCreamFactory();
IceCream appleIceCream = appleFactory.createIceCream();
appleIceCream.taste();
//生产香蕉口味冰激凌
IceCreamFactory bananaFactory = new BananaIceCreamFactory();
IceCream bananaIceCream = bananaFactory.createIceCream();
bananaIceCream.taste();
//生产橘子口味冰激凌
IceCream orangeIceCream = new OrangeIceCreamFactory().createIceCream();
orangeIceCream.taste();
}
}
问题三、 不同人的需求是不同的,有的人吃冰激凌是当做饭后甜点,有的人直接把它当饭吃。因此,为了让顾客有多种选择,想要对每种口味冰激凌的量进行分类,分为大份和小份的。比如我们之前生产的是大份的冰激凌,那么要完成生产多种口味小份的冰激凌,如何解决?
3、抽象工厂模式
第一步、 由于要生产不同大小的冰激凌,所以,现在冰激凌的接口有两个,分别是 BigIceCream 和 SmallIceCream:
public interface BigIceCream {
public void taste();
}
public interface SmallIceCream {
public void taste();
}
第二步、 定义各个口味的冰激凌,继承刚刚定义的接口,实现其方法:
public class BigAppleIceCream implements BigIceCream {
public void taste() {
System.out.println("这是苹果味冰激凌(大份)");
}
}
public class SmallAppleIceCream implements SmallIceCream {
public void taste() {
System.out.println("这是苹果味冰激凌(小份)");
}
}
后边还有四个类BigBananaIceCream、SmallBananaIceCream、BigOrangeIceCream、SmallOrangeIceCream 省略
第三步、 定义工厂接口,有两个方法,分别生产小份大的和大份的:
public interface IceCreamFactory {
public BigIceCream createBigIceCream();
public SmallIceCream createSmallIceCream();
}
第四步、 定义三个工厂类继承上边的接口并实现其方法
public class AppleIceCreamFactory implements IceCreamFactory {
public BigIceCream createBigIceCream() {
return new BigAppleIceCream();
}
public SmallIceCream createSmallIceCream() {
return new SmallAppleIceCream();
}
}
public class BananaIceCreamFactory implements IceCreamFactory {
public BigIceCream createBigIceCream() {
return new BigBananaIceCream();
}
public SmallIceCream createSmallIceCream() {
return new SmallBananaIceCream(); 、
}
}
public class OrangeIceCreamFactory implements IceCreamFactory {
public BigIceCream createBigIceCream() {
return new BigOrangeIceCream();
}
public SmallIceCream createSmallIceCream() {
return new SmallOrangeIceCream();
}
}
第五步、测试:
public class Client {
public static void main(String[] args) {
//生产苹果味冰激凌
IceCreamFactory appleIceCreamFactory = new AppleIceCreamFactory();
BigIceCream appleBigIceCream = appleIceCreamFactory.createBigIceCream();
SmallIceCream appleSmallIceCream = appleIceCreamFactory.createSmallIceCream();
appleBigIceCream.taste();
appleSmallIceCream.taste();
//生产香蕉口味冰激凌
IceCreamFactory bananaIceCreamFactory = new BananaIceCreamFactory();
BigIceCream bananaBigIceCream = bananaIceCreamFactory.createBigIceCream();
SmallIceCream bananaSmallIceCream = bananaIceCreamFactory.createSmallIceCream();
bananaBigIceCream.taste();
bananaSmallIceCream.taste();
//生产橘子口味冰激凌
IceCreamFactory orangeIceCreamFactory = new OrangeIceCreamFactory();
BigIceCream orangeBigIceCream = orangeIceCreamFactory.createBigIceCream();
SmallIceCream orangeSmallIceCream = orangeIceCreamFactory.createSmallIceCream();
orangeBigIceCream.taste();
orangeSmallIceCream.taste();
}
}
三、总结:
1、简单工厂模式适用于工厂类需要创建的对象比较少的情况,客户只需要传入具体的参数,就可以忽略工厂的生产细节,去获取想要的对象;
2、工厂方法模式,主要是针对单一产品结构的情景;
3、抽象工厂模式则是针对多级产品结构(系列产品)的一种工厂模式。
每种模式都有自己的优点和弊端,没有最好的模式,只有最适合的模式,只要符合实际开发需求就是最好的。