0

设计模式 - Pro成

 1 year ago
source link: https://www.cnblogs.com/ProCheng/p/17509163.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

设计模式 - Pro成 - 博客园

​ 设计模式和设计原则从编程开始就接触了,但那个时候不知其所以然,工作一段时间后,再看设计模式,发现这东西在项目中或者框架中普遍存在。和以前的知识就融会贯通了。于是我打算自己写一篇关于设计原则与设计模式博文吧。

为什么要设计模式和设计原则呢?

  1. 提高代码质量和可维护性:设计模式和设计原则强调良好的软件设计原则和实践,例如高内聚、低耦合、单一职责原则等。通过遵循这些原则,可以编写结构清晰、易于理解和维护的代码。
  2. 促进代码重用:设计模式鼓励将可重用的组件和模块进行抽象和封装,使其可以在不同的上下文中重复使用。这样可以减少重复编写代码的工作量,提高开发效率
  3. 增加代码的可扩展性和灵活性:设计模式和设计原则提供了一种灵活的架构和设计方法,使系统能够轻松地扩展和适应变化。通过遵循开闭原则、依赖倒置原则等设计原则,可以使系统更容易进行功能扩展和修改。
  4. 促进团队合作和交流:设计模式提供了一种共享的设计词汇和概念,使团队成员能够更容易地理解和沟通设计决策。它们提供了一种通用的语言,促进了团队合作和代码共享。

总的来说,设计模式和设计原则是经过验证和广泛应用的最佳实践和经验总结。它们帮助开发人员构建高质量的软件系统,并提供了解决常见设计问题的方法。通过应用这些原则和模式,可以改善软件的可维护性、可扩展性和可重用性,提高开发效率,并减少代码错误和重构的需求。

一个类只做一件事

csharp
class Animal{
       void run(string name){
           console.write(name+"能跑")
       }
}

var animal = new Animal()
       animal.run("狗")  
       animal.run("小鸟") // 小鸟不能跑

       /*
可以看到Animal类是单一原则的,只做一件事
方法之前也是单一原则的,当我们传入小鸟就出现了问题
我们可以新增一个方法,这样可以保证方式是单一原则,一个方法也做一件事,以后修改互不影响
*/

依赖倒置原则

就是面向接口编程,细节依赖抽象,抽象不依赖细节

例子:有一个食物类,我们应该把它抽象出来,让具体的食物去实现食物接口,比如香蕉啊,苹果啊,白米饭啊。这时假如有一个人要进食,只需要传入食物接口,就可以了。

csharp
var people = new People();
people.eat(new Banana());
people.eat(new Apple());

// 食物接口
interface IFood
{
       // 味道
       string name{ get; set; }
   }
   
   // 香蕉
   class Banana : IFood
{
       public string name { get; set; }
}
// 苹果
class Apple : IFood
{
       public string name { get; set; }
   }

// 人
class People
{
       public void eat(IFood food)
       {
           Console.WriteLine("我要吃"+ food.name);
       }
}

对扩展开放,对修改闭合

例子:有一个喂食的类,喂食的类关联两个对象,一个食物 一个是动物,食物应该是抽象的,动物应该也是抽象的,这样我们以后要添加新的对象时,只需要实现对应的接口就行了,喂食类照样工作

csharp
var feed = new Feed();

var dogFood = new DogFood(){value = "一号狗粮"};

var tigerFood = new DogFood(){value = "一号肉食"};

var dog = new List<Dog>() { new Dog(), new Dog() };
var tiger = new List<Tiger>() { new Tiger(), new Tiger() };

feed.StartFeed(dog, dogFood);
feed.StartFeed(tiger, tigerFood);


// 能吃东西的实现这个接口
interface IEat { void eat(IFoot foot); }

// 食物实现这个接口
interface IFoot { string value { get; set; } }

// 狗是动物
class Dog : IEat
{
       public void eat(IFoot foot)
       {
           Console.WriteLine("狗吃"+foot.value);
       }
}

   // 老虎是动物
   class Tiger : IEat
   {
       public void eat(IFoot foot)
       {
           Console.WriteLine("老虎吃"+foot.value);
       }
}


// 狗吃的食物
   class DogFood : IFoot
   {
       public string value { get; set; }
   }

