1、简述
工厂模式包括简单工厂模式、工厂方法模式和抽象工厂模式,属于创建型模式。
2、不使用工厂模式
(1)类图分析
一个接口Computer,接口有两个实现类HP和Apple,同时有一个测试类Client。不使用工厂模式时,在Client中直接通过new操作符类创建HP和Apple类的实例。
(2)代码展示
Computer接口:
package com.factory;public interface Computer {void compute();}
HP类:
package com.factory;public class HP implements Computer {@Overridepublic void compute() {// TODO Auto-generated method stubSystem.out.println("This is HP PC");}}
Apple类:
package com.factory;public class Apple implements Computer {@Overridepublic void compute() {// TODO Auto-generated method stubSystem.out.println("This is Apple PC");}}
测试类:
package com.factory;public class Client {public static void main(String[] args) {// TODO Auto-generated method stub//不适用工厂模式常见多个类Apple apple = new Apple();HP hp = new HP();pute();pute();}}
(3)运行结果:
This is Apple PCThis is HP PC
(4)缺点和不足:
对于测试类Client来说调用者而言,需要知道HP和Car类的细节,尤其是构造方法的细节,比如需要知道构造方法的参数类型、参数个数等。当有许多Conputer接口的实现类时候,对于Client来说,需要知道的类细节更多,给Client带来较大压力。
3、使用工厂模式
(1)简单工厂模式
(a)类图分析
在上述实现方式的基础上,在类的实现结构中增加一层ComputerFactory,此类的作用是返回HP或者Apple等类的实例对象,具体创建并返回哪一个类的实例在ComputerFactory中通过分支语句来实现。最终的Client测试类仅仅需要调用ComputerFactory中的方法,并传入必要的参数即可。简言之,就是工厂类一般是使用静态方法,通过接受的参数的不同来返回不同的对象实例。
(b)代码展示
Computer接口、HP类、Apple类与(1)中相同
ComputerFactory类:
方式一:
package com.factory;public class ComputerFactory {public static Computer createComputer(String computer) {if("HP".equals(computer)) {return new HP();}else if("Apple".equals(computer)){return new Apple();}else {return null;}}}
方式二:
package com.factory;public class ComputerFactory {public static Computer createHP() {return new HP();} public static Computer createApple() {return new Apple();}}
测试类:
测试一(对应于方式一):
package com.factory;public class Client {public static void main(String[] args) {//使用简单工厂模式Computer hp = ComputerFactory.createComputer("HP");Computer apple = ComputerFactory.createComputer("Apple"); pute();pute();}}
测试二(对应于方式二):
package com.factory;public class Client {public static void main(String[] args) {//使用简单工厂模式Computer hp = ComputerFactory.createHP();Computer apple = ComputerFactory.createApple(); pute();pute();}}
(c)运行结果
This is Apple PCThis is HP PC
(d)缺点和不足:
如果需要增加新的Computer类的话,需要修改ComputerFactory内部的代码。这违反了类设计的开闭原则,开闭原则就是说类对拓展开放,对修改关闭。所以简单工厂模式在面对需要增加新的类的时候会违反开闭原则。
(2)工厂方法模式
(a)类图分析
简单工厂模式中,只有一个公共的工厂类ComputerFactory,所以当需要增加商品的时候,需要修改ComputerFactory,导致违反了开闭原则。所以为每个商品类定义一个特定的工厂类,此处为HP类设置定义一个HPFactory工厂类,为Apple类定义一个AppleFactory类。这样的话看,当需要增加一个新的产品类的时候,不需要对原有的工厂类进行修改,只需要增加一个新的工厂类即可。同时,为了各个工厂的统一性,定义一个工厂接口Factory,然后各个具体产品工厂XXXFactory实现接口Factory,从而统一了接口中的方法。
(b)代码展示
Computer类:
package com.factorymethod;public interface Computer {void compute();}
HP类:
package com.factorymethod;public class HP implements Computer{@Overridepublic void compute() {// TODO Auto-generated method stubSystem.out.println("HP");}}
Apple类:
package com.factorymethod;public class Apple implements Computer {@Overridepublic void compute() {// TODO Auto-generated method stubSystem.out.println("Apple");}}
Factory类:
package com.factorymethod;public interface Factory {Computer createrComputer();}
HPFactory类:
package com.factorymethod;public class HPFactory implements Factory {@Overridepublic Computer createrComputer() {// TODO Auto-generated method stubreturn new HP();}}
AppleFactory类:
package com.factorymethod;public class AppleFactory implements Factory {@Overridepublic Computer createrComputer() {// TODO Auto-generated method stubreturn (Computer) new Apple();}}
测试类Client:
package com.factorymethod;public class Client {public static void main(String args[]) {Computer hp = new HPFactory().createrComputer();Computer apple = new AppleFactory().createrComputer();pute();pute();}}
(c)运行结果
HPApple
(d)缺点与不足
相比于简单工厂模式,工厂方法模式避免了破坏开闭原则,但是由于为每个类都创建了一个工厂类,导致了类的数目增加。
(3)抽象工厂模式
(a)概述
抽象工厂模式是工厂方法模式的升级版本,适用于有多个业务种类和等级的情形,可以用来生产不同产品族的全部产品,对于增加新的产品,无能为力;支持增加产品族。
抽象工厂模式中,有一系列产品接口,每个产品接口都有多个实现类,在工厂类中通过选择产品接口的不同实现类可以生产出不同种类、不同等级的产品,从而形成了产品族。例如,每个产品接口都有两个实现类GoodXXX和PoorXXX,工厂类中如果选择所有的GoodXXX实现类,将生产出Good产品,工厂类中如果选择所有的PoorXXX实现类,将生产出Poor产品,从而最终形成了两个产品线。
(b)类图分析
在此案例中,有三个产品接口CPU、Monitor和Keyboard,同时每个产品接口有两个实现类,分别为GoodCPU和PoorCPU、GoodMonitor和PoorMonitor、GoodKeyboar和PoorKeyboard,其中GoodFactory工厂选择GoodCPU、GoodMonitor、GoodKeyboar创建产品,PoorFactory工厂选择PoorCPU、PoorMonitor、PoorKeyboard创建产品,从而形成了Good和Poor产品两个产品线。
(c)代码展示
CPU类:
package abstractfactory;public interface CPU {void say();}class GoodCPU implements CPU{@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("I am is Good CPU");}}class PoorCPU implements CPU{@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("I am is Poor CPU");}}
Monitor类:
package abstractfactory;public interface Monitor {void say();}class GoodMonitor implements Monitor{@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("I am Good Monitor");} }class PoorMonitor implements Monitor{@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("I am Poor Monitor");}}
Keyboard类:
package abstractfactory;public interface Keyboard {void say();}class GoodKeyboard implements Keyboard{@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("I am Good Keyboard");} }class PoorKeyboard implements Keyboard{@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("I am Poor Keyboard");} }
Factory接口:
package abstractfactory;public interface Factory {CPU createCPU();Monitor createMonitor();Keyboard createKeyboard();}
GoodFactory类:
package abstractfactory;public class GoodFactory implements Factory {@Overridepublic CPU createCPU() {// TODO Auto-generated method stubreturn new GoodCPU();}@Overridepublic Monitor createMonitor() {// TODO Auto-generated method stubreturn new GoodMonitor();}@Overridepublic Keyboard createKeyboard() {// TODO Auto-generated method stubreturn new GoodKeyboard();}}
PoorFactory类:
package abstractfactory;public class PoorFactory implements Factory {@Overridepublic CPU createCPU() {// TODO Auto-generated method stubreturn new PoorCPU();}@Overridepublic Monitor createMonitor() {// TODO Auto-generated method stubreturn new PoorMonitor();}@Overridepublic Keyboard createKeyboard() {// TODO Auto-generated method stubreturn new PoorKeyboard();}}
Client测试类:
package abstractfactory;public class Client {public static void main(String[] args) {// TODO Auto-generated method stubFactory gf = new GoodFactory();CPU gcpu = gf.createCPU();Monitor gmonitor = gf.createMonitor();Keyboard gkeyboard = gf.createKeyboard();gcpu.say();gmonitor.say();gkeyboard.say();System.out.println("----------------------------------");Factory pf = new PoorFactory();CPU pcpu = pf.createCPU();Monitor pmonitor = pf.createMonitor();Keyboard pkeyboard = pf.createKeyboard();pcpu.say();pmonitor.say();pkeyboard.say();}}
运行结果;
I am is Good CPUI am Good MonitorI am Good Keyboard----------------------------------I am is Poor CPUI am Poor MonitorI am Poor Keyboard
(d)缺点和不足
抽象工厂莫斯可以增加产品族,但是不可以增加产品。