为了更好地理解这两个模式,自己假设了如下场景,可能有些牵强,但应该还好。嘿嘿。
Acer,Lenovo两家本本制造商,假设原来有一OEM两个牌子的本本都做,这时,无论你想买那种牌子的,都可以直接向OEM购买。
可是后来该OEM商发现,如果一次同时做很多个牌子的本本,有些不利于管理,而且,如果以后要加入新的品牌的话,要有许多设备上的改动,等等原因,于是,它决定衍生出些子厂,每个子厂只做一种牌子的本本,而OEM核心总部,只负责制定规范,即,每个子厂要完成的所有任务。
该OEM的初始状态,就是静态工厂方法的场景,自己负责一切生产任务,根据外界的需求,去制造本本。
后来,为了便于管理,和把引入新品牌后产生的变动降到最低,采取了工厂方法模式。即,核心的工厂不再负责创建等具体动作,把这些派发给自己的子工厂。而核心工厂,仅负责制定规范。
1.工厂方法模式
首先,定义产品接口,Laptop,当然,也可以是个抽象类。
点击(此处)折叠或打开
- package factoryMethod;
-
- abstract public class Laptop {
-
- private String mark;
-
- public Laptop(String str){
-
- this.mark = str;
-
- }
-
- abstract public String getId();
-
- public void echoMark(){
-
- System.out.println("this is a "+mark+" Laptop");
-
- }
-
- }
有了产品接口,我们就可以去定义那个核心工厂接口
点击(此处)折叠或打开
- package factoryMethod;
-
- public interface LaptopFactory {
-
- public Laptop produce();
-
- public void service();
-
- }
如代码所示,核心工厂规定了它子类要完成的行为,即,制造本本,和售后服务。
下面,是具体产品类,比如Acer品牌的本本
点击(此处)折叠或打开
- package factoryMethod;
-
- public class AcerLaptop extends Laptop {
-
-
- private static final String mark = "Acer";
- protected static int initId;
-
- public AcerLaptop() {
- super(AcerLaptop.mark);
- AcerLaptop.initId = 10001;
- }
-
- public String getId() {
-
- return "Acer--"+(AcerLaptop.initId++);
-
- }
-
- }
再来个Lenovo的本本
点击(此处)折叠或打开
- package factoryMethod;
-
- public class LenovoLaptop extends Laptop {
-
- private static final String mark = "Lenovo";
- protected static int initId;
-
- public LenovoLaptop() {
-
- super(LenovoLaptop.mark);
- LenovoLaptop.initId = 20001;
- }
-
- public String getId() {
-
- return "Lenovo--"+(LenovoLaptop.initId++);
-
- }
-
- }
其实Laptop定义的抽象方法没什么具体意义,该例子只为描述工厂方法模式。
下面,来定义具体工厂,Acer的,和Lenovo的,里面的方法同样没什么太大意义,只为测试。
点击(此处)折叠或打开
- package factoryMethod;
-
- public class AcerFactory implements LaptopFactory {
-
- @Override
- public Laptop produce() {
-
- return new AcerLaptop();//生产Acer的本本
-
- }
-
- @Override
- public void service() {
-
- System.out.println("welcom to Acer hotline ");
-
- }
-
- }
点击(此处)折叠或打开
- public class LenovoFactory implements LaptopFactory{
-
- public Laptop produce(){
-
- return new LenovoLaptop();//生产lenovo的本本
-
- }
-
- public void service(){
-
- System.out.println("welcom to Lenovo hotline ");
-
- }
-
- }
来一个测试类。
点击(此处)折叠或打开
- package factoryMethod;
-
- public class Client {
-
- public static void main(String[] args) {
-
- LenovoFactory lf = new LenovoFactory();
- AcerFactory af= new AcerFactory();
- Laptop lt1 = lf.produce();
- Laptop lt2 = lf.produce();
- Laptop lt3 = af.produce();
- Laptop lt4 = af.produce();
-
-
- lf.service();
- System.out.println(lt1.getId());
- System.out.println(lt2.getId());
- System.out.println("--------------");
- af.service();
- System.out.println(lt3.getId());
- System.out.println(lt4.getId());
-
- }
- }
打印结果如下
点击(此处)折叠或打开
- welcom to Lenovo hotline
- Lenovo--20001
- Lenovo--20002
- --------------
- welcom to Acer hotline
- Acer--10001
- Acer--10002
过了一段时间,该OEM决定除了做本本,也做手机。而且OEM核心工厂决定改变下现有策略,每个子工厂做同一品牌的两个产品,例如,子工厂A做Acer的手机和本本。
这时,有了同族产品的概念,即某些产品是一个产品族的,这里就是指同一个品牌的。
为了完成这一变更,就要是用抽象工厂方法了。这个要比前一个复杂一些,所以先画了一个uml图。
-工厂接口,AbstractFatory,指定了子类要实现的制造本本,制造手机的方法
-具体工厂类,AcerFactory,LenovoFactory,均实现了上述方法,每个具体工厂负责一个产品族。
-MobilePhone抽象类,指定Phone产品的一些属性特征,Laptop同理。
-Phone与Laptop属于不同等级的产品,但是同一品牌的Phone和Laptop是同一产品族的产品,在此例中。
这里就不再罗列代码了,uml图可以比较清晰的说明每个角色间的关系。
总结起来,引用百度百科的一句话,抽象工厂模式使用同一个 工厂等级结构负责不同产品等级结构产品对象的创建。
----------------------------------------------------------------------------