class TigerFood : IFoot
{
       public string value { get; set; }
}

// 喂食类
class Feed
   {
       public void StartFeed(IEnumerable<IEat> eats,IFoot foot) { 

           foreach (IEat eat in eats)
           {
               eat.eat(foot);
           }
       }
}

里氏替换原则

父类出现的地方,能用子类代替

csharp
interface IFood{ string name {get;set;} }

class Banana:IFood{
       string name {get;set;}
}
class Apple:IFood{
       string name {get;set;}
}

IFood food1 = new Banana();
IFood food2 = new Apple();

接口隔离原则

不要依赖不需要的接口,接口不要设计的太过庞大

csharp
public void StartFeed(IEnumerable<IEat> eats,IFoot foot) { 
   
       foreach (IEat eat in eats)
       {
           eat.eat(foot);
       }
}

/*

可以看到上面是满足最小接口的,
如果IEat换成 IAnimal呢,就可能出现问题,
吃这个行为只能动物进行吗?比如机器人吃电池呢
所以说,接口不要设计的太庞大,应该合理进行细分

*/

迪米特法则

一个模块对另一个模块应该要有尽可能少的了解,当要修改一个模块的时候影响的模块就小,使其功能独立。

例子:有A和B对象,B里面依赖了A,B在别的地方使用,B应该隐藏A

csharp
class A{
       void say(){
           console.write('aaa')
       }
}
class B{
       // 这里使用禁止public
       private A _A;
       public B(){
           this._A = new A()
       }
       public say(){
           // 我觉得这里是迪米特法则的核心
           this._B.say()
       }
}

class client{
       void main{
           B b = new B();
           b.say()
    }
}

创造型模式(5个)

全局只有一个实例

csharp
class Example
{
       private static Example _Example;
       static Example()
       {
           _Example = new Example();
           Console.WriteLine("构造出来了哦");
       }
       public static Example GetExample() {

           return _Example;
       }
}

工厂方法模式

创建一个工厂接口,由子类去实现具体工厂的创建。工厂创建的对象称其为产品。有了产品,当然要有创建产品接口。

csharp
IShapeFactory shapeFactory = new CircleFactory();
// 或者 IShapeFactory shapeFactory = new RectangleFactory();

IShape shape = shapeFactory.CreateShape();
shape.draw();// 我是圆

/// <summary>
/// 图型接口
/// </summary>
interface IShape
{
       void draw();
}

/// <summary>
/// 圆形类
/// </summary>
class Circle : IShape
{
       public void draw()
       {
           Console.WriteLine("我是一个圆");
       }
}
/// <summary>
/// 矩形类
/// </summary>
class Rectangle : IShape
{
       public void draw()
       {
           Console.WriteLine("我是一个矩形");
       }
}

/// <summary>
/// 图型工厂
/// </summary>
interface IShapeFactory
{
       IShape CreateShape();
}

/// <summary>
/// 生成圆形的工厂
/// </summary>
class CircleFactory : IShapeFactory
{
       public IShape CreateShape()
       {
           return new Circle();
       }
}

/// <summary>
/// 生成矩形的工厂
/// </summary>
class RectangleFactory : IShapeFactory
{
       public IShape CreateShape()
       {
           return new Rectangle();
       }
}

抽象工厂模式

抽象工厂和工厂方法类似,只不过抽象工厂是一群工厂

csharp
IGUIFactory factory = new CircleFactory();	// 这里替换后,可以生成别的产品,
IColor color1 = factory.createColor();
IText text1 = factory.createText();

color1.render();
text1.render();

/// <summary>
/// 颜色接口
/// </summary>
interface IColor
{
       void render();
}
/// <summary>
/// 文本接口
/// </summary>
interface IText {
       void render();
}

/// <summary>
/// 带颜色的圆
/// </summary
class CircleColor : IColor
{
       public void render()
       {
           Console.WriteLine("我是一个带颜色的圆");
       }
}
/// <summary>
/// 带文本的圆
/// </summary>
class CircleText : IText
{
       public void render()
       {
           Console.WriteLine("我是一个带文本的圆");
       }
}

