public static int i;
?
我才看,不知行不行
?
我才看,不知行不行
解决方案 »
- 请教如何用wmi 拦截将要运行的进程
- 命令shutdown -r -t 0怎么写?
- 关于DataView and DataGrid的两个问题。
- DataGrid绑定数据源中类型为DateTime的数据,为什么显示出来后时间没了。
- 如何在窗体上动态添加一个button?
- 我只装了.NET SDK?每次调试程序都要到C:\winnt\microsoft.net\framework\v1.1.4322>目录下怎么样注册系统才能让我在当前的案例文件目录中
- 请教:用StreamWriter类将中文写到一个扩展名为.asp的文件中为什么会是乱码?
- xml读写问题 急急急!!!!!!!!!
- 智能提示
- 关于Button的问题
- 我再没兴趣学C#了!
- 请问各位,到底Visual Studio 7.0正式版本出来了没有?我看到了盗版的,但我不知是不是正式版本??
class GlobalVariable
{
public static int i;
}你可以直接使用GlobalVariable.i,必须把变量放在class中。
记得在编译的时候加上 /r:yourclass.dll(或在VS中的solution中加入参考)
您现在的位置:胡同口 > 电脑与网络 > Visual Studio > .NET http://b25908.xici.net
乱弹DP之SINGLETON
本帖版权归原作者,其它媒体或网站转载请与e龙西祠胡同[http://www.xici.net]或原作者联系,并注明出处。
作者: Ripper 发表日期: 2001-07-28 16:11:23 返回《.NET》 快速返回乱弹DP之SINGLETON
乱弹都谈不上,抄抄GoF(Gang of Four)的 《Design Patterns》罢了。
这次说的是SINGLETON模式,也是创建型模式之一。
SINGLETON模式的目的是:
1. 提供一个可供全局访问的类
2.保证这个类只能有一个实例(这里的叙述顺序和GoF的书相反,我觉得1比2更重要一点)。
一般SINGLETON提供一个Instance方法来返回唯一的实例,这个实例由SINGLETON本身负责创建,并保证其唯一性。
前面抄了一段《Design Patterns》,现在偶试着简单地解释一下这个模式的用途和适用的场合。
通常我们的程序里会需要用到一些全局变量,在程序中的任何地方都可以引用这些变量。比如在MFC程序当中,有一个由CWinApp类继承而来的全局实例,它就是一个SINGLETON。
作为一个类,一般地我们是可以通过声明一个local变量创建一个新的实例或者用new在heap里创建一个对象。但是考虑到有些全局变量从逻辑上看应该只有唯一实例的。比如你建立一个计算机的框架class PC,需要一个全局的变量SocketA,通过它可以获得class CPU的信息(AMD支持双cpu的主板chipset刚刚推出,这里我们不考虑有两个SocketA的情况:)。那么就可以定义一个class SocketA。很明显SocketA作为一个全局变量不应该被随便的声明,创建多个实例。我们必须阻止程序中对SocketA类的显式声明。解决的方法就是把class SocketA的构造函数隐藏起来。这样就可以防止粗心的程序员创建多个SocketA的实例。但总得有一个SocketA的实例才能使用它啊。这个创建工作由谁来负责呢?很明显程序员已经不能做这个工作了。所以应该由SocketA自己来创建自己的实例。
由此可以得到SocketA类的的声明: class SocketA
{
private static SocketA sockA = null;
public static SocketA instance()
{
if(null == sockA)
sockA=new SocketA();
return sockA;
}
public CPU cpu;
protected SocketA() {;}
}
成员sockA和方法instance都被声明成static。Instance方法中会对sockA做初始化工作。SocketA的构造函数被声明成protected,这样就不能做SocketA sa=new SocketA();的显式实例话动作。Instance方法中对sockA的初始化是一个lazy initialization,即在用到sockA的时候才对它做初始化。
下面是完整的程序:using System;
namespace singelton
{
abstract class CPU
{
public int frequency;
public abstract void overClock(int byPercent);
}
class Duron : CPU
{
public int frequency
{
get
{
return frequency;
}
set
{
frequency=value;
}
}
public override void overClock(int byPercent)
{
if (byPercent<=0)
Console.WriteLine("You should increase the frequency.");
else if(byPercent<=50)
Console.WriteLine("You need a powerful Fan.");
else if(byPercent>=51)
Console.WriteLine("Put an egg on the die before you doing this.");
}
} class SocketA
{
private static SocketA sockA = null;
public static SocketA instance()
{
if(null == sockA)
sockA=new SocketA();
return sockA;
}
//如果为cpu写get和set方法则在执行时会出错
//rIPPER不明白是为什么 :(
public CPU cpu;
protected SocketA() {;}
}
public class test
{
public static void Main()
{
SocketA.instance().cpu=new Duron();
SocketA.instance().cpu.overClock(100);
Console.ReadLine();
}
}
}再看看前文砍人专家写的《白话设计模式——Factory 方法》,IncreaseFactory负责创建不同的IncreaseClass子类,以适应需求的变化。IncreaseFactory的职责是创建其他类,无论有多少个IncreaseFactory类的实例,它们完成的功能都是一样的。所以很明显,在我们的程序里只需要一个IncreaseFactory类的实例。因此在这里可以使用SINGLETON模式来创建IncreaseFactory类(对于这个Factory Method,并不是必须使用SINGLETON,完全是举例子方便)。
下面是在砍人专家的程序基础上修改得到的SINGLETON的例子。rIPPER另外加了一些注释说明。
using System;
namespace singelton
{
abstract class IncreaseClass
{
protected double dbli;
abstract public double increase();
}
class InceraseByPercent:IncreaseClass
{
public InceraseByPercent(double toIncrease)
{
dbli= toIncrease;
}
public override double increase()
{
return dbli*1.05; //当然,变化的幅度可以用数据库来保存,这是后话。
}
} class InceraseByValue:IncreaseClass
{
public InceraseByValue(double toIncrease)
{
dbli= toIncrease;
}
public override double increase()
{
return (dbli+100);
}
} //在第二个例子中,具体的Increase类在运行的过程中通过一个Factory来动态获取。
//这下好了,如果哪天老板说超过4000的工资涨工资的策略是:先涨1%,(我靠,不如不涨),在加50,我就可以添加一个类 class IncreaseByMetabolism:IncreaseClass
{
public IncreaseByMetabolism (double toIncrease)
{
dbli= toIncrease;
} public override double increase()
{
return (dbli*1.01+50);
}
}
//Commented by rIPPER:
//IncreaseFactory类和《白话设计模式——Factory 方法》相比有比较大的变化
class IncreaseFactory//Increase类的工厂
{
//就是这个了,唯一的实例
private static IncreaseFactory increaseFactory= null;
//在这里负责创建实例
public static IncreaseFactory instance()
{
if(null==increaseFactory)
{
increaseFactory=new IncreaseFactory();
}
return increaseFactory;
}
//factory method
public IncreaseClass creatIncreaseClass(double number)
{
if (number<=2000) return new InceraseByPercent(number);
else if (number>2000 && number<=4000) return new InceraseByValue(number);
else return new IncreaseByMetabolism (number);
}
//protected的构造函数,保证无法被显示实例化
protected IncreaseFactory(){;}
}
class Employee
{
public double salary; //为了简化,这里只保留了salary。
public Employee(double dSalary)
{
salary=dSalary;
}
public void increaseSalary()
{
//Commented by rIPPER:
//这里和《白话设计模式——Factory 方法》不同
//只要用instance就可以得到一个factory,再调用它的factory method就
//可以了
IncreaseClass ibp=IncreaseFactory.instance().creatIncreaseClass(salary);
//Commented by rIPPER:
//下面这句不能通过编译,保证只有一个实例
//IncreaseFactory IF=new IncreaseFactory();
salary= ibp.increase();
System.Console.WriteLine("now the salary is "+salary);
}
}
//测试一下刚才的代码: public class test
{
public static void Main()
{
System.Console.WriteLine("Please input the number");
//Commented by rIPPER:
//这里和beta1不同,请注意
double dsalary=Convert.ToDouble(System.Console.ReadLine());
Employee emp=new Employee(dsalary);
emp.increaseSalary();
Console.ReadLine();
} }
//程序运行后,输入100,输出为105。输入3000,输出3100。OK,成功!
}后话:
由于C#没有指针,对SINGLETON的实现与Gof书中的C++例子有所不同。C++中instance方法的返回值是一个指针类型,C#中就是SINGLETON类本身的类型。
再补充一点:SINGLETON并不局限于只提供对唯一一个实例的访问。可以修改instance方法,以提供对多个实例的访问。由于对于这些实例的访问还是要通过唯一的instance方法,那么对它们的访问仍然是安全而可控的。
设想我们使用多线程技术进行任务处理。一般而言会在主线程之外创建一个worker thread,由这个线程来负责处理任务。基于方便和安全的考虑,在这里我们使用SINGLETON模式负责线程的创建。当你的程序要面临的任务数量增大而来不及处理时我们应该增加线程数量以提供处理能力。由于线程的创建工作完全由SINGLETON类来负责集中管理,我们只需要对这个类做一点修改就能实现这个变化。参考文献:
1. 《设计模式 可复用面向对象软件的继承》 Erich Gamma等机械工业出版社 2000
2. 《白话设计模式——Factory 方法》砍人专家
3. 《Design Patterns: Solidify Your C# Application Architecture with Design Patterns》 Samir Bajaj 微软MSDN杂志
小姐
不可否认
我长得很丑
可是
我很温柔
而且
永远不会说谎
mailto: [email protected]
-= MSFT .NET =-