常用的設計模式

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

工厂方法模式

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

[csharp] view plain copy print?

  1. /// <summary>
  2. /// 抽象产品类
  3. /// </summary>
  4. public class Product{
  5. public Product(){
  6. Console.Write("new Product");
  7. }
  8. }
  9. /// <summary>
  10. /// 具体产品类A
  11. /// </summary>
  12. public class ConcreteProductA:Product {
  13. public ConcreteProduct(){
  14. Console.Write("创建了一个 ConcreteProductA");
  15. }
  16. }
  17. /// <summary>
  18. /// 具体产品类B
  19. /// </summary>
  20. public class ConcreteProductB:Product {
  21. public ConcreteProduct(){
  22. Console.Write("创建了一个 ConcreteProductB");
  23. }
  24. }
  25. /// <summary>
  26. /// 抽象的创建者
  27. /// </summary>
  28. abstract public class Creator{
  29. //抽象的工厂方法
  30. public abstract Product FactoryMethod();
  31. }
  32. /// <summary>
  33. /// 具体方法工厂A
  34. /// </summary>
  35. public class ConcreteCreatorA:Creator{
  36. //返回一个产品A的对象
  37. public override Product FactoryMethod(){
  38. return new ConcreteProductA();
  39. }
  40. }
  41. /// <summary>
  42. /// 具体方法工厂B
  43. /// </summary>
  44. public class ConcreteCreatorB:Creator{
  45. //返回一个产品B的对象
  46. public override Product FactoryMethod(){
  47. return new ConcreteProductB();
  48. }
  49. }
  50. //client端
  51. static void Main(string[] args)
  52. {
  53. Creator c = new ConcreteCreatorA();
  54. Product p = c.FcatoryMethod();
  55. c = new ConcreteCreatorB();
  56. p = c.FcatoryMethod();
  57. Console.ReadLine();
  58. }

适配器模式Adapter

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

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

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

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

[csharp] view plain copy print?

  1. /// <summary>
  2. /// 目标接口,客户所期待的接口。
  3. /// </summary>
  4. public class Target{
  5. public virtual void Request(){
  6. Console.Write("我是本系统中的普通请求.");
  7. }
  8. }
  9. /// <summary>
  10. /// 适配器,匹配2个接口不一致的类
  11. /// </summary>
  12. public class Adapter:Target{
  13. private Adaptee adaptee = new Adaptee();
  14. public void Request(){
  15. adaptee.SpecificRequest();
  16. }
  17. }
  18. /// <summary>
  19. /// 源接口,与客户期待的接口不一致
  20. /// </summary>
  21. public class Adaptee(){
  22. public void SpecificRequest(){
  23. Console.Write("我是原有的真实调用的系统");
  24. }
  25. }
  26. //client端
  27. static void Main(string[] args)
  28. {
  29. Target t = new Adapter();
  30. t.Request();
  31. Console.ReadLine();
  32. }

桥接模式 Bridge

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

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

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

[csharp] view plain copy print?

  1. /// <summary>
  2. /// 抽象部分
  3. /// </summary>
  4. public class Abstraction{
  5. protected Implementor implementor;
  6. public void SetImplementor(Implementor implementor){
  7. this.implementor = implementor;
  8. }
  9. public virtual void Operation(){
  10. implementor.OperationImp();
  11. }
  12. }
  13. /// <summary>
  14. /// 被提炼的抽象部分
  15. /// </summary>
  16. public class RefinedAbstraction:Abstraction{
  17. public override void Operation(){
  18. implementor.OperationImp();
  19. }
  20. }
  21. /// <summary>
  22. /// 实现部分
  23. /// </summary>
  24. abstract public class Implementor{
  25. public abstract void OperationImp();
  26. }
  27. /// <summary>
  28. /// 具体实现A
  29. /// </summary>
  30. public class conscreteImplementorA:Implementor{
  31. pulic override void OperationImp(){
  32. Console.Write("我是具体的A");
  33. }
  34. }
  35. /// <summary>
  36. /// 具体实现B
  37. /// </summary>
  38. public class conscreteImplementorB:Implementor{
  39. pulic override void OperationImp(){
  40. Console.Write("我是具体的B");
  41. }
  42. }
  43. //client端
  44. static void Main(string[] args)
  45. {
  46. Abstraction ab = new RefinedAbstraction();
  47. ab.SetImplementor(new conscreteImplementorA());
  48. ab.Operaton();
  49. ab.SetImplementor(new conscreteImplementorB());
  50. ab.Operaton();
  51. Console.ReadLine();
  52. }

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

装饰模式 Decorator

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

[csharp] view plain copy print?

  1. /// <summary>
  2. /// 最高接口,被装饰者和“装饰品”都继承于此
  3. /// </summary>
  4. abstract public class Component{
  5. public abstract void Operation();
  6. }
  7. /// <summary>
  8. /// 具体的被装饰者
  9. /// </summary>
  10. public class Concretecomponent:Component{
  11. public override void Operation(){
  12. Console.Write("具体对象的装饰操作");
  13. }
  14. }
  15. /// <summary>
  16. /// 装饰类
  17. /// </summary>
  18. abstract public class Decorator:Component(){
  19. protected Component component;
  20. public void SetComponent(Component component){
  21. this.component = component;
  22. }
  23. public override void Operation(){
  24. if(component!=null) component.Operation();
  25. }
  26. }
  27. /// <summary>
  28. /// 具体的装饰类A
  29. /// </summary>
  30. public class ConcreteDecoratorA:Decorator{
  31. private string addedState;
  32. public override void Operation(){
  33. base.Operation();
  34. addedState="New State";
  35. Console.Write("具体装饰A的操作(添加了新的状态)");
  36. }
  37. }
  38. /// <summary>
  39. /// 具体的装饰类B
  40. /// </summary>
  41. public class ConcreteDecoratorB:Decorator{
  42. public override void Operartion(){
  43. base.Operation();
  44. AddedBehavior();
  45. Console.WriteLine("具体装饰B的操作(添加了新的方法)");
  46. }
  47. private void AddedBehavior(){
  48. //添加新的行为
  49. }
  50. }
  51. //client端
  52. static void Main(string[] args)
  53. {
  54. Concretecomponent c = new Concretecomponent();
  55. Decorator d1 = new ConcreteDecoratorA();
  56. Decorator d2 = new ConcreteDecoratorB();
  57. d1.SetComponent(c);
  58. d2.SetComponent(d1);//注意这里装饰的是d1,因为这里的d1是装饰了d1的c。
  59. d2.Operation();
  60. Console.ReadLine();
  61. }

外观模式 Facade

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

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

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

[csharp] view plain copy print?

  1. /// <summary>
  2. /// 高层的统一接口,封装了子系统繁杂的接口。
  3. /// </summary>
  4. public class Facade{
  5. private SubSystemOne one;
  6. private SubSystemTwo two;
  7. private SubSystemThree three;
  8. public Facade(){
  9. one = new SubSystemOne();
  10. two = new SubSystemTwo();
  11. three = new SubSystemThree();
  12. }
  13. public void MethodA(){
  14. one.MethodOne();
  15. two.MethodTwo();
  16. }
  17. public void MethodB(){
  18. one.MethodOne();
  19. three.MethodThree();
  20. }
  21. }
  22. /// <summary>
  23. /// 子系统One。
  24. /// </summary>
  25. public class SubSystemOne{
  26. public void MethodOne(){
  27. Console.Write("我是One");
  28. }
  29. }
  30. /// <summary>
  31. /// 子系统Two
  32. /// </summary>
  33. public class SubSystemTwo{
  34. public void MethodTwo(){
  35. Console.Write("我是Two");
  36. }
  37. }
  38. /// <summary>
  39. /// 子系统Three
  40. /// </summary>
  41. public class SubSystemThree{
  42. public void MethodThree(){
  43. Console.Write("我是Three");
  44. }
  45. }
  46. //client端
  47. static void Main(string[] args)
  48. {
  49. Facade f1 = new Facade();
  50. f1.MethodA();
  51. Facade f2 = new Facade();
  52. f2.MethodB();
  53. Console.ReadLine();
  54. }

策略模式 Strategy

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

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

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

[csharp] view plain copy print?

  1. /// <summary>
  2. /// 算法的公共接口
  3. /// </summary>
  4. abstract public class Strategy{
  5. public abstract void AlgorithmInterface();
  6. }
  7. /// <summary>
  8. /// 具体算法A
  9. /// </summary>
  10. public class ConcreteStrategyA:Strategy{
  11. public override void AlgorithmInterface(){
  12. Console.Write("具体算法A");
  13. }
  14. }
  15. /// <summary>
  16. /// 具体算法B
  17. /// </summary>
  18. public class ConcreteStrategyB:Strategy{
  19. public override void AlgorithmInterface(){
  20. Console.Write("具体算法B");
  21. }
  22. }
  23. /// <summary>
  24. /// 具体算法C
  25. /// </summary>
  26. public class ConcreteStrategyC:Strategy{
  27. public override void AlgorithmInterface(){
  28. Console.Write("具体算法C");
  29. }
  30. }
  31. /// <summary>
  32. /// 上下文,用来维护一个对Strategy对象的引用。
  33. /// </summary>
  34. public class Context{
  35. private Strategy strategy;
  36. public Context(Strategy strategy){
  37. this.strategy=strategy;
  38. }
  39. //上下文接口
  40. public void ContextInterface(){
  41. strategy.AlgorithmInterface();
  42. }
  43. }
  44. //client端
  45. static void Main(string[] args)
  46. {
  47. Context context = new Context(new ConcreteStrategyA());
  48. context.ContextInterface();
  49. context = new Context(new ConcreteStrategyB());
  50. context.ContextInterface();
  51. context = new Context(new ConcreteStrategyC());
  52. context.ContextInterface();
  53. Console.ReadLine();
  54. }

观察者模式 Observer

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

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

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

[csharp] view plain copy print?

    1. /// <summary>
    2. /// 抽象观察类
    3. /// </summary>
    4. abstract public class Observer{
    5. public abstract void Update();
    6. }
    7. /// <summary>
    8. /// 具体观察类
    9. /// </summary>
    10. public class Concreteobserver:Observer{
    11. private string name;
    12. private string observerState;
    13. private ConcreteSubject subject;
    14. public Concreteobserver(ConcreteSubject subject,string name){
    15. this.subject=subject;
    16. this.name= name;
    17. }
    18. public override void Update(){
    19. observerState=subject.GetState();
    20. Console.write("观察者{0}的新状态是{1}",name,observerState);
    21. }
    22. }
    23. /// <summary>
    24. /// 抽象主题类
    25. /// </summary>
    26. abstract public class Subject(){
    27. private List<observer> observers = new List<observer>() ;
    28. public void  Attach(Observer observer){
    29. observers.Add(Observer);
    30. }
    31. public void Detach(Observer Observer){
    32. observers.Remove(Observer);
    33. }
    34. public void NotifyObservers(){
    35. foreach(Observer o in observers){
    36. o.Update();
    37. }
    38. }
    39. }
    40. /// <summary>
    41. /// 具体主题类
    42. /// </summary>
    43. public class ConcreteSubject:Subject{
    44. private string subjectState;
    45. public string SubjectState{
    46. get{return subjectstate;}
    47. set{subjectstrate=value;}
    48. }
    49. public void GetState(){
    50. return subjectstate;
    51. }
    52. }
    53. //client端
    54. static void Main(string[] args)
    55. {
    56. ConcreteSubject c = new ConcreteSubject();
    57. Concreteobserver o1 = new Concreteobserver(c,"X");
    58. Concreteobserver o2 = new Concreteobserver(c,"Y");
    59. Concreteobserver o3 = new Concreteobserver((c,"Z");
    60. c.Attach(o1);
    61. c.Attach(o2);
    62. c.Attach(o3);
    63. c.subjectstate="abc";
    64. c.Nofify();
    65. Console.ReadLine();
    66. }
时间: 2024-07-29 05:53:09

常用的設計模式的相关文章

設計模式--抽象工廠模式

抽象工廠用例圖 代碼 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(dep

設計模式具體應用

大话设计模式中的利用反射加抽象工厂的数据访问程序.先来看看反射技术的基本格式:--反射工廠 Assembly.Load(“程序集名称”).CreateInstance(“命名空间.类名称”); 只要在程序顶端写上using System.Reflection来引用Reflection,就可以采用反射工厂来克服抽象工厂模式的先天不足.下面我们来看通过反射技术实现不同数据库的访问程序. DataAccess类,用反射技术,取代了抽象工厂中的IFactory,SqlServerFactory和Acce

實戰設計模式之工厂方法模式

對於http請求原理的朋友應該了解IIS上後綴映射 /*当我们请求一个*.aspx的文件时,此时会映射到System.Web.UI.PageHandlerFactory类上进行处理,而对*.ashx的请求将映射到System.Web.UI.SimpleHandlerFactory类中(这两个类都是继承于IHttpHandlerFactory接口的)*/ 下面用一線圖來直觀的看一下 圖引用:http://www.cnblogs.com/zhili/p/FactoryMethod.html 為了更直

設計模式觀察者模式

觀察者用例圖 代碼 class Program { static void Main(string[] args) { ConcreteSubject s = new ConcreteSubject(); s.Attach(new ConcreteObserver(s, "X")); s.Attach(new ConcreteObserver(s, "Y")); s.Attach(new ConcreteObserver(s, "Z")); s.

[設計模式].01.簡單工廠模式

用戶接口 1 //定義一個用戶該有的操作 2 public interface IUser 3 { 4 bool Login(string userName, string psw); 5 bool Login(); 6 bool Exsit(); 7 } 用戶抽象類 1 //定義一個抽象類,讓它去實現IUser接口 2 //編寫每個要User類需要執行的操作,如登錄信息記錄到日志,修飾符定義為可重寫virtual 3 public abstract class User : IUser 4 {

VR廣告設計與商業

<VR廣告設計與商業>培訓營 課程 By 高煥堂/台灣VR產業聯盟 主席  2016.11月 在Buy+購物的浪潮下,<VR廣告製作>也水漲船高,歡迎您一起來學習VR廣告製作技術. 進入無框世界 我們知道,傳統多媒體大多給觀眾圈定了一個"框",例如TV建構了一個有框世界,讓人們從框外觀看框裡的節目.而VR技術則打破了傳統螢幕的"框",引導人們進入螢幕的框內,給予一個完整的世界.在廣告方面,從"有框"到"無框&qu

這個日曆戳一下,一天就往時了|這個設計了不得

俺們每日都為你舉薦幾個最近察覺的好設計.「這個設計了不得」的微信市民號上線啦,直爽搜new balance 580查「BestDesign」或者「Qthings」就能夠訂閱,留意俺們每天發覺的新奇好設計.Buzzifloat by Alain Gilles更少的原料體現著未有足夠的安閒度?在吉布提科隆國外工作家倶及裝備展( ORGATEC )上,盧旺達設計師 Alain Gilles 用為家私企業 BuzziSpace 所設計的極簡風座椅 Buzzifloat 給出了否認的解答.座椅的設計靈性出

通過數據了解用戶——數據在新品設計中的應用

通常情況下,我們可以通過用戶訪談的方法了解用戶需求,其實設計師還可以通過分析用戶問卷調查數據以及網站頁面數據等方式,了解用戶需求以及用戶在使用產品時遇到的問題. 而且,直接通過接觸用戶了解到的需求有可能只是個案,為了增強客觀性,通常都會通過大樣本調查,從數據實證的角度,進一步更準確和客觀地找到用戶的普遍需求. 此外,通過對數據分析結果與用戶訪談所得到的定性分析結論,進行比較和綜合分析,設計師也能夠從不同的角度了解用戶的真實需求. 從用研的角度來看,交互設計包括新產品設計以及已有產品的改版設計兩大

面向對象設計原則

我寫面向對象是有套路的. 自古深情留不住,唯有套路得人心. 简介 对于一个以面向对象软件设计思想构建的系统来说,系统的可维护性和可复用性都是至关重要的,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计思想需要解决的核心问题之一.在面向对象设计思想中,可维护的复用性是以面向对象的设计原则为基础的.面向对象设计原则是为支持可维护的复用性而诞生的,这些原则蕴含在很多设计模式中,它们是从许多软件设计方案中总结出来的指导性原则.最为常见的面向对象设计原则如下所示:面相对象设计的五个基本原则SOL