/// <summary>
/// 带颜色的圆
/// </summary
class RectangleColor : IColor
{
       public void render()
       {
           Console.WriteLine("我是一个带颜色的矩形");
       }
}
/// <summary>
/// 带文本的圆
/// </summary>
class RectangleText : IText
{
       public void render()
       {
           Console.WriteLine("我是一个带文本的矩形");
       }
}


/// <summary>
/// 图型工厂
/// </summary>
interface IGUIFactory
{
       IColor createColor();
       IText createText();
}

/// <summary>
/// 生成圆形的工厂
/// </summary>
class CircleFactory : IGUIFactory
{
       public IColor createColor()
       {
           return new  CircleColor();
       }
       public IText createText()
       {
           return new CircleText();
       }
}

/// <summary>
/// 生成矩形的工厂
/// </summary>
class RectangleFactory : IGUIFactory
{
       public IColor createColor()
       {
           return new RectangleColor();
       }
       public IText createText()
       {
           return new RectangleText();
       }
}

建造者模式

将对象构建的过程和细节分离,如下

csharp
// 指导者,用来指导构建的类
AppleDirector appleDirector = new AppleDirector();
// 构造一个Q苹果
AppleBuild build = new QAppleBuild();
appleDirector.SetAppleBuild(build);
Apple apple = appleDirector.Build();
apple.display();


/// <summary>
/// 苹果类
/// </summary>
class Apple
{
       public string name { get; set; }
       public string color { get; set; }
       public void display() {
           Console.WriteLine(name);
           Console.WriteLine(color);
       }
}

/// <summary>
/// 抽象建造者
/// </summary>
abstract class AppleBuild{
       protected Apple _apple;
       public abstract void nameBuilder();
       public abstract void colorBuilder();
       public AppleBuild()
       {
           _apple = new Apple();
       }
       public Apple getApple() {
           return _apple;
       }
}

class QAppleBuild : AppleBuild
{
       public override void colorBuilder()
       {
           base._apple.color = "绿色";
       }
       public override void nameBuilder()
       {
           base._apple.name = "绿苹果";
       }
}

class WAppleBuild : AppleBuild
{
       public override void colorBuilder()
       {
           base._apple.color = "红色";
       }
       public override void nameBuilder()
       {
           base._apple.name = "红苹果";
       }
}

/// <summary>
/// 苹果的指导者
/// </summary>
class AppleDirector
{
       private AppleBuild _appleBuild;
       public void SetAppleBuild(AppleBuild appleBuild)
       {
           _appleBuild = appleBuild;
       }
       public Apple Build() {
           this._appleBuild.colorBuilder();
           this._appleBuild.nameBuilder();
           return this._appleBuild.getApple();
       }
}

原型工厂模式

原型工厂模式通过克隆现有对象来创建新对象

csharp
ShapeFactory factory = new ShapeFactory();
factory.GetShape(nameof(Circle)).draw();
factory.GetShape(nameof(Rectangle)).draw();

abstract class Shape
{
       public abstract void draw();
       public abstract Shape clone();
}

class Circle : Shape
{
       public override Shape clone()
       {
           return new Circle();
       }
       public override void draw()
       {
           Console.WriteLine("我是一个圆");
       }
}

class Rectangle : Shape
{
       public override Shape clone()
       {
           return new Rectangle();
       }
       public override void draw()
       {
           Console.WriteLine("我是一个矩形");
       }
}

class ShapeFactory
{
       private Dictionary<string, Shape> shapeCache;
       public ShapeFactory()
       {
           shapeCache = new Dictionary<string, Shape>();
           shapeCache.Add(nameof(Circle), new Circle());
           shapeCache.Add(nameof(Rectangle), new Rectangle());
       }

       public Shape GetShape(string type) {

           if (shapeCache.ContainsKey(type))
           {
               return shapeCache[type].clone();
           }
           return null;
       }
}

结构型模式(7个)

适配器模式

 适配器模式意在转换接口,它能够使原本不能再一起工作的两个类一起工作,所以经常用来在类库的复用

csharp
IPlay play = new VideoAdapter(new Video());

interface IPlay
{
       void show();
}
class Video
{
       public void play()
       {
           Console.WriteLine("输出视频");
       }
}

