前言:
设计模式这本书看过有一段时间了,但是总结的过程一直没有进行,可能也是因为浅尝辄止的学习,实在不知道写些什么。但是学习过程是需要的,虽然是一孔之见但是希望在以后的学习中能及时的回过头来补充和丰富。
从之前的第一次机房收费系统功能实现的喜悦到现在学习了设计模式之后会觉得那种编程是一种不考虑实际应用的代码实现。作为面向对象语言的三大特性:封装、继承、多态。而设计模式的两大主题:系统复用与系统扩展正好和面向对象的特性交相呼应,使得设计模式的应用能够更大程度的优化面向对象编程过程中的不足。下面按照使用的频率介绍几种设计模式:
1、 单例模式:
保证一个类仅有一个实例并提供一个访问它的全局访问点。 而单例模式中又细分为饿汉式单例化和懒汉式单例化,区别:类在何时实例化的不同。懒汉式单例化面临着多线程访问的安全性问题,所以只有通过双锁+判断的方式才能保证安全。饿汉式单例化是随着类的加载就实例化出对象,所以即使后面没有用到的对象也可能已经被实例化,这样就不可避免的消耗了内存。
(1)懒汉式单例化
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); //在判断中实例化,需要的才实例化对象
}
return instance;
}
}
(2)饿汉式单例化
public class Singleton {
private static Singleton instance = new Singleton(); //在初始化时即实例化,随着类的加载
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
(3)扩展:static关键字
特点:A:可以修饰成员变量和成员方法;B:随着类的加载而加载 C:优先于对象存在 D:被类的所有对象共享。这其实也是我们判断该不该使用静态的依据。举例:饮水机和水杯的问题思考 F:可以通过类名调用,既可以通过对象名调用,也可以通过类名调用,建议通过类名调用。
静态的注意事项;A:在静态方法中没有this对象。 B:静态方法只能访问静态成员变量和成员方法
2、三个工厂模式
public class OperationFactory{
public static OPeration creatOperate(){
OPeration oper=null;
switch(){
case "+":oper=new OPerationAdd();break
case "-":oper=new OPerationSub();break
case "*":oper=new OPerationMul();break
case "/":oper=new OPerationDiv();break
}
}
}
工厂方法:定义一个用于创建对象的接口,让子类决定实例化那个类,工厂方法使一个类的实例化延迟到子类。
interface IFactory
{
Operation CreateOperation();
}
class AddFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationAdd();
}
}
class SubFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationSub();
}
}
class MulFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationMul();
}
}
class DivFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationDiv();
}
}
比较:简单工厂的优点在于工厂类中包含了必要的逻辑判断,根据客户端的条件选择使用哪一种计算方法,但是如果增加新的方法需要在原有的工厂类中增加,这样就违反了设计模式的一个很重要的原则开放-封闭原则。工厂方法正是很好的解决了这个缺点,通过对每一种方法建立类,通过接口实现计算工厂达到不需要打开简单工厂的唯一工厂就可以增加新的功能方法,满足了扩展性。工厂方法把简单工厂的内部逻辑判断转移到了客户端,你想要增加功能原本修改工厂类,现在是修改客户端。
抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
interface IDepartment
{
void Insert(Department department);
IDepartment GetDepartment(int id);
}
class SqlserverDepartment : IDepartment //SqlserverDepartment类,用于访问sql server的Department
{
public void Insert(Department department)
{
Console.WriteLine("在SQL server中给User表增加一条记录");
}
public Department GetDaparment(int id)
{
Console.WriteLine("在SQL server中根据ID得到user表中的一条记录");
return null;
}
}
class AccessDepartment : IDepartment //AccessDepartment类,用于访问Access的Department
{
public void Insert(Department department)
{
Console.WriteLine("在SQL server中给User表增加一条记录");
}
public Department GetDaparment(int id)
{
Console.WriteLine("在SQL server中根据ID得到user表中的一条记录");
return null;
}
}
interface IFactory //IFactory接口,定义一个创建访问Department对象的抽象的工厂接口
{
IUser CreateUser();
IDepartment CreateDepartment();
}
class SqlserverFactory : IFactory //sqlserverFactory类,实现IFactory接口,实例化sqlserverUser和sqlserverDepartment
{
public IUser CreateUser()
{
return new SqlserverUser();
}
public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
}
class AccessFactory : IFactory //AccessFactory类,实现IFactory接口,实例化AccessUser和AccessDepartment
{
public IUser CreateUser()
{
return new AccessFactory();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}
优点:具体的创建实例过程与客户端分离,客户端通过他们的抽象接口操纵实现,产品的具体类名也被具体工厂实现分离。
什么时候能够用到抽象工厂:就是能够像这样抽象的时候(这个我也不知道该怎么表达只能意会了)
数据库访问的实现:
两种抽象产品:增加记录、得到记录
四种具体产品:SQLserver增加记录、SQLserver得到记录、Access增加记录、Access得到记录
具体工厂角色:Access、SQLserver
举例:农场系统的实现
两种抽象产品:水果、蔬菜
四种具体产品:北方水果,热带水果,北方蔬菜,热带蔬菜
具体工厂角色:北方工厂,热带角色