设计模式个人学习笔记

(一)策略模式

策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换

在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色

策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度

(二)代理模式

为其他对象提供一种代理以控制对这个对象的访问。这是主要解决直接访问对象带来的问题
缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

(三)单例模式

实现

public class Singleton {
//1. 创建私有变量 ourInstance(用以记录 Singleton 的唯一实例)
//2. 内部进行实例化private static Singleton ourInstance  = new  Singleton();//3. 把类的构造方法私有化,不让外部调用构造方法实例化private Singleton() {}
//4. 定义公有方法提供该类的全局唯一访问点
//5. 外部通过调用getInstance()方法来返回唯一的实例public static  Singleton newInstance() {return ourInstance;}
}

优点
提供了对唯一实例的受控访问;
由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能;
可以根据实际情况需要,在单例模式的基础上扩展做出双例模式,多例模式;

缺点
单例类的职责过重,里面的代码可能会过于复杂,在一定程度上违背了“单一职责原则”。
如果实例化的对象长时间不被利用,会被系统认为是垃圾而被回收,这将导致对象状态的丢失。

(四)多例模式

所谓的多例模式(Multiton Pattern),实际上就是单例模式的自然推广。作为对象的创建模式,多例模式或多例类有如下的特点:

(1)多例类可有多个实例

(2)多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。

(3)根据是否有实例上限分为:有上限多例类和无上限多例类。

public class Emperor {private static int maxNumOfEmperor = 2; // 最多只能有连个皇帝private static ArrayList emperorInfoList = new ArrayList(maxNumOfEmperor); // 皇帝叫什么名字private static ArrayList emperorList = new ArrayList(maxNumOfEmperor); // 装皇帝的列表;private static int countNumOfEmperor = 0; // 正在被人尊称的是那个皇帝// 先把2个皇帝产生出来static {// 把所有的皇帝都产生出来for (int i = 0; i < maxNumOfEmperor; i++) {emperorList.add(new Emperor("皇" + (i + 1) + "帝"));}}// 就这么多皇帝了,不允许再推举一个皇帝(new 一个皇帝)private Emperor() {// 世俗和道德约束你,目的就是不让你产生第二个皇帝}private Emperor(String info) {emperorInfoList.add(info);}public static Emperor getInstance() {Random random = new Random();countNumOfEmperor = random.nextInt(maxNumOfEmperor); // 随机拉出一个皇帝,只要是个精神领袖就成return (Emperor) emperorList.get(countNumOfEmperor);}// 皇帝叫什么名字呀public static void emperorInfo() {System.out.println(emperorInfoList.get(countNumOfEmperor));}
public static void main(String[] args) {  int ministerNum =10; //10个大臣  for(int i=0;iout.print("第"+(i+1)+"个大臣参拜的是:");  emperor.emperorInfo();  }  }

(五)工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。

(六)抽象工厂模式

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

interface IProduct1 {  public void show();  
}  
interface IProduct2 {  public void show();  
}  class Product1 implements IProduct1 {  public void show() {  System.out.println("这是1型产品");  }  
}  
class Product2 implements IProduct2 {  public void show() {  System.out.println("这是2型产品");  }  
}  interface IFactory {  public IProduct1 createProduct1();  public IProduct2 createProduct2();  
}  
class Factory implements IFactory{  public IProduct1 createProduct1() {  return new Product1();  }  public IProduct2 createProduct2() {  return new Product2();  }  
}  public class Client {  public static void main(String[] args){  IFactory factory = new Factory();  factory.createProduct1().show();  factory.createProduct2().show();  }  
} 

抽象工厂模式的优点
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

抽象工厂模式的缺点
产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

(七)门面模式(外观模式)

门面模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。门面模式又称为外观模式,它是一种对象结构型模式

优点:

对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入门面模式,客户代码将变得很简单,与之关联的对象也很少。
实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

缺点:

不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

(八)适配器模式

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

// 已存在的、具有特殊功能、但不符合我们既有的标准接口的类  
class Adaptee {  public void specificRequest() {  System.out.println("被适配类具有 特殊功能...");  }  
}  // 目标接口,或称为标准接口  
interface Target {  public void request();  
}  // 具体目标类,只提供普通功能  
class ConcreteTarget implements Target {  public void request() {  System.out.println("普通类 具有 普通功能...");  }  
}  // 适配器类,继承了被适配类,同时实现标准接口  
class Adapter extends Adaptee implements Target{  public void request() {  super.specificRequest();  }  
}  // 测试类public class Client {  public static void main(String[] args) {  // 使用普通功能类  Target concreteTarget = new ConcreteTarget();  concreteTarget.request();  // 使用特殊功能类,即适配类  Target adapter = new Adapter();  adapter.request();  }  
}  

(九)建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

四个要素
产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。
建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。

class Product {  private String name;  private String type;  public void showProduct(){  System.out.println("名称:"+name);  System.out.println("型号:"+type);  }  public void setName(String name) {  this.name = name;  }  public void setType(String type) {  this.type = type;  }  
}  abstract class Builder {  public abstract void setPart(String arg1, String arg2);  public abstract Product getProduct();  
}  
class ConcreteBuilder extends Builder {  private Product product = new Product();  public Product getProduct() {  return product;  }  public void setPart(String arg1, String arg2) {  product.setName(arg1);  product.setType(arg2);  }  
}  public class Director {  private Builder builder = new ConcreteBuilder();  public Product getAProduct(){  builder.setPart("宝马汽车","X7");  return builder.getProduct();  }  public Product getBProduct(){  builder.setPart("奥迪汽车","Q5");  return builder.getProduct();  }  
}  
public class Client {  public static void main(String[] args){  Director director = new Director();  Product product1 = director.getAProduct();  product1.showProduct();  Product product2 = director.getBProduct();  product2.showProduct();  }  
}  

(十)模板方法模式

一个模板方法是定义在抽象类中的、把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模板方法定义在抽象类中,并由子类不加以修改地完全继承下来。模板方法是一个具体方法,它给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法。由于模板方法是具体方法,因此模板方法模式中的抽象层只能是抽象类,而不是接口。

(十一)桥梁模式

将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥梁模式的用意。
 桥梁模式分离了抽象部分和实现部分,从而极大地提供了系统的灵活性。让抽象部分和实现部分独立出来,分别定义接口,这有助于对系统进行分层,从而产生更好的结构化的系统。

(十二)命令模式