/// <summary>
/// 适配器,适配给IPlay使用
/// </summary>
class VideoAdapter : IPlay
{
       private Video video;
       public VideoAdapter(Video video)
       {
           this.video = video;
       }
       public void show()
       {
           video.play();
       }
}

将抽象和实现进行分离,两者可以独立地变化

csharp
//IShape shape = new Rectangle(new RedColor()); 具体的形状和颜色可以任意变换,业务不受影响
IShape shape = new Rectangle(new BlueColor());
shape.draw();

/// <summary>
/// 形状类
/// </summary>
interface IShape
{
       void draw();
}
class Circle : IShape
{
       private IColor color;
       public Circle(IColor color)
       {
           this.color = color;
       }
       public void draw()
       {
           Console.WriteLine("我是圆形");
           this.color.fill();
       }
}
class Rectangle : IShape
{
       private IColor color;
       public Rectangle(IColor color)
       {
           this.color = color;
       }
       public void draw()
       {
           Console.WriteLine("我是矩形");
           this.color.fill();
       }
}

/// <summary>
/// 颜色类
/// </summary>
interface IColor
{
       void fill();
}

/// <summary>
/// 红色
/// </summary>
class RedColor : IColor
{
       public void fill()
       {
           Console.WriteLine("红色");
       }
}

/// <summary>
/// 蓝色
/// </summary>
class BlueColor : IColor
{
       public void fill()
       {
           Console.WriteLine("蓝色");
       }
}

装饰者模式

在对象添加新东西,不修改原来对象

csharp
// 普通咖啡
ICoffee coffee = new Coffee();

Console.WriteLine(coffee.GetDescription());
// 装饰器装饰
coffee = new QCoffee(coffee);
Console.WriteLine(coffee.GetDescription());

coffee = new WCoffee(coffee);
Console.WriteLine(coffee.GetDescription());

/// <summary>
/// 咖啡接口
/// </summary>
interface ICoffee
{
       string GetDescription();
       double GetCost();
}

class Coffee : ICoffee
{
       public double GetCost()
       {
           return 2;
       }
       public string GetDescription()
       {
           return "咖啡";
       }
}

/// <summary>
/// 装饰器基类
/// </summary>
abstract class CoffeeDecorato : ICoffee
{
       private ICoffee coffee;
       public CoffeeDecorato(ICoffee coffee)
       {
           this.coffee = coffee;
       }
       public virtual double GetCost()
       {
           return coffee.GetCost();
       }
       public virtual string GetDescription()
       {
           return coffee.GetDescription();
       }
}

class QCoffee : CoffeeDecorato
{
       public QCoffee(ICoffee coffee) : base(coffee)
       {
       }
       public override string GetDescription()
       {
           return base.GetDescription()+"q咖啡,得价钱10块";
       }
       public override double GetCost()
       {
           return base.GetCost()+10;
       }
}

class WCoffee : CoffeeDecorato
{
       public WCoffee(ICoffee coffee) : base(coffee){}
       public override string GetDescription()
       {
           return base.GetDescription() + "w咖啡,得价钱20块";
       }
       public override double GetCost()
       {
           return base.GetCost() + 20;
       }
}

组合模式将对象组合成树形结构,用来表示整体与部分的关系

csharp
File file1 = new File("文件1");
File file2 = new File("文件2");
Folder folder1 = new Folder("文件夹1");
Folder folder2 = new Folder("文件夹2");

folder1.add(file1);
folder2.add(file2);

folder2.add(folder1);

/// <summary>
/// 抽象公共属性
/// </summary>
abstract class IFolderCommon
{
       public IFolderCommon(string name)
       {
           this.name = name;
       }
       public string name { get; set; }
}
/// <summary>
/// 文件
/// </summary>
class File : IFolderCommon
{
       public File(string name): base(name){}
}

/// <summary>
/// 文件夹
/// </summary>
class Folder : IFolderCommon
{
       public List<IFolderCommon> _folder;
       public Folder(string name) : base(name)
       {
           this._folder = new List<IFolderCommon>();
       }
       public void add(IFolderCommon folder) { 
           this._folder.Add(folder);
       }
       public void remove(IFolderCommon folder)
       {
           this._folder.Remove(folder);
       }
}

