1.意图:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
2.别名:
kit
4.适用性:
- 一个系统要独立于它的产品创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
- 当您提供一个产品类库,而只想显示它们的接口而不是实现时。
其实上面这些适用性的介绍,本人也看不懂,说白了点,目前我看到工厂模式使用比较多的场景有:
1.隐藏对象的创建
2.如果创建对象的代码过于复杂,使用工厂模式来生成,可以避免那些创建对象重复代码的泛滥,便于维护
3.如果一个对象有多个继承与它的对象,并且将来还有更多的继承出现,使用工厂模式统一管理创建对象。
4.有多个相似子产品,每次使用的是其中一个产品,使用本文的主要讨论abstract factory模式。上面三点可以使用一般工厂模式即可.
5.参与者
- AbstractFactory----声明一个创建抽象产品对象的操作接口.
- ConcreteFactory----实现创建具体产品对象的操作.
- AbstractProduct----为一类产品对象声明一个接口
- ConcreteProduct----定义一个将被相应的具体工厂创建的产品对象,实现AbstractProduct接口
- Client----仅使用由AbstractFactory和AbstractProduct声明的接口.
6.效果
AbstractFactory模式有下面的一些优点和缺点:
1).它分离了具体的类:Abstract Factory模式帮助你控制一个应用创建的对象的类。因为一个工厂封装创建产品对象的责任和过程,它将客户与类的实现分离。客户通过它们的抽象接口操作实例。产品的类名也在具体工厂的实现中被分离;它们不出现在客户代码中。 其实是实现了对具体对象创建的隐藏。
2).它使得易于交换产品系列。一个具体工厂类再一个应用中仅出现一次---即在它初始化的时候。这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂既可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。
3).它有利于产品的一致性。当一个系列中的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要。
4).难以支持新种类的产品(?这里我不明白,不就是增加个具体的abstract factory 的子类么。这个应该是必然的吧)。
7.示例:这个示例是根据设计模式书中C++例子改造而成,主要功能描述是,要创建一个迷宫,这个迷宫有房间组成,房间有墙和门组成,房间,墙和门都有一个共同的方法enter,用于表明能否进入,比如墙肯定不能进入,门要看闭合状态,房间要看是进门还是墙之类的。
// ------------------------------------工厂虚类(也就是AbstractFactory)--------------------------------------
package com.gof.chapter3.abstract_factory.maze;
public abstract class MazeAbstractFactory {
public Maze createMaze() {
Maze maze = new Maze();
Room room1 = this.createRoom();
Room room2 = this.createRoom();
room1.setSide(Direction.East, this.createWall());
room1.setSide(Direction.North, this.createWall());
room1.setSide(Direction.South, this.createWall());
room1.setSide(Direction.West, this.createDoor());
room2.setSide(Direction.East, this.createWall());
room2.setSide(Direction.North, this.createWall());
room2.setSide(Direction.South, this.createWall());
room2.setSide(Direction.West, this.createDoor());
maze.setRoom(room1);
maze.setRoom(room2);
return maze;
}
public abstract Room createRoom();
public abstract Wall createWall();
public abstract Door createDoor();
}
//-------------------------------房间,墙和门的接口,主要定义enter方法--------------------------------------
package com.gof.chapter3.abstract_factory.maze;
public interface MapSite {
public abstract Object enter();
}
//------------------------------------------------房间虚类(ConcreteFactory)---------------------------------------------------
package com.gof.chapter3.abstract_factory.maze;
public abstract class Room implements MapSite{
public abstract Object enter() ;
public abstract void setSide(Direction direction,MapSite site);
public abstract MapSite getSide(Direction direction);
}
//------------------------------------------------门虚类(ConcreteFactory)-------------------------------------------------------
package com.gof.chapter3.abstract_factory.maze;
public abstract class Door implements MapSite{
public abstract Object enter();
}
//-----------------------------------------------墙虚类(ConcreteFactory)--------------------------------------------------------
package com.gof.chapter3.abstract_factory.maze;
public abstract class Wall implements MapSite{
public abstract Object enter();
}
//------------------------------------------定义房间方向的枚举-----------------------------------------------
package com.gof.chapter3.abstract_factory.maze;
public enum Direction {
North,East,South,West
}
//-----------------------------------------迷宫类--------------------------------------------------------------
package com.gof.chapter3.abstract_factory.maze;
public class Maze{
private java.util.List<Room> rooms = null;
public Maze(){
rooms = new java.util.ArrayList<Room>();
}
public void setRoom(Room room){
rooms.add(room);
}
}
//----------------------------------------客户端调用类,创建迷宫-------------------------------------------
package com.gof.chapter3.abstract_factory.maze;
import com.gof.chapter3.abstract_factory.maze.common.CommonMazeFactory;
import com.gof.chapter3.abstract_factory.maze.magic.MagicMazeFactory;
public class Client {
public static void main(String[] ben){
Client c = new Client();
// 普通的迷宫
c.createMaze(new CommonMazeFactory());
//带有魔法的迷宫
c.createMaze(new MagicMazeFactory());
}
public Maze createMaze(MazeAbstractFactory factory){
return factory.createMaze();
}
}
//---------------------------普通迷宫的房间,门,墙和工厂方法的建立------------------------------------------
//房间
package com.gof.chapter3.abstract_factory.maze.common;
import java.util.HashMap;
import java.util.Map;
import com.gof.chapter3.abstract_factory.maze.Direction;
import com.gof.chapter3.abstract_factory.maze.MapSite;
import com.gof.chapter3.abstract_factory.maze.Room;
public class CommonRoom extends Room {
private Map sides = null;
public CommonRoom() {
System.out.println("建立了一个普通的房间");
sides = new HashMap();
}
public Object enter() {
// TODO Auto-generated method stub
return null;
}
public void setSide(Direction direction, MapSite site) {
// just 设置
sides.put(direction, site);
}
public MapSite getSide(Direction direction) {
if (sides.get(direction) != null) {
return (MapSite) sides.get(direction);
} else {
return null;
}
}
}
//门
package com.gof.chapter3.abstract_factory.maze.common;
import com.gof.chapter3.abstract_factory.maze.Door;
public class CommonDoor extends Door{
public CommonDoor(){
System.out.println("建立了一个普通的门");
}
@Override
public Object enter() {
// TODO Auto-generated method stub
return null;
}
}