工厂模式
为什么要使用工厂模式:
工厂模式归根到底,就是将项目主程序中,对象实例化部分抽取出来,从而达到跟主程序解构,以便于项目以后拥有更好的扩展性和维护性。
简单工程模式:
通俗点讲,就是将程序中碰到if...new if...new 的代码提炼到一个静态工厂里面进行实现,这样做的好处以后新增加一种类型对象,不需要调整主程序,只需要调整静态工厂即可。
UML图示:
需要获取类具体实例的程序,通过给简单工厂传入需要具体实例化对象的标记,简单工厂根据标记,new出具体对象返回给使用者。
、
代码示例:
假设需求是这样的,类似宜家一样,用户逛完商店后,记录需要购买的商品的名字,将购买单给服务员,服务员在系统输入商品名字,系统自动带出商品的位置。
需求分析:商品是可变的,而系统定位商品功能这个主程序功能是固定的,是不可变的,需要将可变的商品提炼出来,和主程序解构,以便后期商品的维护和扩展。用简单工厂实现代码如下:
商品抽象类:
public abstract class Produce { //获取商品位置 public abstract void getProduce(); }
具体商品1:
public class NuomilaChair extends Produce { public void getProduce() { System.out.println("诺米拉椅子放在三区12号位置"); } }
具体商品2:
public class AigeChair extends Produce { public void getProduce() { System.out.println("爱格椅子放在三区11号位置"); } }
简单工厂类:
public class SimpleFactory { public Produce findProduce(String name) { Produce produce = null; //新增加商品只需要在工厂类调整,不需要调整主程序代码,实现解耦。 if (name.equals( "Aige")) { produce = new AigeChair(); } else if (name.equals("Nuomila")) { produce = new NuomilaChair(); } return produce; } }
系统类:
public class ProduceSystem { SimpleFactory sf = null; public ProduceSystem(SimpleFactory sf) { this.sf = sf; } public void runSystem() { Produce pro = null; String proName = null; do { try { proName = getProduceName(); pro = this.sf.findProduce(proName); pro.getProduce(); } catch (Exception e) { e.printStackTrace(); System.out.println("输入有误或者不存在该商品!"); } } while (true); } private String getProduceName() { String str = null; System.out.println("请输入商品名字:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { str = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return str; } }
启动程序:
public static void main(String[] args) { new ProduceSystem(new SimpleFactory()).runSystem(); }
工厂模式:
定义了一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法将对象实例化推迟到子类。基于上面讲到的简单工厂方法,即将SimpleFactory设计为抽象方法,由子类继承后实现具体方法。
UML图示 :
实际上就是基于简单工厂,将简单工厂这种静态工厂抽象化,变得更加灵活和可扩展性

代码示例:
基于上面需求,现在该商场是连锁店,每个店的商品的在仓库的摆放位置都不一样,很明显之前的代码很难满足需求,需要将上面的简单工厂进行抽象化,每家连锁店各自实现商品的摆放位置。
代码如下:
商品抽象类:
public abstract class Produce { //获取商品位置 public abstract void getProduce(); }
商品1:
public class AigeChairA extends Produce { public void getProduce() { System.out.println("爱格椅子放在三区11号位置"); } }
商品2:
public class AigeChairB extends Produce { public void getProduce() { System.out.println("爱格椅子放在一区11号位置"); } }
商品3:
public class NuomilaChairA extends Produce { public void getProduce() { System.out.println("诺米拉椅子放在三区12号位置"); } }
商品4:
public class NuomilaChairB extends Produce { public void getProduce() { System.out.println("诺米拉椅子放在二区12号位置"); } }
工厂超类:
public abstract class Factory { public abstract Produce findProduce(String name); }
工厂A:
public class FactoryA extends Factory { @Override public Produce findProduce(String name) { Produce produce = null; //每个工厂各自维护自己的商品 if (name.equals( "Aige")) { produce = new AigeChairA(); } else if (name.equals("Nuomila")) { produce = new NuomilaChairA(); } return produce; } }
工厂B:
public class FactoryB extends Factory { @Override public Produce findProduce(String name) { Produce produce = null; //每个工厂各自维护自己的商品 if (name.equals( "Aige")) { produce = new AigeChairB(); } else if (name.equals("Nuomila")) { produce = new NuomilaChairB(); } return produce; } }
系统类:
public class ProduceSystem { Factory sf = null; public ProduceSystem(Factory sf) { this.sf = sf; } public void runSystem() { Produce pro = null; String proName = null; do { try { proName = getProduceName(); pro = this.sf.findProduce(proName); pro.getProduce(); } catch (Exception e) { e.printStackTrace(); System.out.println("输入有误或者不存在该商品!"); } } while (true); } private String getProduceName() { String str = null; System.out.println("请输入商品名字:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { str = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return str; } }
启动类:
public static void main(String[] args) { new ProduceSystem(new FactoryA()).runSystem(); }
抽象工厂模式
定义了接口用于创建相关或者有依赖依赖关系的对象族,而无需指定具体类
UML图示:
和工厂模式对比,工厂不是只是生产一类产品,而是生成多种不通种类的产品。

代码示例:
基于上面需求,商店定义,该连锁店的商品,只固定卖椅子,床.....等,每家连锁店只能在这些商品。(注意,抽象工厂模式在抽象工厂里面定一个的产品组合后,后续如果需要调整的话,极其麻烦)
商品抽象类A:
public abstract class Bed { //获取商品位置 public abstract void getProduce(); }
商品抽象类B:
public abstract class Chair { //获取商品位置 public abstract void getProduce(); }
商品A具体类1:
public class BedA extends Bed { public void getProduce() { System.out.println("百灵床放在一区10号位置"); } }
商品A具体类2:
public class BedB extends Bed { public void getProduce() { System.out.println("马尔姆放在三区17号位置"); } }
商品B具体类1:
public class ChairA extends Chair { public void getProduce() { System.out.println("爱格椅子放在三区11号位置"); } }
商品B具体类2:
public class ChairB extends Chair { public void getProduce() { System.out.println("诺米拉椅子放在二区12号位置"); } }
工厂抽象类:
public abstract class Factory { public abstract Chair findChair(); public abstract Bed findBed(); }
具体工厂类A:
public class FactoryA extends Factory { @Override public Chair findChair() { return new ChairA(); } @Override public Bed findBed() { return new BedA(); } }
具体工厂类B:
public class FactoryB extends Factory { @Override public Chair findChair() { // TODO Auto-generated method stub return new ChairB(); } @Override public Bed findBed() { // TODO Auto-generated method stub return new BedB(); } }
系统类:
public class ProduceSystem { Factory sf = null; public ProduceSystem(Factory sf) { this.sf = sf; } public void runSystem() { Chair proCha = null; Bed proBed=null; String proName = null; try { proCha = this.sf.findChair(); proBed = this.sf.findBed(); proCha.getProduce(); proBed.getProduce(); } catch (Exception e) { e.printStackTrace(); System.out.println("输入有误或者不存在该商品!"); } } }
启动:
public static void main(String[] args) { new ProduceSystem(new FactoryA()).runSystem(); }
工厂模式和抽象工厂区别:
抽象工程关键在于产品之间的抽象关系,所以至少要两个产品;工厂方法在于生成产品,不关注产品间的关系,所以可以只生成一个产品。也就是对于工厂模式,如果对产品进行分类区分的话,为抽象工厂,如果不进行分类,统一为产品,即为工厂模式。
浙公网安备 33010602011771号