客户端不与子系统交互, 提供简化的接口,降低客户端与复杂系统的交互

csharp
/// <summary>
/// 库存管理
/// </summary>
class InventorySystem{
       // 检查库存是否足够
       public bool CheckStock(string id) {
           return false;
       }
}
/// <summary>
/// 订单管理
/// </summary>
class OrderSystem
{
       // 创建订单
       public string CreateOrder()
       {
           return "订单号";
       }
}

/// <summary>
/// 电子商务外观
/// </summary>
class ECommercePlatformFacade
{
       private InventorySystem _inventorySystem;
       private OrderSystem _orderSystem;

       public ECommercePlatformFacade()
       {
           _inventorySystem = new InventorySystem();
           _orderSystem = new OrderSystem();
       }
       // 用户下单
       public void PlaceOrder(List<string> ids) { 

           foreach (string id in ids)
           {
               // 检查库存是否足够
               if (_inventorySystem.CheckStock(id))
               {   // 创建订单
                   _orderSystem.CreateOrder();
               }
           }
       }
}

/// <summary>
/// 客户端
/// </summary>
class Client
{
       public void main() { 
           ECommercePlatformFacade platformFacade = new ECommercePlatformFacade();
           // 用户批量下单
           platformFacade.PlaceOrder(new List<string>() { "1", "2" });
       }
}

将类似的对象缓存起来,以后重复使用,避免new开销,注意对象释放时机!

csharp
/// <summary>
/// 享元接口
/// </summary>
public interface IPlayer
{
       void AssignWeapon(string weapon);
       void Play();
}

/// <summary>
/// 实现类
/// </summary>
public class Player : IPlayer
{
       private string weapon;
       public void AssignWeapon(string weapon)
       {
           this.weapon = weapon;
       }

       public void Play()
       {
           Console.WriteLine(weapon);
       }
}

/// <summary>
/// 享元工厂
/// </summary>
public class PlayerFactory
{
       /// <summary>
       /// 缓存起来,享元
       /// </summary>
       private Dictionary<string,IPlayer>  players;

       public PlayerFactory()
       {
           this.players = new Dictionary<string,IPlayer>();
       }
       public IPlayer GetPlayer(string weapon)
       {
           if (players.ContainsKey(weapon))
           {
               return players[weapon];
           }
           else
           {
               IPlayer player = new Player();
               player.AssignWeapon(weapon);
               players.Add(weapon, player);
               return player;
           }
       }
}

通过代理的方式,间接的访问对象

csharp
// 统一接口
public interface ISubject
{
       void Request();
}

// 实现类
public class RealSubject : ISubject
{
       public void Request()
       {
           Console.WriteLine("come");
       }
}

// 代理类
public class Proxy: ISubject
{
       private RealSubject realSubject;
       public void Request()
       {
           if (realSubject == null)
           {
               realSubject = new RealSubject();
           }
           // 这里进行代理
           realSubject.Request();
       }
}

// 客户端
public class Client
{
       public void main() {
           Proxy proxy = new Proxy();
           proxy.Request();
       }
}

行为型模式(11个)

模板方法模式

提供一套模板,走特定的程序,然后让子类去继承它,重写一些通用的逻辑

csharp
Template temp = new TimeTask();
temp.run();

// 模板类
abstract class Template
{
    public void run()
    {
        // 走特定的流程
        Start();
        Add();
        End();
    }
    protected void Start()
    {
        Console.WriteLine("任务开");
    }
    /// <summary>
    /// 提供一个模板
    /// </summary>
    protected abstract void Add();
    protected void End()
    {
        Console.WriteLine("任务结束");
    }
}

// 实现类
class TimeTask : Template
{
    protected override void Add()
    {
        Console.WriteLine("中间插入的内容");
    }
}

// 客户端
class Client
{
    void main() {
        Template temp = new TimeTask();
        temp.run();
    }
}

定义命令接口,实现具体的命令,然后调用者,接收一个命令接口,客户端传入具体命令

csharp
// 命令接口
interface ICommand
{
    void Execute();
}

// 命令实现类
class OpenDocument: ICommand
{
    private Document doc;
    public OpenDocument(Document doc)
    {
        this.doc = doc;
    }
    public void Execute()
    {
        this.doc.Open();
    }
}

