文档章节

常用的设计模式和代码

白志华
 白志华
发布于 2015/10/18 10:55
字数 2582
阅读 5
收藏 0

设计模式是软件开发讨论中,亘古不变的话题,今天又拿出来说道两句,也是对设计模式的一个复习吧。


工厂方法模式

       工厂方法模型定义了一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到了其子类中。工厂方法模式是优化的简单工厂模式,它很好的支持了“开闭原则”。每一个具体的工厂只能构建一个类的对象。具体工厂类与产品类是一对一的关系。

/// <summary>  
/// 抽象产品类
/// </summary>  
public class Product{
	public Product(){
		Console.Write("new Product");
	} 
}

/// <summary>  
/// 具体产品类A
/// </summary>
public class ConcreteProductA:Product {
	public ConcreteProduct(){
		Console.Write("创建了一个 ConcreteProductA");
	}
}

/// <summary>  
/// 具体产品类B
/// </summary>
public class ConcreteProductB:Product {
	public ConcreteProduct(){
		Console.Write("创建了一个 ConcreteProductB");
	}
}

/// <summary>  
/// 抽象的创建者
/// </summary>
abstract public class Creator{
	
	//抽象的工厂方法
	public abstract Product FactoryMethod();
	
}

/// <summary>  
/// 具体方法工厂A
/// </summary>
public class ConcreteCreatorA:Creator{
	//返回一个产品A的对象
	public override Product FactoryMethod(){
		return new ConcreteProductA();
	}
}

/// <summary>  
/// 具体方法工厂B
/// </summary>
public class ConcreteCreatorB:Creator{
	//返回一个产品B的对象
	public override Product FactoryMethod(){
		return new ConcreteProductB();
	}
}

//client端
static void Main(string[] args)  
{  
    Creator c = new ConcreteCreatorA();
    Product p = c.FcatoryMethod();
    
    c = new ConcreteCreatorB();
    p = c.FcatoryMethod();
    
    Console.ReadLine();
}


适配器模式Adapter

      适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

      两个成熟的类需要通信,但是接口不同,由于开闭原则,我们不能去修改这两个类的接口,所以就需要一个适配器来完成衔接过程。

      变压器就是很好的适配器模式的例子。用电设备所需要的电压是9V,但是电线上的电压却是220V的,我们不能去更改它们的电压输入或输出,所以我们用到了变压器。变压器是220V的输入,9V的输出。这样就可以将200V的电压变为9V的电压,用变压器将用电设备连接到了电线上工作了。

       上面两幅图中,都是Client端需要Request这个方法,但是Adaptee没有这个方法,所以就需要提供一个中间件/包装类(Wrapper)Adapter类来衔接。不同的是第一幅图Adapter继承自Adaptee,而第二幅图是在Adapter类中包装了一个Adaptee的实例。这就决定了第一幅图讲的是“类的结构模式”,而第二幅图则是“对象的结构模式”。

/// <summary>  
/// 目标接口,客户所期待的接口。
/// </summary> 
public class Target{
	public virtual void Request(){
		Console.Write("我是本系统中的普通请求.");
	}
	
}

/// <summary>  
/// 适配器,匹配2个接口不一致的类
/// </summary> 
public class Adapter:Target{
	private Adaptee adaptee = new Adaptee();
	public void Request(){
		adaptee.SpecificRequest();
	}
}

/// <summary>  
/// 源接口,与客户期待的接口不一致
/// </summary> 
public class Adaptee(){
	public void SpecificRequest(){
		Console.Write("我是原有的真实调用的系统");
	}
}

//client端
static void Main(string[] args)  
{  
	Target t = new Adapter();
	t.Request();
	
	Console.ReadLine();
}

桥接模式 Bridge

      桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。它很好的支持了开闭原则和组合及复用原则。实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这些多角度分离出来让他们独立变化,减少他们之间的耦合。

      2个相互耦合的系列,每个系列都有各自的产品变动。将这2个系列抽象成2个角色类,将各自的变化封装到对象的角色类中,然后再将2个角色类之间用组合的关系表示,这样就大大简化了使用类继承的复杂性,逻辑变得清晰了,易于扩展和维护。

      桥接模式封装了变化,完成了解耦,实现了弱耦合

