C#学习笔记-抽象工厂模式
题目1:数据访问,通过数据库对用户表单的进行访问,数据库包含SQL Server,对用户表单进行“新增用户”和“查询用户”信息等操作。
分析:
首先,确认用户表单,里面包含两个ID和Name两个字段,两种字段可以读写功能;
单独准备一个数据库的类,然后直接对用户直接进行操作即可。
实现:
using System; namespace 抽象工厂模式
{
class Program
{
static void Main(string[] args)
{
//向su数据库中添加user这个新的用户
User user = new User();
// bug:不能更换数据库的原因是su这个数据库已经被框死在了SQL Server上
SqlserverUser su = new SqlserverUser();
su.Insert(user); //在su的数据库中查找unknownUser这个用户
User unknownUser = new User();
unknownUser = su.GetUser(); Console.Read();
}
} /// <summary>
/// 用户类
/// 准备ID和Name两个字段
/// </summary>
class User
{
private int _id;
private string _name; public int Id
{
get { return _id; }
set { _id = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
} /// <summary>
/// 用于操作User表
/// “增加用户”和“得到用户”两种方法
/// </summary>
class SqlserverUser
{
/// <summary>
/// 增加用户信息
/// </summary>
/// <param name="user">新的用户信息</param>
public void Insert(User user)
{
Console.WriteLine("在SQL server中给User增加一条记录");
}
/// <summary>
/// 得到用户方法
/// </summary>
/// <param name="id">(传入信息)通过用户的id值</param>
/// <returns>(返回信息)通过id值得到对应的用户数据</returns>
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
}
题目2:在1的基础上,我们增加新的数据库Access,同样对刚才的数据库进行访问。
分析:
基于1的基础上,SqlserverUser su = new SqlserverUser();将数据库的对象定死在了SQL Server上了,这就出现了很大的局限性。
为了将SQL与Access灵活使用,我们就需要用到工厂方法模式来封装数据库,让子类决定实例化哪一个类。
实现:
using System; namespace 抽象工厂模式2
{
class Program
{
static void Main(string[] args)
{
//向iu数据库中添加user这个新的用户
User user = new User();
IFactory factory = new SqlServerFactory(); //若要更改成Access数据库 将SqlServerFactory换成AccessFactory即可
IUser iu = factory.CreateUser();
iu.Insert(user); //在iu的数据库中查找unknownUser这个用户
User unknownUser = new User();
unknownUser = iu.GetUser(); Console.Read();
}
} /// <summary>
/// 用户类
/// 准备ID和Name两个字段
/// </summary>
class User
{
private int _id;
private string _name; public int Id
{
get { return _id; }
set { _id = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
} interface IUser
{
void Insert(User user);
User GetUser(int id);
} /// <summary>
/// 用于访问SQL Server的User
/// “增加用户”和“得到用户”两种方法
/// </summary>
class SqlserverUser:IUser
{
/// <summary>
/// 增加用户信息
/// </summary>
/// <param name="user">新的用户信息</param>
public void Insert(User user)
{
Console.WriteLine("在SQL server中给User增加一条记录");
}
/// <summary>
/// 得到用户方法
/// </summary>
/// <param name="id">(传入信息)通过用户的id值</param>
/// <returns>(返回信息)通过id值得到对应的用户数据</returns>
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
/// <summary>
/// 用户访问Access的User
/// </summary>
class AccessUser : IUser
{
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
} public void Insert(User user)
{
Console.WriteLine("在Access中给User增加一条记录");
}
}
/// <summary>
/// 接口
/// 定义了一个创建访问User表对象的抽象的工厂接口
/// </summary>
interface IFactory
{
//因为sql和access都继承于IUser,所以返回值设定为IUser即可
IUser CreateUser();
}
/// <summary>
/// 实现IFactory接口,实例化SqlserverUser
/// </summary>
class SqlServerFactory : IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
}
/// <summary>
/// 实现IFactory接口,实例化AccessUser
/// </summary>
class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
}
}
题目3:在2是我基础上,我们再增加一个信息表,例如Department表来记录信息。
分析:
这里Department与User是一样信息,所以和Department的构造与User类似,再同时修改工厂类及其子类信息即可。
这里需要使用的就是抽象工厂模式(Abstract Factory),提供一个 创建一系列相关或者互相依赖对象的接口,而无需指定他们具体的类。
实现:
using System; namespace 抽象工厂模式3
{
class Program
{
static void Main(string[] args)
{
//向iu数据库中添加user这个新的用户
User user = new User();
IFactory factory = new AccessFactory();
IUser iu = factory.CreateUser();
iu.Insert(user); //在iu的数据库中查找unknownUser这个用户
User unknownUser = new User();
unknownUser = iu.GetUser(); //向id数据库中添加dept这个新的用户
Department dept = new Department();
IDepartment id = factory.CreateDepartment();
id.Insert(dept); //在id的数据库中查找unknownDept这个用户
Department unknownDept = new Department();
unknownDept = id.GetDepartment(); Console.Read();
}
} /// <summary>
/// 用户类
/// 准备ID和Name两个字段
/// </summary>
class User
{
private int _id;
private string _name; public int Id
{
get { return _id; }
set { _id = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
/// <summary>
/// 增加一个Department表
/// </summary>
class Department
{
private int _id;
private string _deptName; public int Id
{
get { return _id; }
set { _id = value; }
} public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
} interface IUser
{
void Insert(User user);
User GetUser(int id);
} /// <summary>
/// 用于访问SQL Server的User
/// “增加用户”和“得到用户”两种方法
/// </summary>
class SqlserverUser : IUser
{
/// <summary>
/// 增加用户信息
/// </summary>
/// <param name="user">新的用户信息</param>
public void Insert(User user)
{
Console.WriteLine("在SQL server中给User增加一条记录");
}
/// <summary>
/// 得到用户方法
/// </summary>
/// <param name="id">(传入信息)通过用户的id值</param>
/// <returns>(返回信息)通过id值得到对应的用户数据</returns>
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
/// <summary>
/// 用户访问Access的User
/// </summary>
class AccessUser : IUser
{
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
} public void Insert(User user)
{
Console.WriteLine("在Access中给User增加一条记录");
}
} /// <summary>
/// 与User表一致
/// </summary>
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
class SqlserverDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
return null;
} public void Insert(Department department)
{
Console.WriteLine("在SQL server中给Department增加一条记录");
}
}
class AccessDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
} public void Insert(Department department)
{
Console.WriteLine("在Access中给Department增加一条记录");
} } /// <summary>
/// 接口
/// 定义了一个创建访问User表对象的抽象的工厂接口
/// </summary>
interface IFactory
{
//因为sql和access都继承于IUser,所以返回值设定为IUser即可
IUser CreateUser();
IDepartment CreateDepartment();
}
/// <summary>
/// 实现IFactory接口,实例化SqlserverUser
/// </summary>
class SqlServerFactory : IFactory
{
public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
} public IUser CreateUser()
{
return new SqlserverUser();
} }
/// <summary>
/// 实现IFactory接口,实例化AccessUser
/// </summary>
class AccessFactory : IFactory
{
public IDepartment CreateDepartment()
{
return new AccessDepartment();
} public IUser CreateUser()
{
return new AccessUser();
}
}
}
题目4:在3中我们可以得知,如果增加一个信息表Project,就意味着需要增加信息表本身的三个类:IProject、SqlserverProject、AccessProject,同时还需要更改Ifactory、SqlserverFactory和AccessFactory才可以完全实现,那么如果我有100个调用数据库访问的类,工作量将变得巨大。
分析:
信息表本身的类是无法删减的,所以我们只有从工厂类来入手,我们将IFactory、SqlserverFactory和AccessFactory三个工厂类去除,用一个DataAccess类来代替,简化代码。
实现:
using System; namespace 抽象工厂模式4
{
class Program
{
static void Main(string[] args)
{
//向iu数据库中添加user这个新的用户
User user = new User();
IUser iu = DataAccess.CreateUser(); //直接得到实际的数据库访问实例,不存在任何依赖
iu.Insert(user); //在iu的数据库中查找unknownUser这个用户
User unknownUser = new User();
unknownUser = iu.GetUser(); //向id数据库中添加dept这个新的用户
Department dept = new Department();
IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept); //在id的数据库中查找unknownDept这个用户
Department unknownDept = new Department();
unknownDept = id.GetDepartment(); Console.Read();
}
} /// <summary>
/// 用户类
/// 准备ID和Name两个字段
/// </summary>
class User
{
private int _id;
private string _name; public int Id
{
get { return _id; }
set { _id = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
/// <summary>
/// 增加一个Department表
/// </summary>
class Department
{
private int _id;
private string _deptName; public int Id
{
get { return _id; }
set { _id = value; }
} public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
} interface IUser
{
void Insert(User user);
User GetUser(int id);
} /// <summary>
/// 用于访问SQL Server的User
/// “增加用户”和“得到用户”两种方法
/// </summary>
class SqlserverUser : IUser
{
/// <summary>
/// 增加用户信息
/// </summary>
/// <param name="user">新的用户信息</param>
public void Insert(User user)
{
Console.WriteLine("在SQL server中给User增加一条记录");
}
/// <summary>
/// 得到用户方法
/// </summary>
/// <param name="id">(传入信息)通过用户的id值</param>
/// <returns>(返回信息)通过id值得到对应的用户数据</returns>
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
/// <summary>
/// 用户访问Access的User
/// </summary>
class AccessUser : IUser
{
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
} public void Insert(User user)
{
Console.WriteLine("在Access中给User增加一条记录");
}
} /// <summary>
/// 与User表一致
/// </summary>
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
class SqlserverDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
return null;
} public void Insert(Department department)
{
Console.WriteLine("在SQL server中给Department增加一条记录");
}
}
class AccessDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
} public void Insert(Department department)
{
Console.WriteLine("在Access中给Department增加一条记录");
} } class DataAccess
{
//在此确定需要使用的数据库信息
private static readonly string db = "Sqlserver";
//private static readonly string db = "Access";
public static IUser CreateUser()
{
IUser result = null;
switch (db)
{
case "Sqlserver":
result = new SqlserverUser();
break;
case "Access":
result = new AccessUser();
break;
}
return result;
}
public static IDepartment CreateDepartment()
{
IDepartment result = null;
switch (db)
{
case "Sqlserver":
result = new SqlserverDepartment();
break;
case "Access":
result = new AccessDepartment();
break;
}
return result;
}
}
}
题目5:从4中我们可以看出简单工厂的方法就不需要输入参数,这样在客户端就只需要db的值,客户端没有出现任何一个SQL或者Access的字样,达到了解耦的目的,但是同时的问题也出现了,如果我增加了数据库,例如Oracle的数据库访问,那么就需要在DataAccess类中每个方法的switch中加case。
分析:
在实例化的过程中我们不难发现:如果是Sqlserver就会去实例化SQL Server数据库相关类,如果是Access就去实例化Access相关类,对应的数据库类可以通过字符串得出来,所以我们可以用到“反射”这种方法:Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")
实现:
using System;
using System.Reflection;//反射 namespace 抽象工厂模式5
{
class Program
{
static void Main(string[] args)
{
//向iu数据库中添加user这个新的用户
User user = new User();
IUser iu = DataAccess.CreateUser(); //直接得到实际的数据库访问实例,不存在任何依赖
iu.Insert(user); //在iu的数据库中查找unknownUser这个用户
User unknownUser = new User();
unknownUser = iu.GetUser(); //向id数据库中添加dept这个新的用户
Department dept = new Department();
IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept); //在id的数据库中查找unknownDept这个用户
Department unknownDept = new Department();
unknownDept = id.GetDepartment(); Console.Read();
}
} /// <summary>
/// 用户类
/// 准备ID和Name两个字段
/// </summary>
class User
{
private int _id;
private string _name; public int Id
{
get { return _id; }
set { _id = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
/// <summary>
/// 增加一个Department表
/// </summary>
class Department
{
private int _id;
private string _deptName; public int Id
{
get { return _id; }
set { _id = value; }
} public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
} interface IUser
{
void Insert(User user);
User GetUser(int id);
} /// <summary>
/// 用于访问SQL Server的User
/// “增加用户”和“得到用户”两种方法
/// </summary>
class SqlserverUser : IUser
{
/// <summary>
/// 增加用户信息
/// </summary>
/// <param name="user">新的用户信息</param>
public void Insert(User user)
{
Console.WriteLine("在SQL server中给User增加一条记录");
}
/// <summary>
/// 得到用户方法
/// </summary>
/// <param name="id">(传入信息)通过用户的id值</param>
/// <returns>(返回信息)通过id值得到对应的用户数据</returns>
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
/// <summary>
/// 用户访问Access的User
/// </summary>
class AccessUser : IUser
{
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
} public void Insert(User user)
{
Console.WriteLine("在Access中给User增加一条记录");
}
} /// <summary>
/// 与User表一致
/// </summary>
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
class SqlserverDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
return null;
} public void Insert(Department department)
{
Console.WriteLine("在SQL server中给Department增加一条记录");
}
}
class AccessDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
} public void Insert(Department department)
{
Console.WriteLine("在Access中给Department增加一条记录");
} } class DataAccess
{
//在此确定需要使用的数据库信息
private static readonly string AssemblyName = "抽象工厂模式5";
private static readonly string db = "Sqlserver";
//private static readonly string db = "Access"; public static IUser CreateUser()
{
string className = AssemblyName + "." + db + "User";
//Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
}
public static IDepartment CreateDepartment()
{
string className = AssemblyName + "." + db + "Department";
return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
}
}
}
题目6:在5的基础上,我们只有一点遗憾了:更换数据库访问时,我们还是需要去修改程序,也就是db这个字符串的值
分析:
我们可以利用配置文件来更改DataAccess的信息了,这样就不用去程序中修改了。