// 命令实现类
class CloseDocument : ICommand
{
    private Document doc;
    public CloseDocument(Document doc)
    {
        this.doc = doc;
    }
    public void Execute()
    {
        this.doc.Close();
    }
}

// 文档类
class Document
{
    public void Open() { }
    public void Close() { }
}

// 客户端使用
class Button
{
    private ICommand cmd;
    public void SetCommand(ICommand cmd)
    {
        this.cmd = cmd;
    }
    public void Click()
    {
        // 写具体的业务
        cmd.Execute();
    }
}

class Client
{
    void main()
    {
        Document doc = new Document();
        ICommand cmd = new OpenDocument(doc);
        Button btn = new Button();
        btn.SetCommand(cmd);
        btn.Click();    // 打开
    }
}

迭代器模式

迭代器模式,针对集合对象,将其封装成可遍历

csharp
// 迭代器接口
public interface IIterator<T>
{
    bool hasNext();
    T next();
}

// 集合接口
public interface ICollection<T>
{
    IIterator<T> CreateIterator();
}

// 集合类的实现
public class MyCollection<T> : ICollection<T>
{
    private List<T> items;
    public MyCollection()
    {
        items = new List<T>();// 初始化集合
    }
    public void Add(T data) {

        items.Add(data);
    }
    // 转换成可迭代对象
    public IIterator<T> CreateIterator()
    {
        return new MyIterator<T>(items);
    }
}


// 迭代器的实现
public class MyIterator<T> : IIterator<T>
{
    private List<T> items;
    private int currentIndex;
    public MyIterator(List<T> items)
    {
        this.items = items;
        this.currentIndex = 0;
    }
    public bool hasNext()
    {
        return currentIndex < items.Count;
    }
    public T next()
    {
        T data = items[currentIndex];
        currentIndex++;
        return data;
    }
}

class Client
{
    void main() {
        MyCollection<string> arr = new MyCollection<string>();
        arr.Add("a");
        arr.Add("b");
        arr.Add("c");
        var iarr = arr.CreateIterator();
        while (iarr.hasNext())
        {
            Console.WriteLine(iarr.next() + "---");
        }
    }
}

观察者模式

一对多关系,当一个对象的状态发生了变化,其相关的依赖对象都能够得到通知

csharp
// 主题接口
public interface ISubject
{
   void Attach(IObserver observer);
   void Detach(IObserver observer);
   void Notify();
}

// 观察者接口
public interface IObserver
{
   void Update();
}

// 主题实现类
public class Subject : ISubject
{
   List<IObserver> observers = new List<IObserver>();
   public void Attach(IObserver observer)
   {
       observers.Add(observer);
   }

   public void Detach(IObserver observer)
   {
       observers.Remove(observer);
   }

   // 通知所有观察者
   public void Notify()
   {
       foreach (var item in observers)
       {
           item.Update();
       }
   }
   public void SetTime()
   {
       Console.WriteLine("主题设置了时间");
       this.Notify();
   }
}

// 观察者实现类
public class Observer : IObserver
{
   public void Update()
   {
       Console.WriteLine("+");
   }
}

// 客户端
class Client
{
   void main() {
       Observer observer1 = new Observer();
       Observer observer2 = new Observer();

       Subject subject = new Subject();
       subject.Attach(observer1);
       subject.Attach(observer2);
       subject.SetTime(); // 会自动通知观察者
   }
}

中介者模式

对象之间不直接通信,而是通过中介者对象来进行通信

csharp
// 中介者接口
public interface IChatRoom
{
    void SendMessage(User user,string msg);
}

// 中介者实现类
public class ChatRoom : IChatRoom
{
    List<User> users;
    public ChatRoom()
    {
        users = new List<User>();
    }
    public void SendMessage(User user, string msg)
    {
        foreach (var item in users)
        {
            if (item != user)
            {
                item.ReciveMessage(msg);
            }
        }
    }
    public void Add(User user) { 
        users.Add(user);
    }
}

