今天说抽象工厂。有网友提出我闲扯太多,不好意思,这个毛病改不掉了,请多多谅解。
开始继续闲扯。
1.在C语言中void* 的指针可以转成任意类型的指针。在C#中存在有类型检查机制,且子类转成基类并不会丢数据。因为继承本意重在减少重复编写,表示已经拥有。
2.在旁边出主意的或领导或其他人最爱出主意。但是这个主意是否可行,需要实践,所以伟人说实践是检验真理的唯一标准。可以把别人出的主意,给的方法理解成抽象的方法。它只是表示一个意思。去具体实现这个意思的方法就是真实的方法,CPU肯定会找这个意思的具体方法。
3.我们解决问题,一定要先大概分析下需要做的步骤。这样可以把步骤定义成接口或抽象方法。黑猫白猫逮着老鼠就是好猫,一个问题最少有三种解决办法。故具体类有多种变化。
把工厂定义成抽象的,抽象的工厂只能生产抽象的产品,(先画饼,空口套白狼)
具体的工厂生产具体的产品。
由于子类的引用可以用基本的引用表示,所以变成了只用基类互相交互。交涉是领导与领导之间交涉,真正实施的还是小兵,领导代表小兵拿主意。
经常有人问我,接口与抽象有什么区别,从偏重方面说接口偏重于约定,抽象偏重于继承。
在此,我不再自己编写代码,直接拿来例子(备注:以后这样的例子只是研究学习用,所有权归原作者)分析:
//领导出的主意,要求的约定
interface IUser
{
void Insert(User user);
User GetUser(int id);
}
//A小兵是这样实现的
class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Sqlserver中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Sqlserver中根据ID得到User表一条记录");
return null;
}
}
//B小兵是这样实现的
class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
}
//哪个小兵掏领导欢心采用谁的办法,这可是活动的,不是固定死的。
class DataAccess
{
private static readonly string AssemblyName = "抽象工厂模式";
private static readonly string db = ConfigurationManager.AppSettings["DB"];
public static IUser CreateUser()
{
string className = AssemblyName + "." + db + "User";
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
}
public static IDepartment CreateDepartment()
{
string className = AssemblyName + "." + db + "Department";
return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
}
}
//程序=数据+算法,实体作为数据的承载着
class User
{
private int _id;
public int ID
{
get { return _id; }
set { _id = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
//主方法调用工厂创建真正的实践想法的对象。
class Program
{
static void Main(string[] args)
{
User user = new User();
Department dept = new Department();
IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(1);
IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept);
id.GetDepartment(1);
Console.Read();
}
}
总结:基对象的引用,可以表示子类型的引用,正如void*指针可以表示所有类型的指针,但是堆中的对象还是真正的对应对象。
又快12点了,晚安。