Java创建型设计模式:工厂方法模式

文章类别 in java, 设计模式

本文目录

1.工厂方法模式的使用例子

2.工厂方法模式的主要代码实现

3.工厂方法模式的优点

4.工厂方法模式的使用场景

5.我的相关文章

6.工厂方法模式的相关资料

工厂方法模式的使用例子

假设电脑由主机、键盘、显示器、鼠标组成,现在需要组装一台这样的电脑交给调用者去使用,那么可能我们会这样写代码:

public class Host {

    public void describe()
    {
        System.out.println("这是电脑主机");
    }

}


public class Monitor {

    public void describe()
    {
        System.out.println("这是显示器");
    }

}


public class Mouse {

    public void describe()
    {
        System.out.println("这是鼠标");
    }

}

public class _keyboard {

    public void describe()
    {
        System.out.println("这是键盘");
    }

}


public class Computer {

    private Host host;
    private _keyboard _keyboard;
    private Monitor monitor;
    private Mouse mouse;

    public Computer(Host host,_keyboard _keyboard,Monitor monitor,Mouse mouse){
        this.host = host;
        this._keyboard = _keyboard;
        this.monitor = monitor;
        this.mouse = mouse;
    }

    public void show()
    {
        this.host.describe();
        this._keyboard.describe();
        this.monitor.describe();
        this.mouse.describe();
    }
   
}


调用者:

 public static void main(String[] args)
    {
        Host host = new Host();
        _keyboard keyboard = new _keyboard();
        Monitor monitor = new Monitor();
        Mouse mouse = new Mouse();

        Computer computer = new Computer(host,keyboard,monitor,mouse);
        computer.show();
    }

	
输出:

	这是电脑主机
	这是键盘
	这是显示器
	这是鼠标

我们可以看到,调用者为了搞一台电脑,还需要自己去创建主机,键盘,显示器,鼠标这些组件,但是这些组件是和调用者无关的,而且这些组件实际情况下可能是抽象的,调用者根本不知道如何去使用这些。

另外假设调用者需要不同品牌的电脑,例如苹果电脑,联想电脑,三星电脑等等,这样对代码来说不仅耦合度太高了,而且很是不利于之后的优化扩展。

调用者只希望有一个创建电脑的工厂,使用它直接造出一台电脑就好了。

比如想要苹果电脑,那就直接告诉 「苹果工厂」 : “给我造台电脑来” ,然后 「苹果工厂」 就屁颠屁颠的将苹果电脑送过来了。

同样的,如果你想要联想电脑,那就直接告诉 「联想工厂」 : “快,搞台出来给我” ,于是 「联想工厂」 就把崭新的联想电脑送到你手里了。

想想是不是简直不要太爽?

那这时候,我们就可以这样子,先画个类图:

工厂方法设计模式

如果对类图不太了解可以先看这:轻松理解UML用例图时序图类图的教程

可以看到:

  • ComputerFactory 是一个抽象的工厂(接口),它有一个createComputer的方法,这个方法返回的是Computer这个接口类。
  • AppleFactory 和 LenovoFactory是具体的工厂类,分别实现了ComputerFactory,它们重写父类的createComputer方法,其中 AppleFactory的createComputer方法返回的是AppleComputer,LenovoFactory的createComputer方法返回的是LenovoComputer
  • Computer是一个抽象的产品类
  • AppleComputer和LenovoComputer是具体的产品类,分别实现了Computer。

代码体现如下:

 /**
 * Created by wistbean on 2017/10/7.
 * 抽象工厂
 */
public interface ComputerFactory {

    public Computer createComputer();

}

/**
 * Created by wistbean on 2017/10/7.
 * 具体工厂
 */
public class AppleFactory implements ComputerFactory {
    @Override
    public Computer createComputer() {

        //这里主要为了演示工厂方法模式,组装电脑的代码省略...

        Computer appleComputer = new AppleComputer();

        return appleComputer;
    }
}


/**
 * Created by wistbean on 2017/10/7.
 * 具体工厂
 */
public class LenovoFactory implements ComputerFactory {
    @Override
    public Computer createComputer() {

        //这里主要为了演示工厂方法模式,组装电脑的代码省略...

        Computer lenovoComputer = new LenovoComputer();

        return lenovoComputer;
    }
}


/**
 * Created by wistbean on 2017/10/7.
 * 抽象产品
 */
public interface Computer {

    public void describe();
}


/**
 * Created by wistbean on 2017/10/7.
 * 具体产品
 */
public class AppleComputer implements Computer {

    @Override
    public void describe() {
        System.out.println("苹果电脑");
    }
}

/**
 * Created by wistbean on 2017/10/7.
 * 具体产品
 */
public class LenovoComputer implements Computer {

    @Override
    public void describe() {
        System.out.println("联想电脑");
    }
}


/**
 * Created by wistbean on 2017/10/7.
 * 调用
 */
public class Client {

    public static void main(String args[])
    {
        ComputerFactory computerFactory;
        Computer computer;

        //让工厂给我创建一台苹果电脑
        computerFactory = new AppleFactory();
        computer = computerFactory.createComputer();
        computer.describe();

        //让工厂给我创建一台联想电脑
        computerFactory = new LenovoFactory();
        computer = computerFactory.createComputer();
        computer.describe();
    }
}


输出:

	苹果电脑
	联想电脑

以上,便是一个工厂方法模式的实现过程,其中的:

工厂抽象接口用来返回一个产品,所有创建对象的工厂类都必须实现它;

抽象工厂的子类(具体工厂类)则实现了抽象工厂中定义的方法,在这里返回具体的对象,还可以做一些初始化操作,环境配置等等。

抽象的产品类则是所有具体产品的父类,主要定义一些产品的规范。

具体产品类与具体工厂类一一对应,决定了产品的具体行为。

从列子中也可以看到,针对不同的产品提供了不同的工厂,例如苹果电脑对应于苹果工厂;我们定义了一个抽象的工厂,让实例化这个抽象工厂的具体工厂类来决定实例化哪个类,这样让类的实例化延迟到子类中进行了!

工厂方法模式的主要代码实现

public interface IFactory {

    public IProduct createProduct();
}

public class ProductFactory implements IFactory {
    @Override
    public IProduct createProduct() {
        IProduct product = new Product();
        return product;
    }
}


public interface IProduct {

    public void productMethod();

}


public class Product implements IProduct {
    @Override
    public void productMethod() {
        System.out.println("产品行为");
    }
}


public class Client {

    public static void main(String args[])
    {
        IFactory factory;
        IProduct product;

        factory = new ProductFactory();
        product = factory.createProduct();

        product.productMethod();
    }

}

工厂方法模式的优点

  1. 使得代码结构清晰,降低了代码的耦合性,工厂方法模式把复杂的产品实现封装了起来,调用者无需关心产品实例的具体实现,直接通过工厂获取实例即可。

  2. 易于扩展,当我们需要新的产品的时候,只需要实现新的抽象产品类和实现抽象工厂类即可。

工厂方法模式的使用场景

  1. 对于一些较为复杂的对象创建我们可以使用工厂方法模式。
  2. 调用者不知道子类的名称时,只知道对应的工厂,直接从工厂获取可以用工厂方法模式。
  3. 调用者需要组装产品的时候产生过多依赖的关系时,可以用工厂方法模式。

我的相关文章

相关资料