// 用户类
public class User
{
    public string Name { get; set; }
    public IChatRoom ChatRoom { get; set; } 
    public User(IChatRoom chatRoom,string Name)
    {
        this.Name = Name;
        this.ChatRoom = chatRoom;
    }
    public void SendMessage(string msg) {
        // 重点!!,通过中介者进行用户交互
        ChatRoom.SendMessage(this, msg);
    }
    public void ReciveMessage(string msg) {
        Console.WriteLine("接受到消息:"+msg);
    }
}

class Client
{
    void main()
    {
        ChatRoom room = new ChatRoom();
        User user1 = new User(room, "张三");
        User user2 = new User(room, "李四");
        User user3 = new User(room, "王五");

        room.Add(user1);
        room.Add(user2);
        room.Add(user3);
        user1.SendMessage("天气不错");
    }
}

将状态封装成独立的一个类, 通过修改一个类的状态,以实现不同的逻辑

csharp
// 编辑器状态接口
public interface IEditorState
{
    void Edit();
    void Save();
}

/// <summary>
/// 编辑状态
/// </summary>
public class EditEditorState : IEditorState
{
    public void Edit()
    {
        Console.WriteLine("编辑");
    }

    public void Save()
    {
        Console.WriteLine("编辑状态 无法保存");
    }
}

// 预览状态
public class ViewEditorState : IEditorState
{
    public void Edit()
    {
        Console.WriteLine("预览状态 无法修改");
    }

    public void Save()
    {
        Console.WriteLine("保存");
    }
}


// 编辑器实现类
public class EditorState : IEditorState
{
    public IEditorState EditState { get; set; }

    // 重点 此方法更改状态,以实现不同逻辑
    public EditorState()
    {
        this.EditState = new EditEditorState();
    }
    public void SetState(IEditorState EditState)
    {
        this.EditState = EditState;
    }

    public void Edit()
    {
        this.EditState.Edit();
    }

    public void Save()
    {
        this.EditState.Save();
    }
}

// 客户端
class Client
{
    void main() {
        EditorState editor = new EditorState();
        editor.Edit();
        editor.Save();
        // 这里切换状态
        editor.SetState(new ViewEditorState());
        editor.Edit();
        editor.Save();
    }
}

将一个类的具体算法,抽离出来成为策略,切换策略可以实现不同的业务

csharp
// 策略接口
public interface IDrawingStrategy
{
    void Draw();
}

// 实线策略
public class SolidLineDrawingStrategy : IDrawingStrategy
{
    public void Draw()
    {
        Console.WriteLine("绘制实线");
    }
}

// 虚线策略
public class DottedLineDrawingStrategy : IDrawingStrategy
{
    public void Draw()
    {
        Console.WriteLine("绘制虚线");
    }
}

// 绘制策略上下文
public class DrawingContext
{
    private IDrawingStrategy drawingStrategy;

    public void SetDrawingStrategy(IDrawingStrategy drawingStrategy)
    {
        this.drawingStrategy = drawingStrategy;
    }

    // 绘制
    public void Draw() {
        drawingStrategy.Draw();
    }
}

// 客户端
class Client
{
    void main() {
        DrawingContext drawing = new DrawingContext();
        drawing.SetDrawingStrategy(new SolidLineDrawingStrategy());  // 更改策略
        drawing.Draw();

        drawing.SetDrawingStrategy(new DottedLineDrawingStrategy()); // 更改策略
        drawing.Draw();
    }
}

责任链模式

沿着处理链传递,直到有一个能处理为止

csharp
// 抽象责任链
public abstract class Handler
{
    protected Handler success;
    public void SetHandle(Handler success)
    {
        this.success = success;
    }
    public abstract void Request(int sum);
}

public class A : Handler
{
    public override void Request(int sum)
    {
        if(sum>=0 && sum <= 10)
        {
            Console.WriteLine("进入a");
        }else if (success != null)
        {
            // 传递给下一个
            success.Request(sum);
        }
    }
}

public class B : Handler
{
    public override void Request(int sum)
    {
        if (sum >10  && sum <= 20)
        {
            Console.WriteLine("进入b");
        }
        else if (success != null)
        {
            // 传递给下一个
            success.Request(sum);
        }
    }
}
public class C : Handler
{
    public override void Request(int sum)
    {
        if (sum > 20 && sum <= 30)
        {
            Console.WriteLine("进入c");
        }
        else if (success != null)
        {
            // 传递给下一个
            success.Request(sum);
        }
    }
}