/// <summary>  
/// 抽象部分
/// </summary> 
public class Abstraction{
	protected Implementor implementor;
	
	public void SetImplementor(Implementor implementor){
		this.implementor = implementor;
	}
	
	public virtual void Operation(){
		implementor.OperationImp();
	}
}

/// <summary>  
/// 被提炼的抽象部分
/// </summary> 
public class RefinedAbstraction:Abstraction{
	
	public override void Operation(){
		implementor.OperationImp();
	}
}

/// <summary>  
/// 实现部分
/// </summary> 
abstract public class Implementor{
	public abstract void OperationImp();
}

/// <summary>  
/// 具体实现A
/// </summary> 
public class conscreteImplementorA:Implementor{
	pulic override void OperationImp(){
		Console.Write("我是具体的A");
	}
}

/// <summary>  
/// 具体实现B
/// </summary> 
public class conscreteImplementorB:Implementor{
	pulic override void OperationImp(){
		Console.Write("我是具体的B");
	}
}
//client端
static void Main(string[] args)  
{  
	Abstraction ab = new RefinedAbstraction();
	ab.SetImplementor(new conscreteImplementorA());
	ab.Operaton();
	
	ab.SetImplementor(new conscreteImplementorB());
	ab.Operaton();
	
	Console.ReadLine();
}

具体的实例可以看我的另一篇博文《面与卤的鹊桥相会——桥接模式

装饰模式 Decorator

       装饰模式动态地给一个对象添加一些额外的职责,就增加功能来说,它比生成子类更灵活。也可以这样说,装饰模式把复杂类中的核心职责和装饰功能区分开了,这样既简化了复杂类,有去除了相关类中重复的装饰逻辑。装饰模式没有通过继承原有类来扩展功能,但却达到了一样的目的,而且比继承更加灵活,所以可以说装饰模式是继承关系的一种替代方案。装饰模式解耦了核心和装饰功能,所以也是强调了松耦合 

/// <summary>  
/// 最高接口,被装饰者和“装饰品”都继承于此
/// </summary> 
abstract public class Component{
	public abstract void Operation();
}

/// <summary>  
/// 具体的被装饰者
/// </summary> 
public class Concretecomponent:Component{
	public override void Operation(){
		Console.Write("具体对象的装饰操作");
	}
}

/// <summary>  
/// 装饰类
/// </summary> 
abstract public class Decorator:Component(){
	protected Component component;
	
	public void SetComponent(Component component){
		this.component = component;
	}
	public override void Operation(){
		if(component!=null) component.Operation();
	}
}

/// <summary>  
/// 具体的装饰类A
/// </summary> 
public class ConcreteDecoratorA:Decorator{
	private string addedState;
	public override void Operation(){
		base.Operation();
		addedState="New State";
		Console.Write("具体装饰A的操作(添加了新的状态)");
	}
}

/// <summary>  
/// 具体的装饰类B
/// </summary> 
public class ConcreteDecoratorB:Decorator{
	public override void Operartion(){
		base.Operation();
		AddedBehavior();
		Console.WriteLine("具体装饰B的操作(添加了新的方法)");
	}
	private void AddedBehavior(){
		//添加新的行为
	}
}

//client端
static void Main(string[] args)  
{  
	Concretecomponent c = new Concretecomponent();
	Decorator d1 = new ConcreteDecoratorA();
	Decorator d2 = new ConcreteDecoratorB();
	
	d1.SetComponent(c);
	d2.SetComponent(d1);//注意这里装饰的是d1,因为这里的d1是装饰了d1的c。
	d2.Operation();
	
	Console.ReadLine();
}

外观模式 Facade

       外观模式为子系统中的一组接口提供了一个一致的界面,此模式定义了一个高层接口,这个接口使得这些子系统更加容易使用。

       外观模式中,客户对各个具体的子系统是不了解的,所以对这些子系统进行了封装,对外只提供了用户所明白的单一而简单的接口,用户直接使用这个接口就可以完成操作,而不用去理睬具体的过程,而且子系统的变化不会影响到用户,这样就做到了信息隐蔽。

       这就相当于新生接待员。新生对入学流程不清楚,但是接待员学长可是明白的。学生跟着接待员就可以把各个手续办理完毕了。可以说外观模式封装了细节

 

/// <summary>  
/// 高层的统一接口,封装了子系统繁杂的接口。
/// </summary> 
public class Facade{
	private SubSystemOne one;
	private SubSystemTwo two;
	private SubSystemThree three;
	
	public Facade(){
		one = new SubSystemOne();
		two = new SubSystemTwo();
		three = new SubSystemThree();
	}
	
	public void MethodA(){
		one.MethodOne();
		two.MethodTwo();
	}
	
	public void MethodB(){
		one.MethodOne();
		three.MethodThree();
	}
	
}

/// <summary>  
/// 子系统One。
/// </summary> 
public class SubSystemOne{
	public void MethodOne(){
		Console.Write("我是One");
	}
}

/// <summary>  
/// 子系统Two
/// </summary> 
public class SubSystemTwo{
	public void MethodTwo(){
		Console.Write("我是Two");
	}
}

/// <summary>  
/// 子系统Three
/// </summary> 
public class SubSystemThree{
	public void MethodThree(){
		Console.Write("我是Three");
	}
}

//client端
static void Main(string[] args)  
{
	Facade f1 = new Facade();
	f1.MethodA();
	
	Facade f2 = new Facade();
	f2.MethodB();
	
	Console.ReadLine();
}

策略模式 Strategy

       策略模式定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。本模式使得算法的变化不会影响到使用算法的客户。

       策略模式将每一个算法封装到一个具有公共接口的独立类中,解除了客户与具体算法的直接耦合,是客户改变算法更为容易。

        策略模式+简单工厂+反射+配置文件可以组成更为灵活的方式。 


/// <summary>  
/// 算法的公共接口
/// </summary> 
abstract public class Strategy{
	public abstract void AlgorithmInterface();
}

/// <summary>  
/// 具体算法A
/// </summary> 
public class ConcreteStrategyA:Strategy{
	public override void AlgorithmInterface(){
		Console.Write("具体算法A");
	}
}

/// <summary>  
/// 具体算法B
/// </summary> 
public class ConcreteStrategyB:Strategy{
	public override void AlgorithmInterface(){
		Console.Write("具体算法B");
	}
}

/// <summary>  
/// 具体算法C
/// </summary> 
public class ConcreteStrategyC:Strategy{
	public override void AlgorithmInterface(){
		Console.Write("具体算法C");
	}
}

/// <summary>  
/// 上下文,用来维护一个对Strategy对象的引用。
/// </summary> 
public class Context{
	private Strategy strategy;
	
	public Context(Strategy strategy){
		this.strategy=strategy;
	}
	
	//上下文接口
	public void ContextInterface(){
		strategy.AlgorithmInterface();
	}
}

//client端
static void Main(string[] args)
{
	Context context = new Context(new ConcreteStrategyA());
	context.ContextInterface();
	
	context = new Context(new ConcreteStrategyB());
	context.ContextInterface();
	
	context = new Context(new ConcreteStrategyC());
	context.ContextInterface();
	
	Console.ReadLine();
}

观察者模式 Observer

       观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都会得到通知,并被自动更新,

         系统中有两个方面,其中一个方面依赖与另一个方面,我们把这两个方面抽象,是各自可以独立的变化和复用。

         就像我们现在所用到的分层,不就是一层层的依赖么?还有系统组件升级,系统功能也跟着变化,这也属于观察者模式。

/// <summary>  
/// 抽象观察类
/// </summary> 
abstract public class Observer{
	public abstract void Update();
}

/// <summary>  
/// 具体观察类
/// </summary> 
public class Concreteobserver:Observer{
	private string name;
	private string observerState;
	private ConcreteSubject subject;
	
	public Concreteobserver(ConcreteSubject subject,string name){
		this.subject=subject;
		this.name= name;
	}
	
	public override void Update(){
		observerState=subject.GetState();
		Console.write("观察者{0}的新状态是{1}",name,observerState);
	}
}

/// <summary>  
/// 抽象主题类
/// </summary> 
abstract public class Subject(){
	private List<observer> observers = new List<observer>() ;
	
	public void  Attach(Observer observer){
		observers.Add(Observer);
	}
	
	public void Detach(Observer Observer){
		observers.Remove(Observer);
	}
	
	public void NotifyObservers(){
		foreach(Observer o in observers){
			o.Update();
		}
	}
}

/// <summary>  
/// 具体主题类
/// </summary> 
public class ConcreteSubject:Subject{
	private string subjectState;
	
	public string SubjectState{
		get{return subjectstate;}
		set{subjectstrate=value;}
	}
	
	public void GetState(){
		return subjectstate;
	}
}

//client端
static void Main(string[] args)  
{  
	ConcreteSubject c = new ConcreteSubject();
	Concreteobserver o1 = new Concreteobserver(c,"X");
	Concreteobserver o2 = new Concreteobserver(c,"Y");
	Concreteobserver o3 = new Concreteobserver((c,"Z");
	c.Attach(o1);
	c.Attach(o2);
	c.Attach(o3);
	c.subjectstate="abc";
	c.Nofify();
	
	Console.ReadLine();
}


欲了解其他模式,请查看我的这3篇博文:

设计模式之创建型模式

设计模式之结构型模式

设计模式之行为型模式

版权声明:本文为博主原创文章,未经博主允许不得转载。

本文转载自:http://blog.csdn.net/xiaoxian8023/article/details/8115240

共有 人打赏支持
白志华
粉丝 29
博文 265
码字总数 57524
作品 0
长沙
程序员
JavaScript设计模式之观察者模式

前言 准备研究一下MVVM的一些东西,由于MVVM运用了观察者模式的思想,因此翻开了《JavaScript设计模式与开发实践》一书,将观察者模式学习了一遍,顺便有对一些常用的设计模式进行一些了解,...

Srtian
05/22
0
0
Java设计模式 create FactoryMethod

工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。 为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经...

神勇小白鼠
2011/05/18
0
0
设计模式什么的哪有那么神秘 ----第一集 一些吐槽和重构的韵味

一日面试, ...... Hr:你对设计模式熟悉吗? 应聘者A:我了解常用的设计模式,平时经常使用工厂模式和单例模式.而且我也看过一些讲23种设计模式的书.其他不常用的模式用的不是太熟. Hr:你用过外观...

架构梦想
2013/08/04
0
7
JavaScript 中常见设计模式-代理模式

     代理模式   情景:小明追女生 A   非代理模式:小明 =花=> 女生A   代理模式:小明 =花=> 让女生A的好友B帮忙 =花=> 女生A   代理模式的特点   代理对象和本体对象具有一...

webstack前端栈
06/15
0
0
Python学习:19.Python设计模式-单例模式

一、单例模式存在的意义   在这里的单例就是只有一个实例(这里的实例就像在面向对象的时候,创建了一个对象也可以说创建了一个实例),只用一个实例进行程序设计,首先我们可以了解一下什...

BD-ld-2017
07/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

[MicroPython]STM32F407开发板驱动OLED液晶屏

1.实验目的 1.学习在PC机系统中扩展简单I/O 接口的方法。 2.进一步学习编制数据输出程序的设计方法。 3.学习 F407 Micropython开发板控制OLED显示字符。 2.所需元器件 F407 Micropython开发板...

bodasisiter
31分钟前
0
0
php require和include 相对路径一个有趣的坑

以前总是被教育,不要使用相对路径,这样性能比较差,但是相对路径的问题不仅仅是性能哦,看下面这里例子 这是项目结构 .├── main.php├── t│ ├── t1.php│ └── t2.php└─...

anoty
31分钟前
15
0
x64技术之SSDT_Hook

测试环境: 虚拟机: Windows 7 64bit 过PG工具 驱动加载工具 PCHunter64 系统自带的计算器和任务管理器等 实现思路: 实际思路与win32的思路一样.都是替换SSDT表里边的函数地址.不过微软被搞怕...

simpower
32分钟前
0
0
TreeMap源码分析,看了都说好

一、简介 TreeMap最早出现在JDK 1.2中,是 Java 集合框架中比较重要一个的实现。TreeMap 底层基于红黑树实现,可保证在log(n)时间复杂度内完成 containsKey、get、put 和 remove 操作,效率很...

Java小铺
42分钟前
0
0
协变、逆变

概念 假设 A、B表示类型 ≤ 表示继承关系 f<⋅>表示类型转换 若A ≤ B,则 A是B的子类,B是A的超类 协变、逆变 什么是型变?型变(type variance)允许对类型进行子类型转换。 为了下面讲解先...

obaniu
48分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部