The purpose of the factory method is clear that define an interface to create an object, but he does not directly create objects, and he is created by his subclasses, so that the responsibility of the creation of objects will be delayed in the subclass of the interface, What type of object created is determined by subclasses, and the time to create an object is determined by the interface. So this mode can be used in the following cases: 1, a class can't repreat the class of objects it must create.2, a class wants it creates.3, classes delegate responibility to one of SEVERAL HELPER SUBCLASS, But Do Not Know Whick Helper Subclass Is The Delegate. Here we raise an example of a bakery: Bakery bread machine is better than an abstract product, it is a general bread, then we can make through a special process It becomes different kinds of bread, such as: can be a Chinese-style bread or a US bread. These special types of bread are our specific products. People who do bread (maybe yourself) are Creator (creator), we use our method (factory method) to do the bread we want. The flexibility here is self-evident, using the bread machine to make us more choices, only we decide to eat that bread when we need it, this is not a good thing, if there is no bread Machine may only eat Chinese bread. Below we will take a few examples in our very familiar FCL (.NET FramrWork Class Labrrly), IEnumerable and IEnumerator are a Creator and a product. Another example is: WebRequest is an abstraction of the .NET Framework for accessing the request / response model in Visual Basic, in Visual Basic. Applications using this request / response model can request data from the Internet in a manner unknown. In this way, the application processes an instance of the WebRequest class, and the specific subclass of the protocol executes the specific details of the request. The request is sent from the application to a particular URI, such as a web page on the server. The URI determines the appropriate subclass to be created from a WebRequest sub-list registered with the application. Registration WebRequest child is usually to handle a particular protocol (such as HTTP or FTP), but can also register it to process a request for paths on a particular server or server. (WebRequest is taken from MSDN), which is a factory method with parameters. Inside the FCL plant method is the most common mode application.
With a simple example (bread), I don't know if it is, I don't want to re-describe the mode, but I will emphasize when I need it, the following uses the structural map of the creation mode to show this mode. .
This time I want to implement the example, first we need to look at our environment (context), in order to achieve a maze creation environment, this labyrinth is shown in the following figure:
In order to achieve plant mode to create a maze, we have a class diagram. From the figure, there are many factory methods in Creat (Mazegame), and users can get different houses (component maze components), but maybe we I don't know if our MazeGame is to create what kind of Room so we can define some subclasses (now there are two) used to achieve different creation work, and Room is the most common house that makes up our maze, Mazegame can produce such a large The house but in order to meet different requirements, we can define some special houses such as: a house with a bomb (refers to a bomb on the wall) and can be magical-like houses (you can give Mono). This allows us to do not change the original interface, use MazeGame's subclasses to complete these special creation work, just as shown in the figure below. We delay the creation of the details to the subclasses, which greatly enhances the toughness of the program. If we want to create a new house or new door we can add a MazeGame with a MazeGame without changing the original code Class to achieve this idea. But I think this has a problem to create a new house we must create a new subclass to meet this request, which looks like a pair of pairs of parallel. This will make our Creator's subclasses more and more, we can use parameters to reduce this type of reproduction, the code implemented below does not realize this factory method, netizens can realize themselves. As long as we deliver a parameter to MakeWall and MakeDoor to determine what kind of Wall and Door created, we need to write a negative version in the default mazegame.
If you have a nonsense, don't say much, Gof is more clear than me (in fact, I am also learned from them. Let's implement our maze, the code is as follows:
First achieve our environment
Using system;
Using system.collections;
// This namespace is some of the environments that run instances include Maze, Door, etc.
Namespace CommonObject {
// There is a method in the base class of all maze members to show information of the current component.
Public class mapsite {
Public Virtual String Enter () {
Return string.empty;
}
}
// The wall is one of the components that make up the maze, here is a very general wall (no bomb)
Public class wall: Mapsite {
Public override string enter () {
Return "this is a wall.";
}
Public wall () {}
}
// The door is also one of the components of the maze, which is also a very ordinary door (not magic)
PUBLIC CLASS DOOR: MapSite {
Public override string enter () {
Return "this is a door."
}
// The door is the component between the two houses so the constructor contains two houses.
/ / Explain the door between the two houses
Public Door (room roomfrom, room room) {
THIS.M_ROOM1 = RoomFrom;
THIS.M_ROOM2 = RoomTo;
}
// Let us have the opportunity to enter another house from the door, will get
// Reference to another house
Public Room OthersideFrom (room roomfrom) {
IF (this.m_room1 == roomfrom)
Return this.m_room2;
Else
Return this.m_room1;}
// This is some private variables
Private Room M_ROOM1;
Private Room M_ROOM2;
// Describe the status of the door defaults all new doors are off
PRIVATE BOOL M_ISOPEN = FALSE;
/ / Provide a public access to accessor
Public bool isopen {
Set {this.m_isopen = value;
Get {return this.m_isopen;
}
}
// The room is the basic unit that makes up the maze
Public Class Room: MapSite
{
// Enumeration Type indicates the face of the house
Public enum Sides {
North = 0,
EAST,
South,
WEST
}
Public override string enter () {
Return "this is a room."
}
// Conquer the function, in order to distinguish between our rooms, add a sign to each room
Public Room (int roomnumber) {
THIS.M_ROOMNUMBER = Roomnumber;
}
// Set the face of the house, the house has four faces, because we don't know each face now
// The specific type (door wall?) So we use the MapSite type.
Public void setside (Side, MapSite Sidemap) {
THIS.M_SIDE [(INT) Side] = SIDEMAP;
}
/ / Get the designated surface, and we don't know which one is getting
// So we return the structure with MapSite
Public mapsite getside (Side Side) {
Return this.m_side [(int) Side];
}
// Some private member room
protected int m_roomnumber;
// The house has 4 faces
protected const Int m_sides = 4;
// Store the unknown type (wall or door) with a 1-dimensional MapSite array
protected mapsite [] m_side = new mapsite [m_sides];
}
// House with bomb
Public class bombedroom: room {
Public Bombedroom (int Roomnumber): base (roomnumber) {}
}
// House with maze
Public class enchantedroom: room {
Public Enchantedroom (int Roomnumber, Spell Spell): Base (roomnumber) {}
}
// This is a special wall - with a bomb
Public Class Bombedwall: Wall {}
// This is a door that can be magic
Public class enchanteddoor: door {
Public EnchantedDoor (Room Roomfrom, Room Roomto): Base (Roomfrom, Roomto) {}
}
// This is our maze.
Public class maze {
Private arraylist m_rooms = new arraylist ();
Public room roomnumber (int roomnumber) {
Return (Room) this.m_rooms [roomnumber];
}
Public void addroom (room room) {
THIS.M_ROOMS.ADD (Room);
}
}
// Magic class
Public class spell {}}}
Next is the implementation of factory methods:
Using system;
Using system.collections;
Namespace factoryMethod_example
{
// Add Mazecontext
USING COMMONOBJECT;
/ / Realize the Creator class of some factory methods
Public Class Mazegame
{
/ / To return to the object of the client
PRIVATE MAZE M_MAZE = NULL;
// An accessor is used to get Maze
Public maze maze
{
get
{
IF (this.m_maze == null)
THIS.M_MAZE = CREATEMAZE ();
Return this.m_maze;
}
}
// constructor
Public mazegame ()
{
}
// The following is some factory methods to create each component of the maze
Public virtual maze makemaze ()
{
Return new maze ();
}
Public Virtual Room Makeroom (INT ID)
{
Return New Room (ID);
}
Public Virtual Wall Makewall ()
{
Return New Wall ();
}
Public Virtual Door Makedoor (room room1, room room)
{
Return New Door (Room1, Room2);
}
// Create a maze
Public Maze Createmaze ()
{
Maze maze = makemaze ();
// Create a door and room
Room Room1 = Makeroom (1);
Room Room2 = Makeroom (2);
Door thedoor = Makedoor (Room1, Room2);
// Add room to the labyrinth
Maze.Addroom (room1);
Maze.Addroom (room2);
// Set the surface of ROOM1
Room1.setside (room.sides.north, makewall ());
Room1.setside (room.sides.east, itdoor);
Room1.setside (room.sides.South); Makewall ());
Room1.setside (room.sides.west, makewall ());
// Set the surface of ROOM2
Room2.setside (room.sides.north, makewall ());
Room2.setside (room.sides.east, makewall ());
Room2.setside (room.sides.South); Makewall ());
Room2.setside (room.sides.west, theduc);
Return maze;
}
}
// Create a bomb maze
Public class bombedmazegame: Mazegame {
Public bombedmazegame () {}
Public override wall make makewall () {
Return new bombedwall ();
}
Public Override Room Makeroom (int N) {
Return New Bombedroom (n);
}
}
// Create a maze with magic
Public class enchantedmazegame: mazegame {
Private Spell M_SPell;
Public Enchantedmazegame (Spell Spell) {
THIS.M_SPELL = SPELL;}
Public Override Door Makedoor (Room R1, Room R2) {
Return New EnchantedDoor (R1, R2);
}
Public Override Room Makeroom (int N) {
Return New EnchantedRoom (n, this.m_spell);
}
}
}
The above code is tested in .NET IDE, it has said that there are many factories in FCL in the FCL, and if you want to continue learning and understanding, you can look at MSDN's help. I hope that these can help you better understand the factory method model. If there is any incorrect place, I hope that I can send an email to Wu_Jian830@hotmail.com, I will be humbly, I hope we can make progress together.