实现:
using System;
using System.Reflection;//反射
using System.Configuration; namespace 抽象工厂模式6
{
class Program
{
static void Main(string[] args)
{
//向iu数据库中添加user这个新的用户
User user = new User();
IUser iu = DataAccess.CreateUser(); //直接得到实际的数据库访问实例,不存在任何依赖
iu.Insert(user); //在iu的数据库中查找unknownUser这个用户
User unknownUser = new User();
unknownUser = iu.GetUser(); //向id数据库中添加dept这个新的用户
Department dept = new Department();
IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept); //在id的数据库中查找unknownDept这个用户
Department unknownDept = new Department();
unknownDept = id.GetDepartment(); Console.Read();
}
} /// <summary>
/// 用户类
/// 准备ID和Name两个字段
/// </summary>
class User
{
private int _id;
private string _name; public int Id
{
get { return _id; }
set { _id = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
/// <summary>
/// 增加一个Department表
/// </summary>
class Department
{
private int _id;
private string _deptName; public int Id
{
get { return _id; }
set { _id = value; }
} public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
} interface IUser
{
void Insert(User user);
User GetUser(int id);
} /// <summary>
/// 用于访问SQL Server的User
/// “增加用户”和“得到用户”两种方法
/// </summary>
class SqlserverUser : IUser
{
/// <summary>
/// 增加用户信息
/// </summary>
/// <param name="user">新的用户信息</param>
public void Insert(User user)
{
Console.WriteLine("在SQL server中给User增加一条记录");
}
/// <summary>
/// 得到用户方法
/// </summary>
/// <param name="id">(传入信息)通过用户的id值</param>
/// <returns>(返回信息)通过id值得到对应的用户数据</returns>
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
/// <summary>
/// 用户访问Access的User
/// </summary>
class AccessUser : IUser
{
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
} public void Insert(User user)
{
Console.WriteLine("在Access中给User增加一条记录");
}
} /// <summary>
/// 与User表一致
/// </summary>
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
class SqlserverDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
return null;
} public void Insert(Department department)
{
Console.WriteLine("在SQL server中给Department增加一条记录");
}
}
class AccessDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
} public void Insert(Department department)
{
Console.WriteLine("在Access中给Department增加一条记录");
} } class DataAccess
{
//在此确定需要使用的数据库信息
private static readonly string AssemblyName = "抽象工厂模式6";
//app.config是配置文件,是标准的XML文件
//我们常常访问的是appSettings,它是由.NET预定义配置的
private static readonly string db = ConfigurationSettings.AppSettings["DB"]; public static IUser CreateUser()
{
string className = AssemblyName + "." + db + "User";
//Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
}
public static IDepartment CreateDepartment()
{
string className = AssemblyName + "." + db + "Department";
return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
}
} /**
* 用简单工厂的地方,可以考虑用反射技术来去除switch或者if,接触分支判断来带的耦合
*/
}
总结:
抽象工厂模式(Abstract Factory),提供了一个创建一系列相关或者相互依赖对象的接口,而无需指定他们的具体的类。
抽象工厂模式让具体的创建实例过程与客户端分离。
注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。
C#学习笔记-抽象工厂模式的更多相关文章
- 学习笔记——抽象工厂模式Abstract Factory
在工厂模式的基础上,通过为工厂类增加接口,实现其他产品的生产,而不用一类产品就增加一个工厂. 依然以<真菌世界>游戏故事类比,树作为工厂,如果现在有两类树,一类生产快速弄真菌飞机和20毫米 ...
- 设计模式学习心得<抽象工厂模式 Abstract Factory>
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽 ...
- Java设计模式学习记录-抽象工厂模式
前言 上篇博客介绍了简单工厂模式和工厂方法模式,这次介绍抽象工厂模式,抽象工厂模式和工厂方法模式的区别在于需要创建对象的复杂程度上. 抽象工厂模式 抽象工厂模式是围绕着一个超级工厂创建其他工厂.这个超 ...
- 设计模式之笔记--抽象工厂模式(Abstract Factory)
抽象工厂模式(Abstract Factory) 定义 抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 类图 描述 多个抽象产品 ...
- Java学习笔记——Java工厂模式之简单工厂
package com.app; import java.util.Date; /* * 工厂模式:简单工厂.工厂方法.抽象工厂 * * */ public class Test0718_Factor ...
- 设计模式 笔记 抽象工厂模式 Abstract Factory
//---------------------------15/04/09---------------------------- //Abstract Factory 抽象工厂----对象创建型模式 ...
- java之设计模式工厂三兄弟之抽象工厂模式
[学习难度:★★★★☆,使用频率:★★★★★] 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工 ...
- 【设计模式】抽象工厂模式(Abstract Factory Pattern)
[前言] 上次针对自己的理解书写一篇工厂模式的文章,后面对于工厂模式进行更加多的学习,于是了解到了抽象工厂模式.其实网上大多数人们都是抽象工厂模式是工厂模式的升级版本,虽然我并不知道所说的升级是什么意 ...
- java23种设计模式(二)抽象工厂模式
我们接着上一章的工厂方法模式继续学习一下抽象工厂模式. 抽象工厂模式:在工厂模式中,如果有多个产品,则就是抽象工厂模式. 例子: 有一个工厂开了两个子公司,专门用来生产电脑配件键盘和鼠标,一个是联想工 ...
随机推荐
- 二、spring Boot构建的Web应用中,基于MySQL数据库的几种数据库连接方式进行介绍
包括JDBC.JPA.MyBatis.多数据源和事务. 一.JDBC 连接数据库 1.属性配置文件(application.properties) spring.datasource.url=jdbc ...
- 自学Python2.7-collections系列
Python collections系列 Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供 ...
- CentOS 7 学习(一) 配置LAMP和Nginx
CentOS 7 学习(一) 配置LAMP和Nginx CentOS是RedHat Linux企业版的代码编译版本,属于比较通用的服务器Linux版本,据说Ubuntu Server更通用,呵呵,不过 ...
- springboot 入门五-日志一
springboot内部采用commons logging作为日志纪录,但也保留了第三方的日志框架接入的实现,例如Java Util Logging,Log4J2还有Logback.如果你要实现一种日 ...
- iOS 环信集成项目应用
环信iOS端3.0版本集成记录--聊天界面篇 环信离线推送证书... 1,环信处在后台的时候,消息的接收与推送 离线发推送 配置属性 EMCallOptions *options = [[EMClie ...
- Mybatis-----优化配置文件,基于注解CR
这篇主要写配置文件的优化,例如 jdbc.properties 配置文件 ,引入数据库的文件,例如driver,url,username,password 等,然后在 SqlMapConfig.x ...
- xamarin android制作圆角边框
xamarin android制作圆角边框 效果图如下: 关键代码: drawable文件夹新建shape_corner_down.xml <?xml version="1.0&quo ...
- ArcGIS API for JavaScript 4.2学习笔记[22] 使用【QueryTask类】进行空间查询 / 弹窗样式
上一篇写道,使用Query类进行查询featureLayer图层的要素,也简单介绍了QueryTask类的使用. 这一篇博文继续推进,使用Query类和QueryTask类进行空间查询,查询USA的著 ...
- 重启网络服务时 Bringing up interface eth0
重启网络服务时报错: Bringing up interface eth0: Error:Connection activation failed:Device not managed by Net ...
- DataInputStream EOFEXCEPTION
在编写socket通信时,服务端使用了DataInputStream.readUTF()读取字节流时,出现EOFEXCEPTION 原因是客户端没有使用DataOutputStream.writeUT ...