设计模式学习之简单工厂(simple facotry)、工厂方法(actory method)、抽象工厂(abstract factory)

一.简单工厂(Simple Factory)

GOF没有把简单工厂作为设计模式之一列出。但是为了学习后面的两种工厂模式,还是先来了解一下简单工厂。

作用:专门由一个类来决定实例化哪个产品类
实现要点:可能很多人平时都不知不觉地使用了简单工厂。简单工厂就是把决定实例化哪个类的方法放到一个单独的类(所谓的工厂类)里。
UML:

代码:

     abstract class Product
{
public abstract void showProduct();
}
class ProductA : Product
{
public override void showProduct()
{
Console.WriteLine(
"this is productA");
}
}
class ProductB : Product
{
public override void showProduct()
{
Console.WriteLine(
"this is productB");
}
}
//factory
class Factory
{
public Product getProduct(int type)
{
if (type == 0)
{
return new ProductA();
}
else
{
return new ProductB();
}
}
}
//---------------执行-----------------
class Program
{
static void Main(string[] args)
{
Factory f
= new Factory();
Product p1
= f.getProduct(0);
Product p2
= f.getProduct(1);
p1.showProduct();
p2.showProduct();
Console.ReadLine();
}
}

 

二.工厂方法(Factory Method)

作用:工厂方法是简单工厂的“再抽象”,不在某个类里直接决定实例化哪个产品类,而是把这个决定延迟到它的子类里面。(至于为什么要抽象出父类,参见之前的文章“父类引用指向子类对象”)。
实现要点:抽象工厂类,由其子类决定实例化哪个产品类。
UML:

代码:

abstract class Product
{
public abstract void showProduct();
}
class ProductA : Product
{
public override void showProduct()
{
Console.WriteLine(
"this is productA");
}
}
class ProductB : Product
{
public override void showProduct()
{
Console.WriteLine(
"this is productB");
}
}
//factory
abstract class Factory
{
public abstract Product getProduct();
}
class FacotryA : Factory
{
public override Product getProduct()
{
return new ProductA();
}
}
class FacotryB : Factory
{
public override Product getProduct()
{
return new ProductB();
}
}
//--------------------执行------------------------
class Program
{
static void Main(string[] args)
{
Factory[] f
= new Factory[2];
f[
0] = new FacotryA();
f[
1] = new FacotryB();
foreach (Factory myfactory in f)
{
Product p
= myfactory.getProduct();
p.showProduct();
}

Console.ReadLine();
}
}

 


三.抽象工厂(Abstract Factory)

作用:客户类需要不同的产品组合来满足自己的需求,客户只关心“产品组合”的效果,而不想关心具体的产品细节。
实现要点:
由抽象工厂类(本例中的Home类)的子类来决定选择哪些具体产品组(选bed,sofa,door,desk等);使用这个工厂时,客户类(Client类)先声明一个抽象工厂的类,比如本例中Client类的构造函数里需要一个Home类型的参数,调用者在实例化客户类(main函数中的client1和client2)时,参数直接传入具体的工厂类(本例的SimpleHome或者AdvancedHome)即可,这样调用者不需要知道具体的产品类有哪些(本例中的bed,sofa,door,desk等),就能通过选择工厂类型(本例中的SimpleHome或者AdvancedHome)来获得一系列的产品类型(bed,sofa,door,desk等)。
UML:


代码:

abstract class Products
{
public abstract void showProduct();
}
class ProductBed : Products
{
public override void showProduct()
{
Console.WriteLine(
"exist a Bed");
}
}
class ProductDesk : Products
{
public override void showProduct()
{
Console.WriteLine(
"exist a Desk");
}
}
class ProductDoor : Products
{
public override void showProduct()
{
Console.WriteLine(
"exist a Door");
}
}
class ProductSofa : Products
{
public override void showProduct()
{
Console.WriteLine(
"exist a Sofa");
}
}

//abstractfactory,这里是一个抽象的“家”
abstract class Home
{
protected Products myBed,myDesk,myDoor,mySofa;
public abstract void showMyHouse();
}
//简单的家:只需要门和床
class SimpleHome : Home
{
public SimpleHome()
{
myBed
= new ProductBed();
myDoor
= new ProductDoor();
}
public override void showMyHouse()
{
Console.WriteLine(
"this is a simple Home:");
myBed.showProduct();
myDoor.showProduct();
}
}
//高级一点的家:还有沙发,桌子等家具
class AdvancedHome : Home
{
public AdvancedHome()
{
myBed
= new ProductBed();
myDoor
= new ProductDoor();
mySofa
= new ProductSofa();
myDesk
= new ProductDesk();
}
public override void showMyHouse()
{
Console.WriteLine(
"this is a advanced Home:");
myBed.showProduct();
myDoor.showProduct();
mySofa.showProduct();
myDesk.showProduct();
}
}
//调用抽象工厂的客户类
class Client
{
Home myHome;
public Client(Home newHome)
{
this.myHome = newHome;
}
public void showHome()
{
myHome.showMyHouse();
}
}
//--------------------执行-------------------
class Program
{
static void Main(string[] args)
{
//客户不需要选择具体家具了,只需要选择具体的房子类型就可以了,家具自动配好。
Client client1 = new Client(new SimpleHome());
client1.showHome();
Client client2
= new Client(new AdvancedHome());
client2.showHome();
Console.ReadLine();
}

}


总是有人出来追究抽象工厂和工厂方法的区别,它们本来目的就不同,所以不好比: 
工厂方法其实应该是一种思想,我要用一个东西,但是现在又没法确定它怎么办,留下一个接口,由其它对象以后实现。这样就可以把易变的、不确定的部分分离出来,也就是解耦。
抽象工厂则是封装,最好的例子就是你要去买办公外设,你不想东一家西一家挑选了。你就直接对某个代理商说:给我一套办公外设的组合,于是他一口气给你推荐了一系列产品:HP的打印机,Canon的复印机,HP的投影仪,理光的碎纸机。。。为了方便,你所关注的是一系列产品组,而代理商就扮演抽象工厂的角色,给你选择一系列办公产品。(刚改过,以前的电脑例子觉得不是很贴切,因为后来看了Builder模式)
posted @ 2008-11-06 14:20  MichaelChen  阅读(1318)  评论(5编辑  收藏  举报