工厂模式
概述:
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。工厂模式主要有3种,有简单工厂、工厂方法、抽象工厂。下面我们以“美女出门,穿衣打扮”为例子进行说明。
一、简单工厂模式
工厂类根据所传的参数决定创建那个实体。美女根据出门要办的事,决定穿那件衣服,比如出去约会,需要穿个裙子;如果去运动,那就那件运动装。
//定义一个衣服接口,不同衣服都需要实现该接口(有一个穿戴的方法) public interface SingleClothes { public void wear(); }
//定义个裙子实体 public class Skirt implements SingleClothes { @Override public void wear() { System.out.println("我要约会,我想穿裙子"); } } //定义一个运动服 public class SportSuit implements SingleClothes { @Override public void wear() { System.out.println("我要跑步,需要运动装"); } }
//定义一个工厂(根据参数生成对应的实体) public class ClothesFactory { public SingleClothes getClothes(String clothes){ if("skirt".equals(clothes)){ return new Skirt(); }else if("sportSuit".equals(clothes)){ return new SportSuit(); } return null; } }
此时我们要根据具体事件生产对应的实体类,代码如下
public class SingleClient { public static void main(String[] args) { ClothesFactory factory = new ClothesFactory(); SingleClothes skirt = factory.getClothes("skirt"); skirt.wear(); SingleClothes sportSuit = factory.getClothes("sportSuit"); sportSuit.wear(); } }
执行结果如下:

这就是所谓的简单工厂模式,但从例子我们可以看出,如果添加新的衣服类型,那必须修改ClothesFactory 的方法。这种模式不符合“开闭原则”(对扩展开放;对修改封闭)
二、工厂方法模式
该模式中,每个产品由指定的工厂生产,所有工厂都继承或实现一个抽象工厂。基于开闭原则,我们对简单工厂进行改造。
//定义一个抽象工厂 public interface MethodFactory { public SingleClothes getClothes(); } //定义裙子工厂 public class SkirtFactory implements MethodFactory { @Override public SingleClothes getClothes() { return new Skirt(); } } //定义运动装工厂 public class SportSuitFactory implements MethodFactory { @Override public SingleClothes getClothes() { return new SportSuit(); } }
同样我们需要定义想要的衣服对象
//定义一个衣服接口,不同衣服都需要实现该接口(有一个穿戴的方法) public interface SingleClothes { public void wear(); } //定义个裙子实体 public class Skirt implements SingleClothes { @Override public void wear() { System.out.println("我要约会,我想穿裙子"); } } //定义一个运动服 public class SportSuit implements SingleClothes { @Override public void wear() { System.out.println("我要跑步,需要运动装"); } }
此时我们要根据具体工厂生产对应的实体类,代码如下
public class MethodClient { public static void main(String[] args) { MethodFactory factory = new SkirtFactory(); SingleClothes cloths =factory.getClothes(); cloths.wear(); } }
这里我们生成了一个裙子,执行结果如下

如果我们这些要生成运动装,只需将MethodFactory factory = new SkirtFactory();改成MethodFactory factory = new SportSuitFactory();
可以看出代码得到一定的优化,当然最重要的是已经解决“开闭原则”,比如我们现在添加新的衣服(旗袍),那我们无需修改上面的代码,只需要添加对应的工厂和对象即可。
//旗袍实体类 public class Cheongsam implements SingleClothes { @Override public void wear() { System.out.println("我是淑女,我想穿旗袍"); } } //旗袍工厂 public class CheongsamFactory implements MethodFactory { @Override public SingleClothes getClothes() { return new Cheongsam(); } }
虽然上面解决了“简单工厂”的开闭原则,但每生成一个新产品,都需要一套工厂,比如我出门,我需要穿鞋,此时我需要新建一个抽象鞋工厂,然后再具体实现对应的写工厂(高跟鞋、运动鞋等),这样容易造成工厂泛滥。
三、抽象工厂模式
该模式主要用于生产一系列的产品,比如美女出门,需要选择对应的外套和鞋子。那这些产品可以由一个工厂配套产生,这样可以有效的解决“工厂方法模式”工厂泛滥的问题。这就是所谓的抽象工厂模式。
这里我产生两套产品,分别是“穿着高跟鞋和裙子去约会”和“穿着运动装和运动鞋去跑步”。首先我们除了定义上面衣服的实体对象,还需要定义鞋子的实体对象。
//定义一个鞋子接口,不同鞋子都需要实现该接口(有一个穿戴的方法) public interface SingleShoes { public void putOn(); } //定义运动鞋 public class SportShoes implements SingleShoes { @Override public void putOn() { System.out.println("穿着运动鞋去跑步"); } } //定义高跟鞋 public class HighheeledShoes implements SingleShoes { @Override public void putOn() { System.out.println("优雅的踩着高跟鞋"); } }
然后定义一个抽象工厂,该工厂主要用于生产一系列产品(衣服和写)
public interface AbstractFactory { public SingleClothes getClothes(); public SingleShoes getShoes(); }
//定义一个运动装工厂,用于生产运动装和运动鞋 public class SportswearFactory implements AbstractFactory { @Override public SingleClothes getClothes() { return new SportSuit(); } @Override public SingleShoes getShoes() { return new SportShoes(); } }
//定义一个休闲装工厂,用于生产裙子和高跟鞋 public class LeisureClothesFactory implements AbstractFactory { @Override public SingleClothes getClothes() { return new Skirt(); } @Override public SingleShoes getShoes() { return new HighheeledShoes(); } }
此时生产对应休闲套装代码如下:
public class AbstractClient { public static void main(String[] args) { AbstractFactory factory = new LeisureClothesFactory(); SingleClothes clothes = factory.getClothes(); clothes.wear(); SingleShoes shoes = factory.getShoes(); shoes.putOn(); } }
执行结果如下:

如果要生产别的套装,我们只需将AbstractFactory factory = new LeisureClothesFactory();改成AbstractFactory factory = new SportswearFactory();即可。这就是抽象工厂模式,虽然可以解决工厂泛滥的问题,但这个模式有个问题就是扩展性不好,如果我要新增新产品(帽子),那这些所有跟工厂相关的类就必须修改。
PS:曾经实现过跟工厂模式有关的功能:对外接口

浙公网安备 33010602011771号