在petshop4.0中也用到了几个常用的设计模式:简单工厂模式,工厂方法模式,策略模式,并附之返射与配置文件.下面就来用我自己的理解用大白话说出来.
1.简单工厂模式.
比如A与B一起写代码,A负责前台,B负责后台,B写了两个类:X与Y,A负责调用,那么1.A怎么知道B写了X与Y两个类呢?2.B又增加了Z 类怎么办,3.A在代码里写了n个X x = new X(), B把X类改名或重写了怎么办.为了解决这些困难,就提出了简单工厂模式,说白了,有一个基类或接口,然后n个类从它继承,再写一个类作为工厂,里面有个静 态方法负责根据转入参数的不同返回从基类或接口继承的具体对象:
代码
public
interface
IPerson
{
string
GetName();
}
public
class
Kernel : IPerson
{
public
string
GetName()
{
return
"
Kernel
"
;
}
}
public
class
Json : IPerson
{
public
string
GetName()
{
return
"
Json
"
;
}
}
public
class
PersonFactory
{
public
static
IPerson CreateInstance(
string
name)
{
string
path
=
ConfigurationManager.AppSettings[
"
AssemblyName
"
];
string
className
=
""
;
switch
(name)
{
case
"
kernel
"
:
className
=
ConfigurationManager.AppSettings[
"
kernelClass
"
];
break
;
default
:
className
=
ConfigurationManager.AppSettings[
"
JsonClass
"
];
break
;
}
return
Assembly.Load(path).CreateInstance(className)
as
IPerson;
}
}
static
void
Main(
string
[] args)
{
IPerson p1
=
PersonFactory.CreateInstance(
"
kernel
"
);
Console.WriteLine(p1.GetName());
IPerson p2
=
PersonFactory.CreateInstance(
"
Json
"
);
Console.WriteLine(p2.GetName());
Console.ReadKey();
}
如果有变更,现在就只需要更改工厂类就可以了,这样就在一定程度上必免了因为调用对象的变更而导致代码的重写
2.工厂方法模式
类不多时一般用简单工厂.如果类非常多,你就会发现这个工厂会奇大无比,这时就需要对这个工厂分解,工厂方法模式就这样提出来了.
工厂方法模式个人认为本质上就是对工厂也工厂了一遍.先用工厂产生特定类的工厂,然后用特定类的工厂生成你所需要的具体对象.
代码
public
interface
IPerson
{
string
GetName();
}
public
class
Kernel : IPerson
{
public
string
GetName()
{
return
"
Kernel
"
;
}
}
public
class
Json : IPerson
{
public
string
GetName()
{
return
"
Json
"
;
}
}
public
interface
ICreatePerson
{
IPerson CreateInstance();
}
public
class
CreateKernelFactory : ICreatePerson
{
public
IPerson CreateInstance()
{
string
path
=
ConfigurationManager.AppSettings[
"
AssemblyName
"
];
string
className
=
ConfigurationManager.AppSettings[
"
kernelClass
"
];
return
Assembly.Load(path).CreateInstance(className)
as
IPerson;
}
}
public
class
CreateJsonFactory : ICreatePerson
{
public
IPerson CreateInstance()
{
string
path
=
ConfigurationManager.AppSettings[
"
AssemblyName
"
];
string
className
=
ConfigurationManager.AppSettings[
"
jsonClass
"
];
return
Assembly.Load(path).CreateInstance(className)
as
IPerson;
}
}
static
void
Main(
string
[] args)
{
ICreatePerson c1
=
new
CreateKernelFactory();
IPerson p1
=
c1.CreateInstance();
ICreatePerson c2
=
new
CreateJsonFactory();
IPerson p2
=
c2.CreateInstance();
Console.WriteLine(p1.GetName());
Console.WriteLine(p2.GetName());
Console.ReadKey();
}
3.策略模式
有时候你会发现有些需求其实大体都是一样的,同一类的,就是计算方式不同,这时就可以用策略模式:
代码
public
interface
IBuy
{
string
GetCharge();
}
public
class
CashBuy : IBuy
{
double
charge;
double
cut;
public
CashBuy(
double
charge,
double
cut)
{
this
.charge
=
charge;
this
.cut
=
cut;
}
public
string
GetCharge()
{
return
(charge
-
cut).ToString();
}
}
public
class
CreditBuy : IBuy
{
double
charge;
double
precent;
public
CreditBuy(
double
charge,
double
precent)
{
this
.charge
=
charge;
this
.precent
=
precent;
}
public
string
GetCharge()
{
return
(charge
*
precent).ToString();
}
}
public
class
Context
{
IBuy buy;
public
Context(IBuy buy)
{
this
.buy
=
buy;
}
public
string
GetCharge()
{
return
buy.GetCharge();
}
}
static
void
Main(
string
[] args)
{
Context c1
=
new
Context(
new
CashBuy(
200
,
40
));
Context c2
=
new
Context(
new
CreditBuy(
200
,
7
));
Console.WriteLine(c1.GetCharge());
Console.WriteLine(c2.GetCharge());
Console.ReadKey();
}
你会发现在这里不再用接口new出一个个具体对象,而统一用Context对象,并通过Context得到结果.其实这通过工厂模式也可以得到相同 的结果,但它们的测重点有所不同.举个例子:排序算法,我需要的是选择一种算法但这种算法是一种策略,而这些算法实际上是可以相互替代的,即快速排序,基 数排序都可实现问题,而我只要求选择一种.而不是工厂里面创建那样,创建产品A(他是根据要求,而不是选择,即只能创建A),他与产品B是不能互相替代 的。
然而纯粹的策略模式需要A知道B具体构造了哪些对象,会出现在谈简单工厂时所出的那些问题,所以,我们常常把简单工厂与策略模式一起使用:
4.简单工厂+策略模式
代码
public
enum
BuyType
{
Cash,
Credit
}
public
interface
IBuy
{
double
GetPrice();
}
public
class
CashBuy : IBuy
{
double
price;
double
cut;
public
CashBuy(
double
price,
double
cut)
{
this
.price
=
price;
this
.cut
=
cut;
}
public
double
GetPrice()
{
return
price
-
cut;
}
}
public
class
CreditBuy : IBuy
{
double
price;
double
precent;
public
CreditBuy(
double
price,
double
precent)
{
this
.precent
=
precent;
this
.price
=
price;
}
public
double
GetPrice()
{
return
price
*
(
1
-
precent);
}
}
public
class
Content
{
IBuy buy
=
null
;
public
Content(BuyType buyType,
double
price,
double
cut)
{
string
path
=
ConfigurationManager.AppSettings[
"
SimpeFactoryAndStrategyAssemble
"
];
string
className
=
""
;
switch
(buyType)
{
case
BuyType.Cash:
className
=
ConfigurationManager.AppSettings[
"
cash
"
];
break
;
default
:
className
=
ConfigurationManager.AppSettings[
"
credit
"
];
break
;
}
//
buy = Assembly.Load(path).CreateInstance(className, false, BindingFlags.Default, null, new object[] { price, cut }, null, null) as IBuy;
Type type
=
Type.GetType(className,
true
);
buy
=
Activator.CreateInstance(type, price, cut)
as
IBuy;
}
public
double
GetPrice()
{
return
buy.GetPrice();
}
}
static
void
Main(
string
[] args)
{
Content c1
=
new
Content(BuyType.Cash,
200
,
40
);
Content c2
=
new
Content(BuyType.Credit,
200
,
0.7
);
Console.WriteLine(c1.GetPrice().ToString());
Console.WriteLine(c2.GetPrice().ToString());
Console.ReadKey();
}
Demo下载:
http://ljzforever.qupan.com/?folder=951925
参考的文章:
简单工厂模式 & 策略模式——《大话设计模式》读书笔记1
http://hi.baidu.com/springlie/blog/item/6052ad010f26670e1c958366.html
单一职责原则和 & 开放-封闭原则——《大话设计模式》读书笔记2
http://hi.baidu.com/springlie/blog/item/4d01d5c878efc01f7e3e6f59.html
策略模式和抽象工厂模式差别在那里??我怎么感觉两个一个样!!为了区分而区分???
http://topic.csdn.net/t/20050108/17/3709567.html
深入浅出工厂模式
http://blog.csdn.net/ai92/archive/2004/12/26/229825.aspx
深入浅出策略模式
http://blog.csdn.net/ai92/archive/2004/12/26/229825.aspx
简单工厂模式 和 策略模式 学习笔记
http://www.cnblogs.com/sun11086/archive/2009/02/06/1385510.html
简单工厂模式与工厂方法模式
http://hi.baidu.com/wookoo/blog/item/b49f1ac7f89d87ded1006097.html
策略模式和工厂模式的不同
http://www.cnblogs.com/ac1985482/archive/2009/03/07/1405608.html