 将一个请求封装为一个对象(即我们创建的Command对象),从而使你可用不同的请求对客户进行参数化; 对请求排队或记录请求日志,以及支持可撤销的操作。

/// /// 银行帐号/// public class Account{/// /// 帐号总金额/// private decimal totalAmount { get; set; }/// /// 存钱/// /// public void MoneyIn(decimal amount){this.totalAmount += amount;}/// /// 取钱/// /// public void MoneyOut(decimal amount){this.totalAmount -= amount;}public decimal GetTotalAmout(){return totalAmount;}}public abstract class Command{protected Account account;public Command(Account account){this.account = account;}public abstract void Execute();}/// /// 存款命令/// public class MoneyInCommand : Command{private decimal amount;public MoneyInCommand(Account account, decimal amount): base(account){this.amount = amount;}/// /// 实现存钱命令/// public override void Execute(){account.MoneyIn(amount);}}/// /// 取款命令类/// public class MoneyOutCommand : Command{private decimal amount;public MoneyOutCommand(Account account, decimal amount): base(account){this.amount = amount;}/// /// 实现取钱命令/// public override void Execute(){account.MoneyOut(amount);}}public class Invoker{private Command command;public void SetCommand(Command command){this.command = command;}public void ExecuteCommand(){command.Execute();}}

客户端