// 客户端
class Client
{
    void main() {

        A a = new A();
        B b = new B();
        C c = new C();

        a.SetHandle(b);
        b.SetHandle(c);
        a.Request(15);
    }
}

访问者模式

在不改变对象的结构,定义新的操作。元素里面有一个方法来接受访问者,如此以后需要新的操作,只需要添加访问者类即可

csharp
ObjectStructure obj = new ObjectStructure();
ElementA a = new ElementA();
ElementB b = new ElementB();

VisitorA va = new VisitorA();
VisitorB vb = new VisitorB();

obj.Add(a);
obj.Add(b);

obj.show(va);
obj.show(vb);


// 访问者接口
public interface IVisitor
{
    void Visitor(IElement el);
}

// 具体访问者A
public class VisitorA : IVisitor
{
    public void Visitor(IElement el)
    {
        Console.WriteLine("访问者A进行访问");
    }
}

// 具体访问者B
public class VisitorB : IVisitor
{
    public void Visitor(IElement el)
    {
        Console.WriteLine("访问者B进行访问");
    }
}

// 元素抽象类
public abstract class IElement
{
    public abstract void Accept(IVisitor visitor);
}

// 具体元素类A
public class ElementA : IElement
{
    public override void Accept(IVisitor visitor)
    {
        visitor.Visitor(this);
    }
}

// 具体元素类B
public class ElementB: IElement
{
    public override void Accept(IVisitor visitor)
    {
        visitor.Visitor(this);
    }
}

// 定义一个结构
public class ObjectStructure{ 
    List<IElement> children;
    public ObjectStructure()
    {
        children = new List<IElement>();
    }
    public void Add(IElement element) {
        this.children.Add(element);
    }

    // 重点!,这里将访问者传递进来,访问者执行里面的逻辑
    public void show(IVisitor visitor) {

        foreach (var item in children)
        {
            item.Accept(visitor);
        }
    }
}

备忘录模式

捕获和恢复对象的状态,同时保持对象的封装性,对于实现撤销,恢复或历史记录功能的应用程序非常有用

csharp
// 备忘录
public class MemoInfo
{
    public string State { get; }
    public MemoInfo(string state)
    {
        this.State = state;
    }
}

// 操作对象
public class OriginMemo
{
    public string state;
    public string State
    {
        get
        {
            return this.state;
        }
        set
        {
            this.state = value;
            Console.WriteLine("设置成:"+this.state);
        }
    }

    public MemoInfo CreateMemoInfo() { 
        return new MemoInfo(State);
    }
    public void RestData(MemoInfo memoInfo) {

        this.state = memoInfo.State;
        Console.WriteLine("恢复成:"+this.state);
    }
}

// 管理类
public class ManagerMemo
{
    public MemoInfo Memo { get; set; }
}

class Client
{
    void main() {

        OriginMemo memo = new OriginMemo();
        memo.State = "状态1";
        ManagerMemo manager = new ManagerMemo();
        manager.Memo = memo.CreateMemoInfo();	// 这里保留原有对象
        memo.State = "状态2";
        memo.RestData(manager.Memo);	// 这里进行恢复
    }
}

解释器模式

定义语言文法,并解释该语言的表达式

csharp
// 表达式类
public interface IExpression
{
    int Interpret();
}

// 加法表达式类
public class AddExpression : IExpression
{
    private readonly IExpression left;
    private readonly IExpression right;

    public AddExpression(IExpression left,IExpression right)
    {
        this.left = left;
        this.right = right;
    }
    public int Interpret()
    {
        return left.Interpret() + right.Interpret();
    }
}

// 数字类
public class NumberExpression : IExpression
{
    private int number;

    public NumberExpression(int number = 0)
    {
        this.number = number;
    }
    public int Interpret()
    {
        return number;
    }
}

// 客户端
class Client
{
    void main() {

        IExpression a1 = new NumberExpression(1);
        IExpression a2 = new NumberExpression(3);

        IExpression a3 = new AddExpression(a1, a2);
        Console.WriteLine(a3.Interpret());
    }
}

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK