由于一些特殊原因,今天的教程就先将GoF中的“组合模式 ”和“命令模式”
组合模式
组合模式(结构型模式):组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对单个对象和组合对象。
类图
代码实现
IComponent(构件接口)
public interface IComponent
{
void operation();
void add(IComponent c);
void remove(IComponent c);
IComponent getComponent(int i);
}
Component(构件类)
public class Component : IComponent
{
string name;
public Component(string name)
{
this.name = name;
}
public void add(IComponent c)
{
throw new NotImplementedException();
}
public IComponent getComponent(int i)
{
throw new NotImplementedException();
}
public void operation()
{
Console.WriteLine("执行了操作"+name);
}
public void remove(IComponent c)
{
throw new NotImplementedException();
}
}
Container(构件容器类)
public class Container : IComponent
{
List
list = new List (); public void add(IComponent c)
{
list.Add(c);
}
public IComponent getComponent(int i)
{
return list[i];
}
public void operation()
{
foreach(IComponent c in list)
{
c.operation();
}
}
public void remove(IComponent c)
{
list.Remove(c);
}
}
客户端调用示例
Container c = new Container();
c.add(new Component("开机"));
c.add(new Component("滑动鼠标"));
c.add(new Component("关机"));
c.operation();
模式解析
组合模式主要可以分为以下三个角色:
构件接口
构件
构件容器
构件:主要实现该构件的业务逻辑,即operation()方法;
构件容器:这里需要说明一下,构件容器本身也是一个构件,也就是说构件容器中不仅可以包含构件,也可以包含容器,在构建容器A中可以包含构件容器B,将会采取递归的方式来执行构件容器A的operation方法。
适用环境
在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分之间的差异,客户端可以一致的调用他们。
在使用面向对象语言开发的系统中需要处理一个树形结构。
在一个系统中能够分离出构件对象和容器对象,而且他们的类型是不固定的,需要增加一些新的类型。
命令模式
命令模式(结构型):将一个请求封装成对象,从而让你可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤回的操作。
类图
代码实现
ICommand
public interface ICommand
{
void execute();
}
Invoker
public class Invoker
{
public ICommand cmd;
public Invoker(ICommand cmd)
{
this.cmd = cmd;
}
public void call()
{
cmd.execute();
}
}
Receiver
public class Receiver
{
public void action()
{
Console.WriteLine("操作操作");
}
}
Command
public class Command : ICommand
{
Receiver r = new Receiver();
public void execute()
{
r.action();
}
}
客户端调用
Invoker i = new Invoker(new Command());
i.call();
效果
模式解析
根据上面的类图和程序,我们可以看出,在命令模式中主要有四个角色:
具体命令类:有具体的接受者对象,在Execute方法中调用接受者的action方法。
调用者:及命令发送者,他通过一个命令对象来执行请求。
接受者:执行与请求相关的操作,即实现具体的业务逻辑。
命令队列
命令队列的实现需要在前面的基础上增加一个命令队列类
CommandQueue
public class CommandQueue
{
List
list = new List (); public void add(ICommand cmd)
{
list.Add(cmd);
}
public void remove(ICommand cmd)
{
list.Remove(cmd);
}
public void execute()
{
foreach(ICommand cmd in list)
{
cmd.execute();
}
}
}
原本的调用者类需要做部分修改
public class Invoker
{
//public ICommand cmd;
public CommandQueue cmd;
//public Invoker(ICommand cmd)
//{
// this.cmd = cmd;
//}
public Invoker(CommandQueue cmd)
{
this.cmd = cmd;
}
public void call()
{
cmd.execute();
}
}
使用环境
命令的发送者和命令接受者具有不同的生命周期。
命令发送了并不是立即执行。
命令的执行顺序需要进行各种逻辑管理。
单例模式
单例模式是结构最简单的设计模式,它只包涵了一个类,即单例类。
单例模式的目的是保证一个类有且仅有一个实例,并提供一个访问它的全局访问点。
这里就直接用两段程序来看看单例模式是什么样的
饿汉式单例
///
/// 饿汉式单例
///
class HungrySingle
{
private static HungrySingle single = new HungrySingle();
private HungrySingle()
{
}
public static HungrySingle get()
{
return single;
}
}
懒汉式单例
///
/// 懒汉式单例
///
class LazySingle
{
private static LazySingle single = null;
private LazySingle() { }
public static LazySingle get()
{
if(single == null)
{
single = new LazySingle();
}
return single;
}
}
使用环境
系统只需要一个实例对象,例如系统要求提供一个唯一的序列号生成器或是资源管理器,或者因为资源消耗太大二只允许创建一个对象。
客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
閱讀更多 騎著豬豬的CodeMonkey 的文章