接上节:
单例设计模式的关键点
一.私有构造函数
二.声明静态单例对象
三.构造单例对象之前要加锁(lock一个静态的object对象,某些语言可以声明同步执行,其实是一个目的)
四.需要两次检测单例实例是否已经被构造,分别在锁之前和锁之后
工厂模式
题目
很多人都喜欢带手表,手表的种类很多,主要分为石英表,机械表,光能表。
• 所有的手表都有自己的名字;
• 所有的手表都有年月日时分秒(6个属性),并且可以显示时间;
• 所有的手表都可以连续打出五次自己的广告语;
• 机械表可以自动上弦;
• 石英表中的天梭(TISSOT)和机械表中的欧米茄(OMEGA)有秒表计时功能(不需要实现计时的具体逻辑);
• 光能表中的卡西欧(CASIO)可以计算X天之后是哪一天(需要自己实现逻辑,不能使用C#自带的DateTime类,注意闰年);
现在大连有一家表店有如下这些手表:
机械表:欧米茄(OMEGA),万国(IWC )
光能表:卡西欧(CASIO),西铁城(CITIZEN)
石英表:天梭(TISSOT),雷达(RADO)
写一个方法,让这些手表按顺序展示下自己的功能。
评分细则:
程序是用面向对象的思想设计的。 (20分)
合理的设计类,以及父子类之间的继承关系。 (20分)
合理设计接口,合理使用属性。(15分)
正确区分什么时候用abstract,什么时候用virtual关键字。(10分)
程序不包含明显的重复性代码,逻辑清晰,代码简洁。(15分)
计算时间的方法运行结果正确,考虑全面。(10分)
展示功能的方法可以重用,逻辑清晰简单。(10分)
*/
简单工厂
实例Code:
*以手表题目为例
• 所有的手表都有自己的名字;
• 所有的手表都有年月日时分秒(6个属性),并且可以显示时间;
• 所有的手表都可以连续打出五次自己的广告语;
这三个特性是手表的最基本特性:第一条是每个手表特有的属性,第二条是公共属性。第三条也是特有的品牌属性。
*/
class Watch
{
int watchId;
public Watch(int watchId)
{
this.watchId = watchId;
Console.WriteLine("Time Now:{0}", DateTime.Now);
}
/// <summary>
/// 默认为石英表
/// 1--电子表
/// 2--机械表
/// </summary>
/// <returns></returns>
public IProduct GetWatch()
{
switch (watchId)
{
default:
return new Quartz();
case 1:
return new Eletronic();
case 2:
return new Mechanical();
}
}
}
*IWatch接口是手表输出公共属性的关键,在接口中定义ShowTime() ShowAdvertisement() ShowName()。并且所有的手表都得继承IWatch接口并实现ShowTime() ShowAdvertisement() ShowName()。
*Quartz Eletronic Mechanical这三个对象分别表示 石英 电子 机械三种手表且都继承IWatch接口。
思考问题:
假如为了业务发展扩展生产线,我要增加一万个产品。我们再增加一万个case判断,增加一万个产品对象。但是维护起来相当麻烦。此时简单工厂已经不能满足我们的需求。我们引入第二个概念工厂模式。
工厂
实例Code:
class FactoryQuartz : IFactory
{
IProduct Quartz;
public FactoryQuartz()
{
this.Quartz = new Quartz();
}
public IProduct GetProduct()
{
Quartz.ShowName();
Quartz.ShowAdvertisement();
return this.Quartz;
}
}
public class Quartz : IWatch
{
public Quartz()
{
ShowTime();
}
public void ShowAdvertisement()
{
for (int i = 0; i < 6; i++)
{
Console.WriteLine("Advertisement Eletronic Watch");
}
}
public void ShowName()
{
Console.WriteLine("I'm Quartz Watch.");
}
public void ShowTime()
{
Console.WriteLine("Time Now:{0}", DateTime.Now);
}
}
interface IWatch
{
void ShowAdvertisement();
void ShowName();
void ShowTime();
}
思考问题:
抽象工厂
实例Code:
class AbstractFactoryCASIO : IFactory
{
IProduct Eletronic;
//IEletronic Eletronic;
public AbstractFactoryCASIO()
{
this.Eletronic = new Eletronic();
}
public IProduct GetWatch()
{
Eletronic.ShowName();
Eletronic.ShowAdvertisement();
return this.Eletronic;
}
public IEletronic CreateEletronic()
{
return new AbstractElectronicCASIO();
}
}
*我们输出产品,首先考虑它具有产品的基本性能,即GetWatch()的实现。如题:首先是一个表,而且是一个电子表。
public class Eletronic : IWatch
{
public Eletronic()
{
ShowTime();
}
public void ShowAdvertisement()
{
for (int i = 0; i < 6; i++)
{
Console.WriteLine("Advertisement Eletronic Watch");
}
}
public void ShowName()
{
Console.WriteLine("I'm Eletronic Watch");
}
public void ShowTime()
{
Console.WriteLine("Time Now:{0}", DateTime.Now);
}
}
1.在上面的代码中,都使用了接口来表达抽象工厂或者抽象产品,那么可以用抽象类吗?有何区别?
从功能上说,完全可以,甚至可以用接口来定义行为,用抽象类来抽象属性。抽象类更加偏向于属性的抽象,而用接口更加偏向行为的规范与统一。使用接口有更好的可扩展性和可维护性,更加灵活实现松散耦合,所以编程原则中有一条是针对接口编程而不是针对类编程。(如题还有个功能尚未实现,即手表的 年 月 日 时 分 秒 这六个属性就可以利用抽象对象来实现)
2. 到底何时应该用工厂模式
根据具体业务需求。不要认为简单工厂是用switch case就觉得一无是处,也不要觉得抽象工厂比较高大上就到处套。我们使用设计模式是为了解决问题而不是炫技,所以根据三种工厂模式的特质,以及对未来扩展的预期,来确定使用哪种工厂模式。
3.说说你在项目中工厂模式的应用
如题这就是例子,比其他的那种:“扶老奶奶过马路强多了”。