  class Program{static void Main(string[] args){// 创建银行帐号Account account = new Account();// 创建一个存入500元的命令Command commandIn = new MoneyInCommand(account,500);// 创建一个调度者BankAccount.Invoker invoker = new BankAccount.Invoker();// 设置存钱命令invoker.SetCommand(commandIn);// 执行invoker.ExecuteCommand();Console.WriteLine("The current amount is " + account.GetTotalAmout().ToString("N2"));// 再次存入500Command commandIn2 = new MoneyInCommand(account, 500);invoker.SetCommand(commandIn2);invoker.ExecuteCommand();Console.WriteLine("The current amount is " + account.GetTotalAmout().ToString("N2"));// 取出300Command commandOut = new MoneyOutCommand(account, 300);invoker.SetCommand(commandOut);invoker.ExecuteCommand();Console.WriteLine("The current amount is " + account.GetTotalAmout().ToString("N2"));Console.Read();}}

(十三)装饰模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

(十四)迭代器模式

提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。

(十五)组合模式(部分整体模式)

是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
优点: 1、高层模块调用简单。 2、节点自由增加。
缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

import java.util.ArrayList;
import java.util.List;public class Employee {private String name;private String dept;private int salary;private List subordinates;//构造函数public Employee(String name,String dept, int sal) {this.name = name;this.dept = dept;this.salary = sal;subordinates = new ArrayList();}public void add(Employee e) {subordinates.add(e);}public void remove(Employee e) {subordinates.remove(e);}public List getSubordinates(){return subordinates;}public String toString(){return ("Employee :[ Name : "+ name +", dept : "+ dept + ", salary :"+ salary+" ]");}   
}
public class CompositePatternDemo {public static void main(String[] args) {Employee CEO = new Employee("John","CEO", 30000);Employee headSales = new Employee("Robert","Head Sales", 20000);Employee headMarketing = new Employee("Michel","Head Marketing", 20000);Employee clerk1 = new Employee("Laura","Marketing", 10000);Employee clerk2 = new Employee("Bob","Marketing", 10000);Employee salesExecutive1 = new Employee("Richard","Sales", 10000);Employee salesExecutive2 = new Employee("Rob","Sales", 10000);CEO.add(headSales);CEO.add(headMarketing);headSales.add(salesExecutive1);headSales.add(salesExecutive2);headMarketing.add(clerk1);headMarketing.add(clerk2);//打印该组织的所有员工System.out.println(CEO); for (Employee headEmployee : CEO.getSubordinates()) {System.out.println(headEmployee);for (Employee employee : headEmployee.getSubordinates()) {System.out.println(employee);}}     }
}

输出

Employee :[ Name : John, dept : CEO, salary :30000 ]
Employee :[ Name : Robert, dept : Head Sales, salary :20000 ]
Employee :[ Name : Richard, dept : Sales, salary :10000 ]
Employee :[ Name : Rob, dept : Sales, salary :10000 ]
Employee :[ Name : Michel, dept : Head Marketing, salary :20000 ]
Employee :[ Name : Laura, dept : Marketing, salary :10000 ]
Employee :[ Name : Bob, dept : Marketing, salary :10000 ]

(十六)观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。

解决的问题
  将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。
观察者模式用到了c#的delegate知识,不懂的同学可以去百度一下。
我目前觉得观察者模式很适合的地方是更新人物的属性完成时,
自动更新UI界面的相应部分,起到了牵一发动全身的效果

delegate声明的脚本

public delegate void  OnPlayerInfoChangedEvent(InfoType infoType);  
public event OnPlayerInfoChangedEvent OnPlayerInfoChanged;  

注册delegate

void OnPlayerInfoChanged(InfoType infoType)  {  if (infoType == InfoType.Name || infoType == InfoType.HeadPortrait || infoType == InfoType.Level || infoType == InfoType.Energy || infoType == InfoType.Toughen || infoType == InfoType.All)  {  UpdateShow();  }  }  
void Awake()  {  PlayerInfo.Instance.OnPlayerInfoChanged += OnPlayerInfoChanged;  }  

注意在销毁或其他必要的时候取消注册,否则会造成不必要的麻烦。

void OnDestroy()  {  PlayerInfo.Instance.OnPlayerInfoChanged -= OnPlayerInfoChanged;  }  

最后回到原来的声明delegate的脚本,在人物信息更新后及时作出UI更改

// Update is called once per frame  void Update () {  //体力自动增长  if (Energy<100)  {  energyTimer += Time.deltaTime;  if (energyTimer>60)  {  Energy += 1;  energyTimer -=60;  OnPlayerInfoChanged(InfoType.Energy);  }  }  else  {  energyTimer = 0;  }  if (Toughen<50)  {  toughenTimer += Time.deltaTime;  if (toughenTimer>60)  {  Toughen += 1;  toughenTimer -= 60;  }  OnPlayerInfoChanged(InfoType.Toughen);  }  else  {  toughenTimer = 0;  }  }  

(十七)访问者模式

访问者模式(visitor)表示一个作用于某对象结构中的各元素的操作。它可以使你在不改变各元素的类的前提下定义作用于这些元素的新操作。

(十八)责任链模式

某个请求需要多个对象进行处理,从而避免请求的发送者和接收之间的耦合关系。将这些对象连成一条链子,并沿着这条链子传递该请求,直到有对象处理它为止。

namespace ChainofResponsibility
{// 采购请求public class PurchaseRequest{// 金额public double Amount { get; set; }// 产品名字public string ProductName { get; set; }public PurchaseRequest(double amount, string productName){Amount = amount;ProductName = productName;}}// 审批人,Handlerpublic abstract class Approver{public Approver NextApprover { get; set; }public string Name { get; set; }public Approver(string name){this.Name = name;}public abstract void ProcessRequest(PurchaseRequest request);}// ConcreteHandlerpublic class Manager : Approver{public Manager(string name): base(name){ }public override void ProcessRequest(PurchaseRequest request){if (request.Amount < 10000.0){Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);}else if (NextApprover != null){NextApprover.ProcessRequest(request);}}}// ConcreteHandler,副总public class VicePresident : Approver{public VicePresident(string name): base(name){ }public override void ProcessRequest(PurchaseRequest request){if (request.Amount < 25000.0){Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);}else if (NextApprover != null){NextApprover.ProcessRequest(request);}}}// ConcreteHandler,总经理public class President :Approver{public President(string name): base(name){ }public override void ProcessRequest(PurchaseRequest request){if (request.Amount < 100000.0){Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);}else{Console.WriteLine("Request需要组织一个会议讨论");}}}class Program{static void Main(string[] args){PurchaseRequest requestTelphone = new PurchaseRequest(4000.0, "Telphone");PurchaseRequest requestSoftware = new PurchaseRequest(10000.0, "Visual Studio");PurchaseRequest requestComputers = new PurchaseRequest(40000.0, "Computers");Approver manager = new Manager("LearningHard");Approver Vp = new VicePresident("Tony");Approver Pre = new President("BossTom");// 设置责任链manager.NextApprover = Vp;Vp.NextApprover = Pre;// 处理请求manager.ProcessRequest(requestTelphone);manager.ProcessRequest(requestSoftware);manager.ProcessRequest(requestComputers);Console.ReadLine();}}
}

(十九) 状态模式

主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同的一系列类当中,可以把复杂的逻辑判断简单

 /// /// Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。/// public class Context{private State state;/// /// 定义Context的初始状态/// /// public Context(State state){this.state = state;}/// /// 可读写的状态属性,用于读取和设置新状态/// public State State{get { return state; }set { state = value; }}/// /// 对请求做处理,并设置下一个状态/// public void Request(){state.Handle(this);}}/// /// 抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为/// public abstract class State{public abstract void Handle(Context context);}/// /// 具体状态类,每一个子类实现一个与Context的一个状态相关的行为/// public class ConcreteStateA : State{/// /// 设置ConcreteStateA的下一个状态是ConcreteStateB/// /// public override void Handle(Context context){Console.WriteLine("当前状态是 A.");context.State = new ConcreteStateB();}}public class ConcreteStateB : State{/// /// 设置ConcreteStateB的下一个状态是ConcreteSateA/// /// public override void Handle(Context context){Console.WriteLine("当前状态是 B.");context.State = new ConcreteStateA();}}

客户端

 class Program{static void Main(string[] args){// 设置Context的初始状态为ConcreteStateAContext context = new Context(new ConcreteStateA());// 不断地进行请求,同时更改状态context.Request();context.Request();context.Request();context.Request();Console.Read();}}

(二十) 原型模式

原型模式,顾名思义就是通过对象的原型克隆而产生的新的对象

(二十一) 中介者模式

中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。

using UnityEngine;  
using System.Collections;  // 抽象牌友类  
public abstract class AbstractCardPartner  
{  public int MoneyCount { get; set; }  public AbstractCardPartner()  {  MoneyCount = 0;  }  public abstract void ChangeCount(int Count, AbstractMediator mediator);  
}  // 牌友A类  
public class ParterA : AbstractCardPartner  
{  // 依赖与抽象中介者对象  public override void ChangeCount(int Count, AbstractMediator mediator)  {  mediator.AWin(Count);  }  
}  // 牌友B类  
public class ParterB : AbstractCardPartner  
{  // 依赖与抽象中介者对象  public override void ChangeCount(int Count, AbstractMediator mediator)  {  mediator.BWin(Count);  }  
}  // 抽象中介者类  
public abstract class AbstractMediator  
{  protected AbstractCardPartner A;  protected AbstractCardPartner B;  public AbstractMediator(AbstractCardPartner a, AbstractCardPartner b)  {  A = a;  B = b;  }  public abstract void AWin(int count);  public abstract void BWin(int count);  
}  // 具体中介者类  
public class MediatorPater : AbstractMediator  
{  public MediatorPater(AbstractCardPartner a, AbstractCardPartner b)  : base(a, b)  {  }  public override void AWin(int count)  {  A.MoneyCount += count;  B.MoneyCount -= count;  }  public override void BWin(int count)  {  B.MoneyCount += count;  A.MoneyCount -= count;  }  
}  

客户端

using UnityEngine;  
using System.Collections;  public class MediatorPatternInstance : MonoBehaviour {  // Use this for initialization  void Start ()   {  AbstractCardPartner A = new ParterA();  AbstractCardPartner B = new ParterB();  // 初始钱  A.MoneyCount = 20;  B.MoneyCount = 20;  AbstractMediator mediator = new MediatorPater(A, B);  // A赢了  A.ChangeCount(5, mediator);  Debug.Log("A 现在的钱是:"+ A.MoneyCount);// 应该是25  Debug.Log("B 现在的钱是:"+ B.MoneyCount); // 应该是15  // B 赢了  B.ChangeCount(10, mediator);  Debug.Log("A 现在的钱是:"+ A.MoneyCount);// 应该是15  Debug.Log("B 现在的钱是:"+ B.MoneyCount); // 应该是25  }  
}  

中介者模式具有以下几点优点:
简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使得系统变为松耦合。
提供系统的灵活性,使得各个同事对象独立而易于复用。
然而,中介者模式也存在对应的缺点:
中介者模式中,中介者角色承担了较多的责任,所以一旦这个中介者对象出现了问题,整个系统将会受到重大的影响。例如,QQ游戏中计算欢乐豆的程序出错了,这样会造成重大的影响。
新增加一个同事类时,不得不去修改抽象中介者类和具体中介者类,此时可以使用观察者模式和状态模式来解决这个问题

(二十二) 享元模式

享元模式提供的解决方案是:

产生对象时,将能够共享的“内在状态”加以管理

并且将属于各对象能自由更改的“外部状态”也一起设置给新产生的对象中
一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象

(二十三) 备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态

public class ContactPerson{public string Name { get; set; }public string MobileNum { get; set; }}// 发起人public class MobileOwner{// 发起人需要保存的内部状态public List ContactPersons { get; set; }public MobileOwner(List persons){ContactPersons = persons;}// 创建备忘录,将当期要保存的联系人列表导入到备忘录中 public ContactMemento CreateMemento(){return new ContactMemento(new List(this.ContactPersons));25         }// 将备忘录中的数据备份导入到联系人列表中public void RestoreMemento(ContactMemento memento){this.ContactPersons = memento.contactPersonBack;}public void Show(){Console.WriteLine("联系人列表中有{0}个人,他们是:", ContactPersons.Count);foreach (ContactPerson p in ContactPersons){Console.WriteLine("姓名: {0} 号码为: {1}", p.Name, p.MobileNum);}}}// 备忘录public class ContactMemento{// 保存发起人的内部状态public List contactPersonBack;public ContactMemento(List persons){contactPersonBack = persons;}}// 管理角色public class Caretaker{public ContactMemento ContactM { get; set; }}class Program{static void Main(string[] args){List persons = new List(){new ContactPerson() { Name= "Learning Hard", MobileNum = "123445"},new ContactPerson() { Name = "Tony", MobileNum = "234565"},new ContactPerson() { Name = "Jock", MobileNum = "231455"}};MobileOwner mobileOwner = new MobileOwner(persons);mobileOwner.Show();// 创建备忘录并保存备忘录对象Caretaker caretaker = new Caretaker();caretaker.ContactM = mobileOwner.CreateMemento();// 更改发起人联系人列表Console.WriteLine("----移除最后一个联系人--------");mobileOwner.ContactPersons.RemoveAt(2);mobileOwner.Show();// 恢复到原始状态Console.WriteLine("-------恢复联系人列表------");mobileOwner.RestoreMemento(caretaker.ContactM);mobileOwner.Show();Console.Read();}}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部