使用c#實(shí)現(xiàn)23種常見(jiàn)的設(shè)計(jì)模式|全球新消息
設(shè)計(jì)模式通常分為三個(gè)主要類(lèi)別:
創(chuàng)建型模式
結(jié)構(gòu)型模式
(相關(guān)資料圖)
行為型模式。
這些模式是用于解決常見(jiàn)的對(duì)象導(dǎo)向設(shè)計(jì)問(wèn)題的最佳實(shí)踐。
以下是23種常見(jiàn)的設(shè)計(jì)模式并且提供c#代碼案例
:
public sealed class Singleton{ //創(chuàng)建一個(gè)只讀的靜態(tài)Singleton實(shí)例 private static readonly Singleton instance = new Singleton(); // 記錄Singleton的創(chuàng)建次數(shù) private static int instanceCounter = 0; // 單例實(shí)例的公共訪(fǎng)問(wèn)點(diǎn) public static Singleton Instance { get { return instance; } } // 私有構(gòu)造函數(shù) private Singleton() { instanceCounter++; Console.WriteLine("Instances Created " + instanceCounter); } // 在此處添加其他的Singleton類(lèi)方法 public void LogMessage(string message) { Console.WriteLine("Message: " + message); }}
在這個(gè)例子中,我們有一個(gè)名為Singleton
的類(lèi),它有一個(gè)私有的構(gòu)造函數(shù)和一個(gè)靜態(tài)的只讀屬性Instance
,用于訪(fǎng)問(wèn)Singleton
類(lèi)的唯一實(shí)例。我們還有一個(gè)LogMessage
方法,用于模擬Singleton
類(lèi)的某個(gè)行為。
以下是一個(gè)使用這個(gè)Singleton
類(lèi)的控制臺(tái)應(yīng)用程序:
class Program{ static void Main(string[] args) { Singleton fromEmployee = Singleton.Instance; fromEmployee.LogMessage("Message from Employee"); Singleton fromBoss = Singleton.Instance; fromBoss.LogMessage("Message from Boss"); Console.ReadLine(); }}
2. 工廠(chǎng)方法模式(Factory Method)工廠(chǎng)方法模式是一種創(chuàng)建型設(shè)計(jì)模式,它提供了一種創(chuàng)建對(duì)象的接口,但允許子類(lèi)決定實(shí)例化哪個(gè)類(lèi)。工廠(chǎng)方法讓類(lèi)的實(shí)例化推遲到子類(lèi)中進(jìn)行。
下面是一個(gè)使用C#實(shí)現(xiàn)的工廠(chǎng)方法模式的簡(jiǎn)單示例:
// 抽象產(chǎn)品public interface IProduct{ string Operation();}// 具體產(chǎn)品Apublic class ProductA : IProduct{ public string Operation() { return "{Result of ProductA}"; }}// 具體產(chǎn)品Bpublic class ProductB : IProduct{ public string Operation() { return "{Result of ProductB}"; }}// 抽象創(chuàng)建者public abstract class Creator{ public abstract IProduct FactoryMethod();}// 具體創(chuàng)建者Apublic class CreatorA : Creator{ public override IProduct FactoryMethod() { return new ProductA(); }}// 具體創(chuàng)建者Bpublic class CreatorB : Creator{ public override IProduct FactoryMethod() { return new ProductB(); }}
以上代碼中定義了兩個(gè)產(chǎn)品ProductA
和ProductB
,這兩個(gè)產(chǎn)品都實(shí)現(xiàn)了IProduct
接口。接著我們有兩個(gè)Creator類(lèi),CreatorA
和CreatorB
,它們都繼承自抽象基類(lèi)Creator
。CreatorA
工廠(chǎng)創(chuàng)建ProductA
,CreatorB
工廠(chǎng)創(chuàng)建ProductB
。
以下是一個(gè)使用這些工廠(chǎng)和產(chǎn)品的示例:
class Program{ static void Main(string[] args) { // 創(chuàng)建工廠(chǎng)對(duì)象 Creator creatorA = new CreatorA(); Creator creatorB = new CreatorB(); // 通過(guò)工廠(chǎng)方法創(chuàng)建產(chǎn)品對(duì)象 IProduct productA = creatorA.FactoryMethod(); IProduct productB = creatorB.FactoryMethod(); // 打印結(jié)果 Console.WriteLine("ProductA says: " + productA.Operation()); Console.WriteLine("ProductB says: " + productB.Operation()); Console.ReadLine(); }}
當(dāng)你運(yùn)行這個(gè)程序時(shí),它會(huì)顯示出ProductA
和ProductB
的Operation
方法返回的結(jié)果。這說(shuō)明我們已經(jīng)成功地使用工廠(chǎng)方法模式創(chuàng)建了產(chǎn)品實(shí)例。每個(gè)工廠(chǎng)類(lèi)決定了它創(chuàng)建哪個(gè)產(chǎn)品的實(shí)例。這種方式使得客戶(hù)端代碼不需要直接實(shí)例化產(chǎn)品類(lèi),而只需要依賴(lài)工廠(chǎng)接口,增加了程序的靈活性。
抽象工廠(chǎng)模式是一種創(chuàng)建型設(shè)計(jì)模式,它提供了一種接口,用于創(chuàng)建相關(guān)或依賴(lài)對(duì)象的系列,而不指定這些對(duì)象的具體類(lèi)。在這個(gè)模式中,客戶(hù)端通過(guò)他們的抽象接口使用類(lèi),允許該模式在不影響客戶(hù)端的情況下替換實(shí)現(xiàn)類(lèi)。
以下是一個(gè)簡(jiǎn)單的抽象工廠(chǎng)模式的C#實(shí)現(xiàn):
// 抽象產(chǎn)品:動(dòng)物public interface IAnimal{ string Speak();}// 具體產(chǎn)品:狗public class Dog : IAnimal{ public string Speak() { return "Bark Bark"; }}// 具體產(chǎn)品:貓public class Cat : IAnimal{ public string Speak() { return "Meow Meow"; }}// 抽象工廠(chǎng)public abstract class IAnimalFactory{ public abstract IAnimal CreateAnimal();}// 具體工廠(chǎng):狗工廠(chǎng)public class DogFactory : IAnimalFactory{ public override IAnimal CreateAnimal() { return new Dog(); }}// 具體工廠(chǎng):貓工廠(chǎng)public class CatFactory : IAnimalFactory{ public override IAnimal CreateAnimal() { return new Cat(); }}
以上代碼定義了兩種動(dòng)物Dog
和Cat
,它們都實(shí)現(xiàn)了IAnimal
接口。然后我們有兩個(gè)工廠(chǎng)類(lèi),DogFactory
和CatFactory
,它們都繼承自IAnimalFactory
。DogFactory
生產(chǎn)Dog
,而CatFactory
生產(chǎn)Cat
。
以下是一個(gè)使用這些工廠(chǎng)和產(chǎn)品的示例:
class Program{ static void Main(string[] args) { // 創(chuàng)建工廠(chǎng) IAnimalFactory dogFactory = new DogFactory(); IAnimalFactory catFactory = new CatFactory(); // 使用工廠(chǎng)創(chuàng)建產(chǎn)品 IAnimal dog = dogFactory.CreateAnimal(); IAnimal cat = catFactory.CreateAnimal(); // 打印結(jié)果 Console.WriteLine("Dog says: " + dog.Speak()); Console.WriteLine("Cat says: " + cat.Speak()); Console.ReadLine(); }}
當(dāng)你運(yùn)行這個(gè)程序時(shí),會(huì)打印出Dog和Cat的Speak方法的結(jié)果,這顯示了我們已經(jīng)成功地使用了抽象工廠(chǎng)模式創(chuàng)建了產(chǎn)品實(shí)例。這種方式使得客戶(hù)端代碼不需要直接實(shí)例化產(chǎn)品類(lèi),而只需要依賴(lài)工廠(chǎng)接口,增加了程序的靈活性和擴(kuò)展性。
4. 建造者模式(Builder)建造者模式是一種創(chuàng)建型設(shè)計(jì)模式,它提供了一種創(chuàng)建對(duì)象的接口,但是允許使用相同的構(gòu)建過(guò)程來(lái)創(chuàng)建不同的產(chǎn)品。
以下是在C#中實(shí)現(xiàn)建造者模式的一個(gè)簡(jiǎn)單示例:
// 產(chǎn)品public class Car{ public string Engine { get; set; } public string Wheels { get; set; } public string Doors { get; set; }}// 建造者抽象類(lèi)public abstract class CarBuilder{ protected Car car; public void CreateNewCar() { car = new Car(); } public Car GetCar() { return car; } public abstract void SetEngine(); public abstract void SetWheels(); public abstract void SetDoors();}// 具體建造者public class FerrariBuilder : CarBuilder{ public override void SetEngine() { car.Engine = "V8"; } public override void SetWheels() { car.Wheels = "18 inch"; } public override void SetDoors() { car.Doors = "2"; }}// 指揮者public class Director{ public Car Construct(CarBuilder carBuilder) { carBuilder.CreateNewCar(); carBuilder.SetEngine(); carBuilder.SetWheels(); carBuilder.SetDoors(); return carBuilder.GetCar(); }}
以上代碼中,Car
是我們要?jiǎng)?chuàng)建的產(chǎn)品,CarBuilder
是抽象的建造者,定義了制造一個(gè)產(chǎn)品所需要的各個(gè)步驟,FerrariBuilder
是具體的建造者,實(shí)現(xiàn)了CarBuilder
定義的所有步驟,Director
是指揮者,它告訴建造者應(yīng)該按照什么順序去執(zhí)行哪些步驟。
以下是一個(gè)使用這個(gè)建造者模式的示例:
class Program{ static void Main(string[] args) { Director director = new Director(); CarBuilder builder = new FerrariBuilder(); Car ferrari = director.Construct(builder); Console.WriteLine($"Engine: {ferrari.Engine}, Wheels: {ferrari.Wheels}, Doors: {ferrari.Doors}"); Console.ReadLine(); }}
當(dāng)你運(yùn)行這個(gè)程序時(shí),會(huì)看到我們已經(jīng)成功地創(chuàng)建了一個(gè)Car
實(shí)例,它的各個(gè)部分是按照FerrariBuilder
所定義的方式創(chuàng)建的。這說(shuō)明我們使用建造者模式成功地將一個(gè)復(fù)雜對(duì)象的構(gòu)造過(guò)程解耦,使得同樣的構(gòu)造過(guò)程可以創(chuàng)建不同的表示。
原型模式是一種創(chuàng)建型設(shè)計(jì)模式,它實(shí)現(xiàn)了一個(gè)原型接口,該接口用于創(chuàng)建當(dāng)前對(duì)象的克隆。當(dāng)直接創(chuàng)建對(duì)象的代價(jià)比較大時(shí),則采用這種模式。例如,一個(gè)對(duì)象需要在一個(gè)高代價(jià)的數(shù)據(jù)庫(kù)操作后被創(chuàng)建。
以下是在C#中實(shí)現(xiàn)原型模式的一個(gè)簡(jiǎn)單示例:
// 抽象原型public interface IPrototype{ IPrototype Clone();}// 具體原型public class ConcretePrototype : IPrototype{ public string Name { get; set; } public int Value { get; set; } public IPrototype Clone() { // 實(shí)現(xiàn)深拷貝 return (ConcretePrototype)this.MemberwiseClone(); // Clones the concrete object. }}
以上代碼定義了一個(gè)ConcretePrototype
類(lèi),它實(shí)現(xiàn)了IPrototype
接口。接口定義了一個(gè)Clone
方法,用于復(fù)制對(duì)象。在ConcretePrototype
類(lèi)中,我們使用了MemberwiseClone
方法來(lái)創(chuàng)建一個(gè)新的克隆對(duì)象。
以下是一個(gè)使用原型模式的示例:
class Program{ static void Main(string[] args) { ConcretePrototype prototype = new ConcretePrototype(); prototype.Name = "Original"; prototype.Value = 10; Console.WriteLine("Original instance: " + prototype.Name + ", " + prototype.Value); ConcretePrototype clone = (ConcretePrototype)prototype.Clone(); Console.WriteLine("Cloned instance: " + clone.Name + ", " + clone.Value); Console.ReadLine(); }}
在這個(gè)例子中,我們創(chuàng)建了一個(gè)ConcretePrototype
對(duì)象,并為其屬性賦值,然后我們調(diào)用Clone
方法創(chuàng)建了一個(gè)新的ConcretePrototype
對(duì)象。當(dāng)我們運(yùn)行這個(gè)程序時(shí),會(huì)看到原始對(duì)象和克隆對(duì)象的屬性是相同的,這表明我們已經(jīng)成功地克隆了一個(gè)對(duì)象。
執(zhí)行流程如下:
創(chuàng)建一個(gè)具體的原型對(duì)象,為其屬性賦值。調(diào)用原型對(duì)象的Clone
方法,創(chuàng)建一個(gè)新的對(duì)象,該對(duì)象的屬性與原型對(duì)象的屬性相同。打印原型對(duì)象和克隆對(duì)象的屬性,驗(yàn)證它們是否相同。結(jié)構(gòu)型模式: 6. 適配器模式(Adapter)1. 橋接模式(Bridge)橋接模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,用于將抽象部分與其實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。
以下是在C#中實(shí)現(xiàn)橋接模式的一個(gè)簡(jiǎn)單示例:
// 實(shí)現(xiàn)類(lèi)接口public interface IImplementor{ void OperationImp();}// 具體實(shí)現(xiàn)類(lèi)Apublic class ConcreteImplementorA : IImplementor{ public void OperationImp() { Console.WriteLine("Concrete Implementor A"); }}// 具體實(shí)現(xiàn)類(lèi)Bpublic class ConcreteImplementorB : IImplementor{ public void OperationImp() { Console.WriteLine("Concrete Implementor B"); }}// 抽象類(lèi)public abstract class Abstraction{ protected IImplementor implementor; public Abstraction(IImplementor implementor) { this.implementor = implementor; } public virtual void Operation() { implementor.OperationImp(); }}// 擴(kuò)充的抽象類(lèi)public class RefinedAbstraction : Abstraction{ public RefinedAbstraction(IImplementor implementor) : base(implementor) { } public override void Operation() { Console.WriteLine("Refined Abstraction is calling implementor"s method:"); base.Operation(); }}
在這個(gè)代碼中,Abstraction
是抽象類(lèi),它有一個(gè)IImplementor
接口的實(shí)例,通過(guò)這個(gè)實(shí)例調(diào)用實(shí)現(xiàn)類(lèi)的方法。RefinedAbstraction
是擴(kuò)充的抽象類(lèi),它繼承自Abstraction
。ConcreteImplementorA
和ConcreteImplementorB
是實(shí)現(xiàn)類(lèi),它們實(shí)現(xiàn)了IImplementor
接口。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { IImplementor implementorA = new ConcreteImplementorA(); Abstraction abstractionA = new RefinedAbstraction(implementorA); abstractionA.Operation(); IImplementor implementorB = new ConcreteImplementorB(); Abstraction abstractionB = new RefinedAbstraction(implementorB); abstractionB.Operation(); Console.ReadLine(); }}
在這個(gè)例子中,我們創(chuàng)建了兩個(gè)實(shí)現(xiàn)類(lèi)的實(shí)例,然后創(chuàng)建了兩個(gè)抽象類(lèi)的實(shí)例,每個(gè)抽象類(lèi)的實(shí)例都有一個(gè)實(shí)現(xiàn)類(lèi)的實(shí)例。當(dāng)我們調(diào)用抽象類(lèi)的Operation
方法時(shí),它會(huì)調(diào)用實(shí)現(xiàn)類(lèi)的OperationImp
方法。
執(zhí)行流程如下:
創(chuàng)建實(shí)現(xiàn)類(lèi)的實(shí)例。創(chuàng)建抽象類(lèi)的實(shí)例,抽象類(lèi)的實(shí)例有一個(gè)實(shí)現(xiàn)類(lèi)的實(shí)例。調(diào)用抽象類(lèi)的Operation
方法,該方法會(huì)調(diào)用實(shí)現(xiàn)類(lèi)的OperationImp
方法。2. 組合模式(Composite)組合模式(Composite pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,它可以使你將對(duì)象組合成樹(shù)形結(jié)構(gòu),并且能像使用獨(dú)立對(duì)象一樣使用它們。這種模式的主要目的是使單個(gè)對(duì)象和組合對(duì)象具有一致性。
以下是在C#中實(shí)現(xiàn)組合模式的一個(gè)簡(jiǎn)單示例:
// 抽象組件類(lèi)public abstract class Component{ protected string name; public Component(string name) { this.name = name; } public abstract void Add(Component c); public abstract void Remove(Component c); public abstract void Display(int depth);}// 葉節(jié)點(diǎn)類(lèi)public class Leaf : Component{ public Leaf(string name) : base(name) { } public override void Add(Component c) { Console.WriteLine("Cannot add to a leaf"); } public override void Remove(Component c) { Console.WriteLine("Cannot remove from a leaf"); } public override void Display(int depth) { Console.WriteLine(new String("-", depth) + name); }}// 構(gòu)件容器類(lèi)public class Composite : Component{ private List _children = new List(); public Composite(string name) : base(name) { } public override void Add(Component component) { _children.Add(component); } public override void Remove(Component component) { _children.Remove(component); } public override void Display(int depth) { Console.WriteLine(new String("-", depth) + name); // 顯示每個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn) foreach (Component component in _children) { component.Display(depth + 2); } }}
在這個(gè)代碼中,Component
是組件抽象類(lèi),它有一個(gè)名字,并定義了添加、刪除和顯示操作。Leaf
是葉子節(jié)點(diǎn),它實(shí)現(xiàn)了Component
的操作。Composite
是組件容器,它可以添加、刪除和顯示其子節(jié)點(diǎn)。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { Composite root = new Composite("root"); root.Add(new Leaf("Leaf A")); root.Add(new Leaf("Leaf B")); Composite comp = new Composite("Composite X"); comp.Add(new Leaf("Leaf XA")); comp.Add(new Leaf("Leaf XB")); root.Add(comp); Composite comp2 = new Composite("Composite XY"); comp2.Add(new Leaf("Leaf XYA")); comp2.Add(new Leaf("Leaf XYB")); comp.Add(comp2); root.Add(new Leaf("Leaf C")); // 在組合中添加和刪除 Leaf leaf = new Leaf("Leaf D"); root.Add(leaf); root.Remove(leaf); // 顯示樹(shù)形結(jié)構(gòu) root.Display(1); Console.ReadLine(); }}
在這個(gè)例子中,我們創(chuàng)建了一個(gè)根節(jié)點(diǎn),并在其中添加了兩個(gè)葉子節(jié)點(diǎn)。然后我們創(chuàng)建了一個(gè)復(fù)合節(jié)點(diǎn),并在其中添加了兩個(gè)葉子節(jié)點(diǎn),然后我們把復(fù)合節(jié)點(diǎn)添加到根節(jié)點(diǎn)中。我們還在復(fù)合節(jié)點(diǎn)中添加了另一個(gè)復(fù)合節(jié)點(diǎn)。最后,我們又在根節(jié)點(diǎn)中添加和刪除了一個(gè)葉子節(jié)點(diǎn),然后顯示了樹(shù)的結(jié)構(gòu)。
執(zhí)行流程如下:
創(chuàng)建組合和葉子對(duì)象。通過(guò)調(diào)用組合對(duì)象的Add
方法將葉子對(duì)象和其他組合對(duì)象添加到組合對(duì)象中。通過(guò)調(diào)用組合對(duì)象的Remove
方法將葉子對(duì)象從組合對(duì)象中移除。調(diào)用組合對(duì)象的Display
方法顯示組合對(duì)象的結(jié)構(gòu)。3. 裝飾模式(Decorator)裝飾模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它允許在運(yùn)行時(shí)動(dòng)態(tài)地將功能添加到對(duì)象中,這種模式提供了比繼承更有彈性的解決方案。
以下是在C#中實(shí)現(xiàn)裝飾模式的一個(gè)簡(jiǎn)單示例:
// 抽象組件public abstract class Component{ public abstract string Operation();}// 具體組件public class ConcreteComponent : Component{ public override string Operation() { return "ConcreteComponent"; }}// 抽象裝飾器public abstract class Decorator : Component{ protected Component component; public Decorator(Component component) { this.component = component; } public override string Operation() { if (component != null) { return component.Operation(); } else { return string.Empty; } }}// 具體裝飾器Apublic class ConcreteDecoratorA : Decorator{ public ConcreteDecoratorA(Component comp) : base(comp) { } public override string Operation() { return $"ConcreteDecoratorA({base.Operation()})"; }}// 具體裝飾器Bpublic class ConcreteDecoratorB : Decorator{ public ConcreteDecoratorB(Component comp) : base(comp) { } public override string Operation() { return $"ConcreteDecoratorB({base.Operation()})"; }}
在這個(gè)代碼中,Component
是一個(gè)抽象組件,它定義了一個(gè)Operation
方法。ConcreteComponent
是具體組件,它實(shí)現(xiàn)了Component
的Operation
方法。Decorator
是一個(gè)抽象裝飾器,它包含一個(gè)Component
對(duì)象,并重寫(xiě)了Operation
方法。ConcreteDecoratorA
和ConcreteDecoratorB
是具體的裝飾器,它們繼承了Decorator
并重寫(xiě)了Operation
方法,以添加新的功能。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { // 基本組件 Component component = new ConcreteComponent(); Console.WriteLine("Basic Component: " + component.Operation()); // 裝飾后的組件 Component decoratorA = new ConcreteDecoratorA(component); Console.WriteLine("A Decorated: " + decoratorA.Operation()); Component decoratorB = new ConcreteDecoratorB(decoratorA); Console.WriteLine("B Decorated: " + decoratorB.Operation()); Console.ReadLine(); }}
在這個(gè)例子中,我們首先創(chuàng)建了一個(gè)ConcreteComponent
對(duì)象,并調(diào)用它的Operation
方法。然后我們創(chuàng)建了一個(gè)ConcreteDecoratorA
對(duì)象,它裝飾了ConcreteComponent
,并調(diào)用它的Operation
方法。最后,我們創(chuàng)建了一個(gè)ConcreteDecoratorB
對(duì)象,它裝飾了ConcreteDecoratorA
,并調(diào)用它的Operation
方法。這樣,我們就可以在運(yùn)行時(shí)動(dòng)態(tài)地添加功能。
執(zhí)行流程如下:
創(chuàng)建一個(gè)具體組件對(duì)象并調(diào)用其操作。創(chuàng)建一個(gè)裝飾器對(duì)象,該對(duì)象裝飾了具體組件,并調(diào)用其操作。在操作中,裝飾器首先調(diào)用具體組件的操作,然后執(zhí)行額外的操作。創(chuàng)建另一個(gè)裝飾器對(duì)象,裝飾前一個(gè)裝飾器,并調(diào)用其操作。在操作中,這個(gè)裝飾器首先調(diào)用前一個(gè)裝飾器的操作,然后執(zhí)行額外的操作。4. 外觀模式(Facade)外觀模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,提供了一個(gè)統(tǒng)一的接口,用來(lái)訪(fǎng)問(wèn)子系統(tǒng)中的一群接口。外觀模式定義了一個(gè)高層接口,讓子系統(tǒng)更容易使用。
以下是在C#中實(shí)現(xiàn)外觀模式的一個(gè)簡(jiǎn)單示例:
// 子系統(tǒng)Apublic class SubSystemA{ public string OperationA() { return "SubSystemA, OperationA\n"; }}// 子系統(tǒng)Bpublic class SubSystemB{ public string OperationB() { return "SubSystemB, OperationB\n"; }}// 子系統(tǒng)Cpublic class SubSystemC{ public string OperationC() { return "SubSystemC, OperationC\n"; }}// 外觀類(lèi)public class Facade{ private SubSystemA a = new SubSystemA(); private SubSystemB b = new SubSystemB(); private SubSystemC c = new SubSystemC(); public string OperationWrapper() { string result = "Facade initializes subsystems:\n"; result += a.OperationA(); result += b.OperationB(); result += c.OperationC(); return result; }}
在這個(gè)代碼中,SubSystemA
,SubSystemB
和SubSystemC
都是子系統(tǒng),每個(gè)子系統(tǒng)都有一個(gè)操作。Facade
是一個(gè)外觀類(lèi),它封裝了對(duì)子系統(tǒng)的操作,提供了一個(gè)統(tǒng)一的接口。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { Facade facade = new Facade(); Console.WriteLine(facade.OperationWrapper()); Console.ReadLine(); }}
在這個(gè)例子中,我們創(chuàng)建了一個(gè)Facade
對(duì)象,并調(diào)用了它的OperationWrapper
方法。這個(gè)方法封裝了對(duì)子系統(tǒng)的操作,使得客戶(hù)端可以不直接操作子系統(tǒng),而是通過(guò)外觀類(lèi)操作子系統(tǒng)。
執(zhí)行流程如下:
創(chuàng)建一個(gè)外觀對(duì)象。
通過(guò)調(diào)用外觀對(duì)象的方法,間接地操作子系統(tǒng)。
子系統(tǒng)的操作被封裝在外觀對(duì)象的方法中,客戶(hù)端不需要直接操作子系統(tǒng)。
5. 享元模式(Flyweight)享元模式(Flyweight Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,該模式主要用于減少創(chuàng)建對(duì)象的數(shù)量,以減少內(nèi)存占用和提高性能。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它提供了一種減少對(duì)象數(shù)量從而改善應(yīng)用所需的對(duì)象結(jié)構(gòu)的方式。
以下是在C#中實(shí)現(xiàn)享元模式的一個(gè)簡(jiǎn)單示例:
// 享元類(lèi)public class Flyweight{ private string intrinsicState; // 構(gòu)造函數(shù) public Flyweight(string intrinsicState) { this.intrinsicState = intrinsicState; } // 業(yè)務(wù)方法 public void Operation(string extrinsicState) { Console.WriteLine($"Intrinsic State = {intrinsicState}, Extrinsic State = {extrinsicState}"); }}// 享元工廠(chǎng)類(lèi)public class FlyweightFactory{ private Dictionary flyweights = new Dictionary(); public Flyweight GetFlyweight(string key) { if (!flyweights.ContainsKey(key)) { flyweights[key] = new Flyweight(key); } return flyweights[key]; } public int GetFlyweightCount() { return flyweights.Count; }}
在這個(gè)代碼中,Flyweight
是享元類(lèi),它有一個(gè)內(nèi)在狀態(tài)intrinsicState
,這個(gè)狀態(tài)是不變的。FlyweightFactory
是享元工廠(chǎng)類(lèi),它維護(hù)了一個(gè)享元對(duì)象的集合。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { FlyweightFactory factory = new FlyweightFactory(); Flyweight flyweightA = factory.GetFlyweight("A"); flyweightA.Operation("A operation"); Flyweight flyweightB = factory.GetFlyweight("B"); flyweightB.Operation("B operation"); Flyweight flyweightC = factory.GetFlyweight("A"); flyweightC.Operation("C operation"); Console.WriteLine($"Total Flyweights: {factory.GetFlyweightCount()}"); Console.ReadLine(); }}
在這個(gè)例子中,我們創(chuàng)建了一個(gè)FlyweightFactory
對(duì)象,并通過(guò)它創(chuàng)建了兩個(gè)享元對(duì)象。注意,當(dāng)我們?cè)噲D創(chuàng)建第三個(gè)享元對(duì)象時(shí),工廠(chǎng)實(shí)際上返回了第一個(gè)享元對(duì)象的引用,因?yàn)檫@兩個(gè)對(duì)象的內(nèi)在狀態(tài)是相同的。
執(zhí)行流程如下:
創(chuàng)建一個(gè)享元工廠(chǎng)對(duì)象。通過(guò)享元工廠(chǎng)獲取享元對(duì)象。如果對(duì)象已經(jīng)存在,則返回現(xiàn)有對(duì)象;否則,創(chuàng)建新對(duì)象。執(zhí)行享元對(duì)象的操作。顯示當(dāng)前享元對(duì)象的數(shù)量。6. 代理模式(Proxy)代理模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它提供了一個(gè)對(duì)象代替另一個(gè)對(duì)象來(lái)控制對(duì)它的訪(fǎng)問(wèn)。代理對(duì)象可以在客戶(hù)端和目標(biāo)對(duì)象之間起到中介的作用,并添加其他的功能。
以下是在C#中實(shí)現(xiàn)代理模式的一個(gè)簡(jiǎn)單示例:
// 抽象主題接口public interface ISubject{ void Request();}// 真實(shí)主題public class RealSubject : ISubject{ public void Request() { Console.WriteLine("RealSubject: Handling Request."); }}// 代理public class Proxy : ISubject{ private RealSubject _realSubject; public Proxy(RealSubject realSubject) { this._realSubject = realSubject; } public void Request() { if (this.CheckAccess()) { this._realSubject.Request(); this.LogAccess(); } } public bool CheckAccess() { // 檢查是否有權(quán)限訪(fǎng)問(wèn) Console.WriteLine("Proxy: Checking access prior to firing a real request."); return true; } public void LogAccess() { // 記錄請(qǐng)求 Console.WriteLine("Proxy: Logging the time of request."); }}
在這個(gè)代碼中,ISubject
是一個(gè)接口,定義了Request
方法。RealSubject
是實(shí)現(xiàn)了ISubject
接口的類(lèi),Proxy
是代理類(lèi),它也實(shí)現(xiàn)了ISubject
接口,并持有一個(gè)RealSubject
對(duì)象的引用。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { Console.WriteLine("Client: Executing the client code with a real subject:"); RealSubject realSubject = new RealSubject(); realSubject.Request(); Console.WriteLine(); Console.WriteLine("Client: Executing the same client code with a proxy:"); Proxy proxy = new Proxy(realSubject); proxy.Request(); Console.ReadLine(); }}
在這個(gè)例子中,我們首先直接調(diào)用了RealSubject
的Request
方法,然后我們通過(guò)代理調(diào)用了相同的方法。注意,在通過(guò)代理調(diào)用Request
方法時(shí),代理還執(zhí)行了其他的操作,如檢查訪(fǎng)問(wèn)權(quán)限和記錄日志。
執(zhí)行流程如下:
創(chuàng)建一個(gè)真實(shí)主題對(duì)象,并直接調(diào)用其Request
方法。創(chuàng)建一個(gè)代理對(duì)象,代理對(duì)象包含一個(gè)真實(shí)主題的引用。通過(guò)代理對(duì)象調(diào)用Request
方法。在這個(gè)方法中,代理首先檢查訪(fǎng)問(wèn)權(quán)限,然后調(diào)用真實(shí)主題的Request
方法,最后記錄日志。行為型模式: 13. 責(zé)任鏈模式(Chain of Responsibility)1. 命令模式(Command)命令模式(Command Pattern)是一種數(shù)據(jù)驅(qū)動(dòng)的設(shè)計(jì)模式,它屬于行為型模式。在命令模式中,請(qǐng)求在對(duì)象中封裝成為一個(gè)操作或行為,這些請(qǐng)求被送到調(diào)用對(duì)象,調(diào)用對(duì)象尋找可以處理該命令的合適的對(duì)象,并把命令直接送達(dá)到對(duì)應(yīng)的對(duì)象,該對(duì)象會(huì)執(zhí)行這些命令。
以下是在C#中實(shí)現(xiàn)命令模式的一個(gè)簡(jiǎn)單示例:
// 命令接口public interface ICommand{ void Execute();}// 具體命令類(lèi)public class ConcreteCommand : ICommand{ private Receiver receiver; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } public void Execute() { receiver.Action(); }}// 接收者類(lèi)public class Receiver{ public void Action() { Console.WriteLine("Receiver performs an action"); }}// 調(diào)用者或發(fā)送者類(lèi)public class Invoker{ private ICommand command; public void SetCommand(ICommand command) { this.command = command; } public void ExecuteCommand() { command.Execute(); }}
在這個(gè)代碼中,ICommand
是命令接口,定義了Execute
方法。ConcreteCommand
是具體的命令類(lèi),它實(shí)現(xiàn)了ICommand
接口,并持有一個(gè)Receiver
對(duì)象的引用。Invoker
是調(diào)用者或發(fā)送者類(lèi),它持有一個(gè)ICommand
對(duì)象的引用,并可以通過(guò)SetCommand
方法設(shè)置命令,通過(guò)ExecuteCommand
方法執(zhí)行命令。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { Receiver receiver = new Receiver(); ICommand command = new ConcreteCommand(receiver); Invoker invoker = new Invoker(); invoker.SetCommand(command); invoker.ExecuteCommand(); Console.ReadLine(); }}
在這個(gè)例子中,我們創(chuàng)建了一個(gè)Receiver
對(duì)象、一個(gè)ConcreteCommand
對(duì)象和一個(gè)Invoker
對(duì)象。然后我們通過(guò)Invoker
的SetCommand
方法設(shè)置了命令,并通過(guò)ExecuteCommand
方法執(zhí)行了命令。
執(zhí)行流程如下:
創(chuàng)建一個(gè)接收者對(duì)象。創(chuàng)建一個(gè)具體命令對(duì)象,并將接收者對(duì)象傳遞給它。創(chuàng)建一個(gè)調(diào)用者或發(fā)送者對(duì)象。通過(guò)調(diào)用者對(duì)象的SetCommand
方法設(shè)置命令。通過(guò)調(diào)用者對(duì)象的ExecuteCommand
方法執(zhí)行命令。2. 解釋器模式(Interpreter)解釋器模式(Interpreter Pattern)是一種行為型設(shè)計(jì)模式,用于解決一些固定語(yǔ)法格式的需求。它定義了如何在語(yǔ)言中表示和解析語(yǔ)法。
以下是在C#中實(shí)現(xiàn)解釋器模式的一個(gè)簡(jiǎn)單示例:
// 抽象表達(dá)式public interface IExpression{ bool Interpret(string context);}// 終結(jié)符表達(dá)式public class TerminalExpression : IExpression{ private string data; public TerminalExpression(string data) { this.data = data; } public bool Interpret(string context) { if (context.Contains(data)) { return true; } return false; }}// 非終結(jié)符表達(dá)式public class OrExpression : IExpression{ private IExpression expr1 = null; private IExpression expr2 = null; public OrExpression(IExpression expr1, IExpression expr2) { this.expr1 = expr1; this.expr2 = expr2; } public bool Interpret(string context) { return expr1.Interpret(context) || expr2.Interpret(context); }}
在這個(gè)代碼中,IExpression
是抽象表達(dá)式,定義了Interpret
方法。TerminalExpression
是終結(jié)符表達(dá)式,它實(shí)現(xiàn)了IExpression
接口。OrExpression
是非終結(jié)符表達(dá)式,它也實(shí)現(xiàn)了IExpression
接口。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { IExpression isMale = GetMaleExpression(); IExpression isMarriedWoman = GetMarriedWomanExpression(); Console.WriteLine($"John is male? {isMale.Interpret("John")}"); Console.WriteLine($"Julie is a married women? {isMarriedWoman.Interpret("Married Julie")}"); Console.ReadLine(); } // 規(guī)則:Robert 和 John 是男性 public static IExpression GetMaleExpression() { IExpression robert = new TerminalExpression("Robert"); IExpression john = new TerminalExpression("John"); return new OrExpression(robert, john); } // 規(guī)則:Julie 是一個(gè)已婚的女性 public static IExpression GetMarriedWomanExpression() { IExpression julie = new TerminalExpression("Julie"); IExpression married = new TerminalExpression("Married"); return new OrExpression(julie, married); }}
在這個(gè)例子中,我們定義了兩個(gè)規(guī)則,"Robert和John是男性"和"Julie是一個(gè)已婚的女性"。我們?nèi)缓髣?chuàng)建了兩個(gè)表達(dá)式對(duì)象,分別表示這兩個(gè)規(guī)則,并使用這兩個(gè)對(duì)象來(lái)解析輸入。
執(zhí)行流程如下:
創(chuàng)建終結(jié)符表達(dá)式對(duì)象和非終結(jié)符表達(dá)式對(duì)象,用于表示規(guī)則。調(diào)用表達(dá)式對(duì)象的Interpret
方法,解析輸入的字符串。輸出解析結(jié)果。3. 迭代器模式(Iterator)迭代器模式(Iterator Pattern)是一種行為型設(shè)計(jì)模式,它提供了一種方法來(lái)訪(fǎng)問(wèn)一個(gè)對(duì)象的元素,而不需要暴露該對(duì)象的內(nèi)部表示。以下是在C#中實(shí)現(xiàn)迭代器模式的一個(gè)簡(jiǎn)單示例:
// 抽象聚合類(lèi)public interface IAggregate{ IIterator CreateIterator(); void Add(string item); int Count { get; } string this[int index] { get; set; }}// 具體聚合類(lèi)public class ConcreteAggregate : IAggregate{ private List items = new List(); public IIterator CreateIterator() { return new ConcreteIterator(this); } public int Count { get { return items.Count; } } public string this[int index] { get { return items[index]; } set { items.Insert(index, value); } } public void Add(string item) { items.Add(item); }}// 抽象迭代器public interface IIterator{ string First(); string Next(); bool IsDone { get; } string CurrentItem { get; }}// 具體迭代器public class ConcreteIterator : IIterator{ private ConcreteAggregate aggregate; private int current = 0; public ConcreteIterator(ConcreteAggregate aggregate) { this.aggregate = aggregate; } public string First() { return aggregate[0]; } public string Next() { string ret = null; if (current < aggregate.Count - 1) { ret = aggregate[++current]; } return ret; } public string CurrentItem { get { return aggregate[current]; } } public bool IsDone { get { return current >= aggregate.Count; } }}
在這個(gè)代碼中,IAggregate
是抽象聚合類(lèi),定義了CreateIterator
等方法,ConcreteAggregate
是具體聚合類(lèi),實(shí)現(xiàn)了IAggregate
接口。IIterator
是抽象迭代器,定義了First
、Next
等方法,ConcreteIterator
是具體迭代器,實(shí)現(xiàn)了IIterator
接口。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { IAggregate aggregate = new ConcreteAggregate(); aggregate.Add("Item A"); aggregate.Add("Item B"); aggregate.Add("Item C"); aggregate.Add("Item D"); IIterator iterator = aggregate.CreateIterator(); Console.WriteLine("Iterating over collection:"); string item = iterator.First(); while (item != null) { Console.WriteLine(item); item = iterator.Next(); } Console.ReadLine(); }}
在這個(gè)例子中,我們創(chuàng)建了一個(gè)ConcreteAggregate
對(duì)象,并添加了幾個(gè)元素。然后我們通過(guò)CreateIterator
方法創(chuàng)建了一個(gè)迭代器,并使用這個(gè)迭代器遍歷了集合中的所有元素。
執(zhí)行流程如下:
創(chuàng)建一個(gè)聚合對(duì)象,并添加一些元素。通過(guò)聚合對(duì)象的CreateIterator
方法創(chuàng)建一個(gè)迭代器。通過(guò)迭代器的First
方法獲取第一個(gè)元素,然后通過(guò)Next
方法獲取后續(xù)的元素,直到獲取不到元素為止。4. 中介者模式(Mediator)中介者模式是一種行為設(shè)計(jì)模式,它讓你能減少一組對(duì)象之間復(fù)雜的通信。它提供了一個(gè)中介者對(duì)象,此對(duì)象負(fù)責(zé)在組中的對(duì)象之間進(jìn)行通信,而不是這些對(duì)象直接進(jìn)行通信。
首先,讓我們定義一個(gè)中介者接口和一個(gè)具體的中介者:
// Mediator 接口聲明了與組件交互的方法。public interface IMediator{ void Notify(object sender, string ev);}// 具體 Mediators 實(shí)現(xiàn)協(xié)作行為,它負(fù)責(zé)協(xié)調(diào)多個(gè)組件。public class ConcreteMediator : IMediator{ private Component1 _component1; private Component2 _component2; public ConcreteMediator(Component1 component1, Component2 component2) { _component1 = component1; _component1.SetMediator(this); _component2 = component2; _component2.SetMediator(this); } public void Notify(object sender, string ev) { if (ev == "A") { Console.WriteLine("Mediator reacts on A and triggers following operations:"); this._component2.DoC(); } if (ev == "D") { Console.WriteLine("Mediator reacts on D and triggers following operations:"); this._component1.DoB(); this._component2.DoC(); } }}
接著,我們定義一個(gè)基礎(chǔ)組件類(lèi)和兩個(gè)具體組件:
public abstract class BaseComponent{ protected IMediator _mediator; public BaseComponent(IMediator mediator = null) { _mediator = mediator; } public void SetMediator(IMediator mediator) { this._mediator = mediator; }}// 具體 Components 實(shí)現(xiàn)各種功能。它們不依賴(lài)于其他組件。// 它們也不依賴(lài)于任何具體 Mediator 類(lèi)。public class Component1 : BaseComponent{ public void DoA() { Console.WriteLine("Component 1 does A."); this._mediator.Notify(this, "A"); } public void DoB() { Console.WriteLine("Component 1 does B."); this._mediator.Notify(this, "B"); }}public class Component2 : BaseComponent{ public void DoC() { Console.WriteLine("Component 2 does C."); this._mediator.Notify(this, "C"); } public void DoD() { Console.WriteLine("Component 2 does D."); this._mediator.Notify(this, "D"); }}
最后,我們來(lái)創(chuàng)建一個(gè)客戶(hù)端代碼:
class Program{ static void Main(string[] args) { // The client code. Component1 component1 = new Component1(); Component2 component2 = new Component2(); new ConcreteMediator(component1, component2); Console.WriteLine("Client triggers operation A."); component1.DoA(); Console.WriteLine(); Console.WriteLine("Client triggers operation D."); component2.DoD(); }}
這個(gè)示例中的各個(gè)組件通過(guò)中介者來(lái)進(jìn)行通信,而不是直接通信,這樣就可以減少組件之間的依賴(lài)性,使得它們可以更容易地被獨(dú)立修改。當(dāng)一個(gè)組件發(fā)生某個(gè)事件(例如"Component 1 does A")時(shí),它會(huì)通過(guò)中介者來(lái)通知其他組件,這樣其他組件就可以根據(jù)這個(gè)事件來(lái)做出響應(yīng)(例如"Component 2 does C")。
5. 備忘錄模式(Memento)備忘錄模式是一種行為設(shè)計(jì)模式,它能保存對(duì)象的狀態(tài),以便在后面可以恢復(fù)它。在大多數(shù)情況下,這種模式可以讓你在不破壞對(duì)象封裝的前提下,保存和恢復(fù)對(duì)象的歷史狀態(tài)。
以下是一個(gè)簡(jiǎn)單的備忘錄模式的實(shí)現(xiàn),其中有三個(gè)主要的類(lèi):Originator
(保存了一個(gè)重要的狀態(tài),這個(gè)狀態(tài)可能會(huì)隨著時(shí)間改變),Memento
(保存了Originator
的一個(gè)快照,這個(gè)快照包含了Originator
的狀態(tài)),以及Caretaker
(負(fù)責(zé)保存Memento
)。
// Originator 類(lèi)可以生成一個(gè)備忘錄,并且可以通過(guò)備忘錄恢復(fù)其狀態(tài)。public class Originator{ private string _state; public Originator(string state) { this._state = state; Console.WriteLine($"Originator: My initial state is: {_state}"); } public void DoSomething() { Console.WriteLine("Originator: I"m doing something important."); _state = GenerateRandomString(30); Console.WriteLine($"Originator: and my state has changed to: {_state}"); } private string GenerateRandomString(int length = 10) { string allowedSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; string result = string.Empty; while (length > 0) { result += allowedSymbols[new Random().Next(0, allowedSymbols.Length)]; length--; } return result; } public IMemento Save() { return new ConcreteMemento(_state); } public void Restore(IMemento memento) { _state = memento.GetState(); Console.WriteLine($"Originator: My state has changed to: {_state}"); }}// 備忘錄接口提供了獲取備忘錄和原發(fā)器狀態(tài)的方法。但在該接口中并未聲明所有的方法,一些方法只在原發(fā)器中聲明。public interface IMemento{ string GetName(); string GetState(); DateTime GetDate();}// Concrete Memento 存儲(chǔ)原發(fā)器狀態(tài),并通過(guò)原發(fā)器實(shí)現(xiàn)備份。備忘錄是不可變的,因此,沒(méi)有 set 方法。public class ConcreteMemento : IMemento{ private string _state; private DateTime _date; public ConcreteMemento(string state) { _state = state; _date = DateTime.Now; } public string GetState() { return _state; } public string GetName() { return $"{_date} / ({_state.Substring(0, 9)})..."; } public DateTime GetDate() { return _date; }}// Caretaker 不依賴(lài)于具體備忘錄類(lèi)。結(jié)果,它不會(huì)有任何訪(fǎng)問(wèn)原發(fā)器狀態(tài)的權(quán)利,它只能獲取備忘錄的元數(shù)據(jù)。public class Caretaker{ private List _mementos = new List(); private Originator _originator = null; public Caretaker(Originator originator) { this._originator = originator; } public void Backup() { Console.WriteLine("\nCaretaker: Saving Originator"s state..."); _mementos.Add(_originator.Save()); } public void Undo() { if (_mementos.Count == 0) { return; } var memento = _mementos.Last(); _mementos.Remove(memento); Console.WriteLine("Caretaker: Restoring state to: " + memento.GetName()); try { _originator.Restore(memento); } catch (Exception) { Undo(); } } public void ShowHistory() { Console.WriteLine("Caretaker: Here"s the list of mementos:"); foreach (var memento in _mementos) { Console.WriteLine(memento.GetName()); } }}// 客戶(hù)端代碼class Program{ static void Main(string[] args) { Originator originator = new Originator("Super-duper-super-puper-super."); Caretaker caretaker = new Caretaker(originator); caretaker.Backup(); originator.DoSomething(); caretaker.Backup(); originator.DoSomething(); caretaker.Backup(); originator.DoSomething(); Console.WriteLine(); caretaker.ShowHistory(); Console.WriteLine("\nClient: Now, let"s rollback!\n"); caretaker.Undo(); Console.WriteLine("\nClient: Once more!\n"); caretaker.Undo(); }}
以上的代碼中,Originator 持有一些重要的狀態(tài),并且提供了方法去保存它的狀態(tài)到一個(gè)備忘錄對(duì)象以及從備忘錄對(duì)象中恢復(fù)它的狀態(tài)。Caretaker 負(fù)責(zé)保存?zhèn)渫洠撬荒懿僮鱾渫泴?duì)象中的狀態(tài)。當(dāng)用戶(hù)執(zhí)行操作時(shí),我們先保存當(dāng)前的狀態(tài),然后執(zhí)行操作。如果用戶(hù)后來(lái)不滿(mǎn)意新的狀態(tài),他們可以方便地從舊的備忘錄中恢復(fù)狀態(tài)。
6. 觀察者模式(Observer)觀察者模式(Observer Pattern)是一種行為型設(shè)計(jì)模式,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí),依賴(lài)它的所有對(duì)象都會(huì)得到通知并被自動(dòng)更新。以下是在C#中實(shí)現(xiàn)觀察者模式的一個(gè)簡(jiǎn)單示例:
// 抽象觀察者public interface IObserver{ void Update();}// 具體觀察者public class ConcreteObserver : IObserver{ private string name; public ConcreteObserver(string name) { this.name = name; } public void Update() { Console.WriteLine($"{name} received an update!"); }}// 抽象主題public interface ISubject{ void RegisterObserver(IObserver observer); void RemoveObserver(IObserver observer); void NotifyObservers();}// 具體主題public class ConcreteSubject : ISubject{ private List observers = new List(); public void RegisterObserver(IObserver observer) { observers.Add(observer); } public void RemoveObserver(IObserver observer) { if (observers.Contains(observer)) { observers.Remove(observer); } } public void NotifyObservers() { foreach (var observer in observers) { observer.Update(); } } public void ChangeState() { // 觸發(fā)狀態(tài)變化,通知所有觀察者 NotifyObservers(); }}
在這個(gè)代碼中,IObserver
是抽象觀察者,定義了Update
方法,ConcreteObserver
是具體觀察者,實(shí)現(xiàn)了IObserver
接口。ISubject
是抽象主題,定義了RegisterObserver
、RemoveObserver
和NotifyObservers
方法,ConcreteSubject
是具體主題,實(shí)現(xiàn)了ISubject
接口。
以下是一個(gè)使用這個(gè)模式的示例:
class Program{ static void Main(string[] args) { ConcreteSubject subject = new ConcreteSubject(); subject.RegisterObserver(new ConcreteObserver("Observer 1")); subject.RegisterObserver(new ConcreteObserver("Observer 2")); subject.RegisterObserver(new ConcreteObserver("Observer 3")); subject.ChangeState(); Console.ReadLine(); }}
在這個(gè)例子中,我們創(chuàng)建了一個(gè)ConcreteSubject
對(duì)象,并注冊(cè)了三個(gè)觀察者。然后我們通過(guò)ChangeState
方法改變了主題的狀態(tài),這會(huì)觸發(fā)主題通知所有觀察者。
執(zhí)行流程如下:
創(chuàng)建一個(gè)具體主題對(duì)象。創(chuàng)建幾個(gè)具體觀察者對(duì)象,并通過(guò)主題的RegisterObserver
方法將這些觀察者注冊(cè)到主題中。通過(guò)主題的ChangeState
方法改變主題的狀態(tài),這會(huì)觸發(fā)主題通知所有觀察者。7. 狀態(tài)模式(State)狀態(tài)模式在面向?qū)ο缶幊讨?,是一種允許對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變其行為的設(shè)計(jì)模式。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。在狀態(tài)模式中,我們創(chuàng)建對(duì)象表示各種狀態(tài),以及一個(gè)行為隨狀態(tài)改變而改變的上下文對(duì)象。
以下是一個(gè)狀態(tài)模式的示例。這個(gè)示例中,我們將創(chuàng)建一個(gè)銀行賬戶(hù),它有兩個(gè)狀態(tài):正常狀態(tài)(NormalState)和透支狀態(tài)(OverdrawnState)。當(dāng)用戶(hù)執(zhí)行操作(存款和取款)時(shí),賬戶(hù)狀態(tài)將相應(yīng)地進(jìn)行更改。
首先,我們定義一個(gè)表示狀態(tài)的接口:
public interface IAccountState{ void Deposit(Action addToBalance); void Withdraw(Action subtractFromBalance); void ComputeInterest();}
然后,我們創(chuàng)建兩個(gè)表示具體狀態(tài)的類(lèi):
public class NormalState : IAccountState{ public void Deposit(Action addToBalance) { addToBalance(); Console.WriteLine("Deposit in NormalState"); } public void Withdraw(Action subtractFromBalance) { subtractFromBalance(); Console.WriteLine("Withdraw in NormalState"); } public void ComputeInterest() { Console.WriteLine("Interest computed in NormalState"); }}public class OverdrawnState : IAccountState{ public void Deposit(Action addToBalance) { addToBalance(); Console.WriteLine("Deposit in OverdrawnState"); } public void Withdraw(Action subtractFromBalance) { Console.WriteLine("No withdraw in OverdrawnState"); } public void ComputeInterest() { Console.WriteLine("Interest and fees computed in OverdrawnState"); }}
然后,我們創(chuàng)建一個(gè)Context類(lèi),它使用這些狀態(tài)來(lái)執(zhí)行其任務(wù):
public class BankAccount{ private IAccountState _state; private double _balance; public BankAccount(IAccountState state) { _state = state; _balance = 0; } public void Deposit(double amount) { _state.Deposit(() => _balance += amount); StateChangeCheck(); } public void Withdraw(double amount) { _state.Withdraw(() => _balance -= amount); StateChangeCheck(); } public void ComputeInterest() { _state.ComputeInterest(); } private void StateChangeCheck() { if (_balance < 0.0) _state = new OverdrawnState(); else _state = new NormalState(); }}
現(xiàn)在,你可以創(chuàng)建一個(gè)實(shí)例并運(yùn)行一個(gè)Demo來(lái)測(cè)試這個(gè)狀態(tài)模式的代碼:
public class Program{ public static void Main(string[] args) { var account = new BankAccount(new NormalState()); account.Deposit(1000); // Deposit in NormalState account.Withdraw(2000); // Withdraw in NormalState; No withdraw in OverdrawnState account.Deposit(100); // Deposit in OverdrawnState account.ComputeInterest(); // Interest and fees computed in OverdrawnState Console.ReadKey(); }}
這個(gè)程序首先在正常狀態(tài)下進(jìn)行存款操作,然后嘗試進(jìn)行取款操作。由于取款金額超過(guò)賬戶(hù)余額,所以賬戶(hù)進(jìn)入透支狀態(tài),并阻止進(jìn)一步的取款操作。但存款仍然被允許,以使賬戶(hù)回歸到正常狀態(tài)。計(jì)算利息的行為也根據(jù)賬戶(hù)的狀態(tài)變化而變化。
8. 策略模式(Strategy)策略模式定義了一系列的算法,并將每一個(gè)算法封裝起來(lái),使得它們可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶(hù)而獨(dú)立變化。
以下是一個(gè)簡(jiǎn)單的策略模式的C#實(shí)現(xiàn)。這個(gè)例子中,我們將創(chuàng)建一個(gè)排序策略,比如快速排序和冒泡排序,它們實(shí)現(xiàn)同一個(gè)接口,然后創(chuàng)建一個(gè)Context類(lèi),它使用這些策略來(lái)執(zhí)行排序操作。
首先,我們定義一個(gè)表示排序策略的接口:
public interface ISortStrategy{ void Sort(List list);}
然后,我們創(chuàng)建兩個(gè)表示具體策略的類(lèi):
public class QuickSort : ISortStrategy{ public void Sort(List list) { list.Sort(); // Quick sort is in-place but here we are using built-in method Console.WriteLine("QuickSorted list "); }}public class BubbleSort : ISortStrategy{ public void Sort(List list) { int n = list.Count; for (int i = 0; i < n - 1; i++) for (int j = 0; j < n - i - 1; j++) if (list[j] > list[j + 1]) { // swap temp and list[i] int temp = list[j]; list[j] = list[j + 1]; list[j + 1] = temp; } Console.WriteLine("BubbleSorted list "); }}
然后,我們創(chuàng)建一個(gè)Context類(lèi),它使用這些策略來(lái)執(zhí)行其任務(wù):
public class SortedList{ private List _list = new List(); private ISortStrategy _sortstrategy; public void SetSortStrategy(ISortStrategy sortstrategy) { this._sortstrategy = sortstrategy; } public void Add(int num) { _list.Add(num); } public void Sort() { _sortstrategy.Sort(_list); // Print sorted list foreach (int num in _list) { Console.Write(num + " "); } Console.WriteLine(); }}
現(xiàn)在,你可以創(chuàng)建一個(gè)實(shí)例并運(yùn)行一個(gè)Demo來(lái)測(cè)試這個(gè)策略模式的代碼:
public class Program{ public static void Main(string[] args) { SortedList sortedList = new SortedList(); sortedList.Add(1); sortedList.Add(5); sortedList.Add(3); sortedList.Add(4); sortedList.Add(2); sortedList.SetSortStrategy(new QuickSort()); sortedList.Sort(); // Output: QuickSorted list 1 2 3 4 5 sortedList.SetSortStrategy(new BubbleSort()); sortedList.Sort(); // Output: BubbleSorted list 1 2 3 4 5 Console.ReadKey(); }}
這個(gè)程序首先創(chuàng)建了一個(gè)未排序的列表,然后它首先使用快速排序策略進(jìn)行排序,接著又使用冒泡排序策略進(jìn)行排序。
9. 模板方法模式(Template Method)模板方法模式定義了一個(gè)操作中算法的骨架,將這些步驟延遲到子類(lèi)中。模板方法使得子類(lèi)可以不改變算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
以下是一個(gè)模板方法模式的示例。這個(gè)示例中,我們將創(chuàng)建一個(gè)烹飪食物的過(guò)程,這個(gè)過(guò)程有一些固定的步驟(例如準(zhǔn)備材料,清理),但是具體的烹飪步驟則取決于具體的食物。
首先,我們定義一個(gè)抽象的模板類(lèi):
public abstract class CookingProcedure{ // The "Template method" public void PrepareDish() { PrepareIngredients(); Cook(); CleanUp(); } public void PrepareIngredients() { Console.WriteLine("Preparing the ingredients..."); } // These methods will be overridden by subclasses public abstract void Cook(); public void CleanUp() { Console.WriteLine("Cleaning up..."); }}
然后,我們創(chuàng)建兩個(gè)具體的子類(lèi),它們分別實(shí)現(xiàn)了具體的烹飪步驟:
public class CookPasta : CookingProcedure{ public override void Cook() { Console.WriteLine("Cooking pasta..."); }}public class BakeCake : CookingProcedure{ public override void Cook() { Console.WriteLine("Baking cake..."); }}
現(xiàn)在,你可以創(chuàng)建一個(gè)實(shí)例并運(yùn)行一個(gè)Demo來(lái)測(cè)試這個(gè)模板方法模式的代碼:
public class Program{ public static void Main(string[] args) { CookingProcedure cookingProcedure = new CookPasta(); cookingProcedure.PrepareDish(); Console.WriteLine(); cookingProcedure = new BakeCake(); cookingProcedure.PrepareDish(); Console.ReadKey(); }}
在這個(gè)程序中,我們首先創(chuàng)建了一個(gè)CookPasta
對(duì)象,然后調(diào)用其PrepareDish
方法。然后,我們創(chuàng)建了一個(gè)BakeCake
對(duì)象,再次調(diào)用其PrepareDish
方法。這兩個(gè)對(duì)象雖然具有不同的Cook
方法,但是它們的PrepareDish
方法的結(jié)構(gòu)(即算法的骨架)是相同的。
訪(fǎng)問(wèn)者模式(Visitor Pattern)是一種將算法與對(duì)象結(jié)構(gòu)分離的軟件設(shè)計(jì)模式。這種模式的基本想法就是通過(guò)所謂的"訪(fǎng)問(wèn)者"來(lái)改變?cè)氐牟僮鳌_@樣一來(lái),元素的類(lèi)可以用于表示元素結(jié)構(gòu),而具體的操作則可以在訪(fǎng)問(wèn)者類(lèi)中定義。
以下是一個(gè)使用C#實(shí)現(xiàn)的訪(fǎng)問(wèn)者模式示例,包括了詳細(xì)的注釋和執(zhí)行流程。
這個(gè)示例中有三個(gè)主要部分:訪(fǎng)問(wèn)者(IVisitor)、可訪(fǎng)問(wèn)元素(IElement)和元素結(jié)構(gòu)(ObjectStructure)。同時(shí)有具體訪(fǎng)問(wèn)者(ConcreteVisitor)和具體元素(ConcreteElement)。
// 訪(fǎng)問(wèn)者接口public interface IVisitor{ void VisitConcreteElementA(ConcreteElementA concreteElementA); void VisitConcreteElementB(ConcreteElementB concreteElementB);}// 具體訪(fǎng)問(wèn)者Apublic class ConcreteVisitorA : IVisitor{ public void VisitConcreteElementA(ConcreteElementA concreteElementA) { Console.WriteLine($"{concreteElementA.GetType().Name} is being visited by {this.GetType().Name}"); } public void VisitConcreteElementB(ConcreteElementB concreteElementB) { Console.WriteLine($"{concreteElementB.GetType().Name} is being visited by {this.GetType().Name}"); }}// 具體訪(fǎng)問(wèn)者Bpublic class ConcreteVisitorB : IVisitor{ public void VisitConcreteElementA(ConcreteElementA concreteElementA) { Console.WriteLine($"{concreteElementA.GetType().Name} is being visited by {this.GetType().Name}"); } public void VisitConcreteElementB(ConcreteElementB concreteElementB) { Console.WriteLine($"{concreteElementB.GetType().Name} is being visited by {this.GetType().Name}"); }}// 元素接口public interface IElement{ void Accept(IVisitor visitor);}// 具體元素Apublic class ConcreteElementA : IElement{ public void Accept(IVisitor visitor) { visitor.VisitConcreteElementA(this); }}// 具體元素Bpublic class ConcreteElementB : IElement{ public void Accept(IVisitor visitor) { visitor.VisitConcreteElementB(this); }}// 對(duì)象結(jié)構(gòu)public class ObjectStructure{ private List _elements = new List(); public void Attach(IElement element) { _elements.Add(element); } public void Detach(IElement element) { _elements.Remove(element); } public void Accept(IVisitor visitor) { foreach (var element in _elements) { element.Accept(visitor); } }}
執(zhí)行流程如下:
創(chuàng)建具體元素ConcreteElementA和ConcreteElementB的實(shí)例。創(chuàng)建對(duì)象結(jié)構(gòu)ObjectStructure的實(shí)例,并將步驟1創(chuàng)建的具體元素添加到對(duì)象結(jié)構(gòu)中。創(chuàng)建具體訪(fǎng)問(wèn)者ConcreteVisitorA和ConcreteVisitorB的實(shí)例。調(diào)用對(duì)象結(jié)構(gòu)的Accept方法,傳入步驟3創(chuàng)建的具體訪(fǎng)問(wèn)者,使具體訪(fǎng)問(wèn)者訪(fǎng)問(wèn)對(duì)象結(jié)構(gòu)中的所有元素。以下是一個(gè)使用上述代碼的示例:
public class Program{ public static void Main() { ObjectStructure objectStructure = new ObjectStructure(); objectStructure.Attach(new ConcreteElementA()); objectStructure.Attach(new ConcreteElementB()); ConcreteVisitorA visitorA = new ConcreteVisitorA(); ConcreteVisitorB visitorB = new ConcreteVisitorB(); objectStructure.Accept(visitorA); objectStructure.Accept(visitorB); Console.ReadKey(); }}
這個(gè)程序會(huì)打印出訪(fǎng)問(wèn)者A和訪(fǎng)問(wèn)者B分別訪(fǎng)問(wèn)具體元素A和具體元素B的信息。
技術(shù)交流.NET Core交流群:737776595
來(lái)自token的分享
標(biāo)簽:
推薦
-
使用c#實(shí)現(xiàn)23種常見(jiàn)的設(shè)計(jì)模式|全球新消息
使用c 實(shí)現(xiàn)23種常見(jiàn)的設(shè)計(jì)模式設(shè)計(jì)模式通常分為三個(gè)主要類(lèi)別:-創(chuàng)建型
來(lái)源: -
-
中欣氟材:3萬(wàn)噸電子級(jí)氫氟酸項(xiàng)目預(yù)計(jì)7月完成設(shè)備安裝并調(diào)試_每日焦點(diǎn)
中欣氟材6月5日在互動(dòng)平臺(tái)表示,目前公司3萬(wàn)噸電子級(jí)氫氟酸項(xiàng)目正在設(shè)
來(lái)源: -
“數(shù)字南京”即將登陸深圳文博會(huì) “長(zhǎng)江明珠”帶來(lái)文化新體驗(yàn)|天天新消息
光明網(wǎng)訊(記者趙艷艷)本屆深圳文博會(huì)上,南京將以“數(shù)字南京長(zhǎng)江明珠
來(lái)源: -
順利交付!神十五航天員帶回了20多公斤實(shí)驗(yàn)樣品_焦點(diǎn)速看
2023年6月4日,中國(guó)空間站第四批空間科學(xué)實(shí)驗(yàn)樣品隨神舟十五號(hào)飛船返回
來(lái)源: -
使用c#實(shí)現(xiàn)23種常見(jiàn)的設(shè)計(jì)模式|全球新消息
使用c 實(shí)現(xiàn)23種常見(jiàn)的設(shè)計(jì)模式設(shè)計(jì)模式通常分為三個(gè)主要類(lèi)別:-創(chuàng)建型
來(lái)源: -
-
-
暢通武鄂黃黃都市圈大動(dòng)脈 “黃鄂黃”物流結(jié)鏈成網(wǎng) 全球要聞
近日,3輛滿(mǎn)載3600余件聚丙烯顆粒的貨車(chē)駛?cè)牒苯煌稘h口北國(guó)際多式聯(lián)
來(lái)源: -
-
全球報(bào)道:收評(píng):指數(shù)走勢(shì)分化創(chuàng)指跌1.39% 景點(diǎn)及旅游漲幅居前
收評(píng):指數(shù)走勢(shì)分化創(chuàng)指跌1 39%景點(diǎn)及旅游漲幅居前---中國(guó)經(jīng)濟(jì)網(wǎng)北京6
來(lái)源: -
-
環(huán)球播報(bào):中經(jīng)資料:巴基斯坦證券市場(chǎng)一周回顧(2023.5.29-6.2)
中經(jīng)資料:巴基斯坦證券市場(chǎng)一周回顧(2023 5 29-6 2)---1 巴基斯坦國(guó)家
來(lái)源: -
當(dāng)前視點(diǎn)!兩部門(mén):開(kāi)展“春雨潤(rùn)苗”專(zhuān)項(xiàng)行動(dòng) 助力小微經(jīng)營(yíng)主體發(fā)展
兩部門(mén):開(kāi)展“春雨潤(rùn)苗”專(zhuān)項(xiàng)行動(dòng)助力小微經(jīng)營(yíng)主體發(fā)展---人民網(wǎng)北京6
來(lái)源: -
全球最資訊丨快手電商618大促前三天訂單量同比增長(zhǎng)超70%
DoNews6月5日消息,近日,快手電商發(fā)布618戰(zhàn)報(bào)。數(shù)據(jù)顯示,6月1日-6月3
來(lái)源: -
全國(guó)“三夏”大規(guī)模小麥機(jī)收全面展開(kāi)|每日焦點(diǎn)
全國(guó)“三夏”大規(guī)模小麥機(jī)收全面展開(kāi)---記者從農(nóng)業(yè)農(nóng)村部獲悉,截至6月
來(lái)源: -
-
-
財(cái)政部相關(guān)負(fù)責(zé)人:整體來(lái)看我國(guó)財(cái)政狀況健康、安全,為應(yīng)對(duì)風(fēng)險(xiǎn)挑戰(zhàn)留出足夠空間
今年以來(lái),伴隨經(jīng)濟(jì)穩(wěn)健復(fù)蘇,財(cái)政收入增幅回穩(wěn)向上,但也有一些地方政
來(lái)源: -
-
游久電競(jìng)因勞動(dòng)糾紛被限消_環(huán)球快看
天眼查App顯示,近日,游久電競(jìng)關(guān)聯(lián)公司游久時(shí)代(北京)科技有限公
來(lái)源: -
“21世紀(jì)貿(mào)易倡議”首批協(xié)議簽署 臺(tái)灣勞動(dòng)黨指民進(jìn)黨“開(kāi)門(mén)揖盜”
中新社臺(tái)北6月5日電針對(duì)美國(guó)與中國(guó)臺(tái)灣地區(qū)近日簽署“21世紀(jì)貿(mào)易倡議”
來(lái)源: -
北通阿修羅2刷機(jī)(北通阿修羅2pro恢復(fù)出廠(chǎng)設(shè)置)
每日小編都會(huì)為大家?guī)?lái)一些知識(shí)類(lèi)的文章,那么為大家?guī)?lái)的是北通阿修
來(lái)源: -
-
5月份中信理財(cái)博贏私享價(jià)值龍頭股指2號(hào)下跌6.58% 要聞速遞
5月份中信理財(cái)博贏私享價(jià)值龍頭股指2號(hào)下跌6 58%---中國(guó)經(jīng)濟(jì)網(wǎng)北京6月5
來(lái)源: -
半藏森林克隆人暫下線(xiàn) 此前小冰公司推出“GPT克隆人計(jì)劃”|環(huán)球熱門(mén)
近日有網(wǎng)友發(fā)現(xiàn),虛擬人休閑娛樂(lè)平臺(tái)XEva下架了網(wǎng)紅“半藏森林”等AI克
來(lái)源: -
用數(shù)字化技術(shù)保護(hù)蒼山洱海,「智慧林草」讓大理首次實(shí)現(xiàn)防火期零火災(zāi)的階段性突破|最前線(xiàn)|今日熱文
文 | 呂雅寧 編輯 | 蘇建勛“下關(guān)風(fēng),上關(guān)花,蒼山雪,洱海月
來(lái)源: -
5月份東亞聯(lián)豐中國(guó)鳳凰基金下跌9.94%
5月份東亞聯(lián)豐中國(guó)鳳凰基金下跌9 94%---中國(guó)經(jīng)濟(jì)網(wǎng)北京6月5日訊根據(jù)同
來(lái)源: -
-
-
數(shù)字技術(shù)發(fā)力 蒼山洱海生態(tài)保護(hù)筑起“智能屏障” 觀察
數(shù)字技術(shù)發(fā)力蒼山洱海生態(tài)保護(hù)筑起“智能屏障”---今年年初,一部在云
來(lái)源: -
世界最資訊丨聚焦新形勢(shì)新要求 多方共話(huà)互聯(lián)網(wǎng)發(fā)展新篇章
聚焦新形勢(shì)新要求多方共話(huà)互聯(lián)網(wǎng)發(fā)展新篇章---人民網(wǎng)北京6月5日電(記
來(lái)源: -
-
中欣氟材:3萬(wàn)噸電子級(jí)氫氟酸項(xiàng)目預(yù)計(jì)7月完成設(shè)備安裝并調(diào)試_每日焦點(diǎn)
中欣氟材6月5日在互動(dòng)平臺(tái)表示,目前公司3萬(wàn)噸電子級(jí)氫氟酸項(xiàng)目正在設(shè)
來(lái)源: -
紅旗新能源最新寵粉,E001首批盲訂車(chē)主踏上“溯源之旅”
自紅旗E001在上海車(chē)展正式亮相后,這款基于紅旗新能源全新設(shè)計(jì)理念和電動(dòng)平臺(tái)打造的豪華智能純電轎車(chē)已...
來(lái)源: -
-
世界熱資訊!富士康旗下公司經(jīng)營(yíng)異常 富士康精密組件深圳公司經(jīng)營(yíng)異常
天眼查App顯示,近日,富士康精密組件(深圳)有限公司因通過(guò)登記的
來(lái)源: -
王興實(shí)控優(yōu)付科技公司注銷(xiāo) 廈門(mén)優(yōu)付科技公司注銷(xiāo)_天天報(bào)道
天眼查App顯示,近日,廈門(mén)優(yōu)付科技有限公司發(fā)生工商變更,經(jīng)營(yíng)狀態(tài)
來(lái)源: -
-
-
熱點(diǎn)聚焦:征信出問(wèn)題急需用錢(qián)怎么辦?分享六個(gè)靠譜的方案
征信出問(wèn)題后,基本上很難借到錢(qián)。那么,征信出問(wèn)題急需用錢(qián)怎么辦?小
來(lái)源: -
win7如何徹底清理c盤(pán)?win7屏幕休眠時(shí)間怎么調(diào)?
win7如何徹底清理c盤(pán)?1、鼠標(biāo)雙擊計(jì)算機(jī)進(jìn)入頁(yè)面,選中C盤(pán),右鍵單擊它。2、選擇屬性,在常規(guī)選項(xiàng)欄中...
來(lái)源: -
電腦網(wǎng)頁(yè)打不開(kāi)怎么回事?電腦網(wǎng)頁(yè)怎么清理緩存?
電腦網(wǎng)頁(yè)打不開(kāi)怎么回事?1、首先打開(kāi)電腦,點(diǎn)擊電腦左下角的開(kāi)始菜單。2、在彈出的界面中找到windows系...
來(lái)源: -
電腦藍(lán)屏按什么鍵恢復(fù)?電腦藍(lán)屏的時(shí)候怎么重啟?
電腦藍(lán)屏按什么鍵恢復(fù)?第一步:電腦藍(lán)屏后將電腦強(qiáng)制關(guān)機(jī),重新打開(kāi)電腦,在開(kāi)機(jī)時(shí)候不斷按F8進(jìn)入,選...
來(lái)源: -
手機(jī)照片怎么傳到電腦?手機(jī)照片怎么導(dǎo)入電腦?
手機(jī)照片怎么傳到電腦?一、iCloud備份與查看在蘋(píng)果手機(jī)上打開(kāi)設(shè)置,輸入自己的Apple ID進(jìn)入后點(diǎn)擊iClo...
來(lái)源: -
筆記本電腦怎么截圖?筆記本電腦黑屏卻開(kāi)著機(jī)怎么辦?
筆記本電腦怎么截圖?方法一:使用PrScr這個(gè)鍵截屏,獲得的是整個(gè)屏幕的圖片。方法二:Alt+PrScrn這個(gè)組...
來(lái)源: -
微信聊天記錄怎么恢復(fù)?微信聊天記錄刪了能調(diào)出來(lái)嗎?
微信聊天記錄怎么恢復(fù)?1、通過(guò)微信自帶修復(fù)工具來(lái)恢復(fù)。首先打開(kāi)微信app,依次點(diǎn)擊我-設(shè)置-幫助與反饋...
來(lái)源: -
明日之后地下城在哪里?明日之后地下城的寶箱怎么開(kāi)?
明日之后地下城在哪里?1、地下城在半感染者大本營(yíng),也就是在快樂(lè)101的下方,大家直接前往找到即可,很...
來(lái)源: -
環(huán)球簡(jiǎn)訊:司馬懿明明識(shí)破了空城計(jì),為何還要撤兵?臨終前說(shuō)出了原因
司馬懿確實(shí)不負(fù)眾望,真的在回來(lái)之后牽制住了諸葛亮的軍隊(duì),諸葛亮也完
來(lái)源: -
路由器怎么恢復(fù)出廠(chǎng)設(shè)置?路由器紅燈一直亮什么原因?
路由器怎么恢復(fù)出廠(chǎng)設(shè)置?方法一:直接按路由器上的reset鍵,reset鍵一般位于路由器的后面一個(gè)凹進(jìn)的按...
來(lái)源: -
電腦死機(jī)了怎么辦?電腦死機(jī)是什么原因造成的?
電腦死機(jī)了怎么辦?1、長(zhǎng)按關(guān)機(jī)鍵,不要松手。在些過(guò)程中一定不要松開(kāi)手,一般5、6秒后電腦會(huì)關(guān)機(jī),這時(shí)...
來(lái)源: -
電腦怎么設(shè)置定時(shí)關(guān)機(jī)?電腦開(kāi)機(jī)密碼忘了怎么解除?
電腦怎么設(shè)置定時(shí)關(guān)機(jī)?電腦設(shè)置定時(shí)關(guān)機(jī)一般可以借助cmd指令完成操作,具體操作步驟如下:1、打開(kāi)電腦...
來(lái)源: -
“數(shù)字南京”即將登陸深圳文博會(huì) “長(zhǎng)江明珠”帶來(lái)文化新體驗(yàn)|天天新消息
光明網(wǎng)訊(記者趙艷艷)本屆深圳文博會(huì)上,南京將以“數(shù)字南京長(zhǎng)江明珠
來(lái)源: -
顯示器分辨率怎么調(diào)?顯示器分辨率不能調(diào)怎么回事?
顯示器分辨率怎么調(diào)?1、打開(kāi)桌面,在任意空白位置,鼠標(biāo)右擊,選擇顯示設(shè)置操作界面。2、在顯示設(shè)置界...
來(lái)源: -
如何調(diào)節(jié)電腦屏幕亮度?電腦屏幕保護(hù)怎么取消?
如何調(diào)節(jié)電腦屏幕亮度1、鼠標(biāo)放在桌面電源圖標(biāo)上方,右擊鼠標(biāo),選擇Windows移動(dòng)中心。2、在彈出的對(duì)話(huà)框...
來(lái)源:
財(cái)富更多》
-
全國(guó)“三夏”大規(guī)模小麥機(jī)收全面展開(kāi)|每日焦點(diǎn)
全國(guó)“三夏”大規(guī)模小麥機(jī)收全面展開(kāi)---...
-
專(zhuān)家:我國(guó)胃癌診療水平穩(wěn)步提升
專(zhuān)家:我國(guó)胃癌診療水平穩(wěn)步提升---近日...
-
當(dāng)前視點(diǎn)!兩部門(mén):開(kāi)展“春雨潤(rùn)苗”專(zhuān)項(xiàng)行動(dòng) 助力小微經(jīng)營(yíng)主體發(fā)展
兩部門(mén):開(kāi)展“春雨潤(rùn)苗”專(zhuān)項(xiàng)行動(dòng)助力...
-
全球報(bào)道:收評(píng):指數(shù)走勢(shì)分化創(chuàng)指跌1.39% 景點(diǎn)及旅游漲幅居前
收評(píng):指數(shù)走勢(shì)分化創(chuàng)指跌1 39%景點(diǎn)及...
-
環(huán)球播報(bào):中經(jīng)資料:巴基斯坦證券市場(chǎng)一周回顧(2023.5.29-6.2)
中經(jīng)資料:巴基斯坦證券市場(chǎng)一周回顧(20...
動(dòng)態(tài)更多》
-
漲停雷達(dá):半導(dǎo)體...
-
今日精選:攜程集...
-
香腸太陽(yáng)曬干好還...
-
寧德時(shí)代回應(yīng)供貨...
-
雞蛋便宜了!未來(lái)...
-
每日視訊:重啟天...
熱點(diǎn)
- realme10系列正式宣布 采用雙曲面屏正面頂部居中挖孔
- 五菱全新微型電動(dòng)車(chē)內(nèi)飾官圖發(fā)布 座椅采用星際形打孔工藝
- 努比亞Z40星空典藏版正式開(kāi)售 采用微米級(jí)油畫(huà)筆觸紋理技術(shù)
- iQOO11系列正式官宣 首批搭載驍龍8Gen2機(jī)型之一
- 海信34英寸帶魚(yú)屏顯示器發(fā)布 支持165Hz刷新率
- OPPO明年將商用240W超級(jí)閃充 新一代電芯支持更高倍率充電
- 第一款A(yù)ndroid手機(jī)渲染圖曝光 橫向滑蓋設(shè)計(jì)和全尺寸鍵盤(pán)
- 吉利首款純電皮卡11月9日上市 車(chē)輛續(xù)航里程超過(guò)610公里
- 努比亞Z40SPro星空典藏版正式公布 堪稱(chēng)窄邊框天花板
- vivo無(wú)線(xiàn)運(yùn)動(dòng)耳機(jī)2今日正式上市 首銷(xiāo)只要119元
- 最高檢:截至2022年底全國(guó)共辦理生態(tài)環(huán)境和資源保護(hù)公益訴訟案件40余萬(wàn)件
- 電腦屏保時(shí)間怎么設(shè)置?電腦屏保后無(wú)法喚醒怎么辦?
- 筆記本屏幕亮度怎么調(diào)?筆記本屏幕的灰塵怎么清理?
- 志愿星光點(diǎn)亮社區(qū)“微治理”-焦點(diǎn)速遞
- 電腦防火墻在哪里設(shè)置?電腦防火墻怎么全部關(guān)閉?
- 電腦護(hù)眼模式怎么設(shè)置?電腦護(hù)眼模式真的護(hù)眼嗎?
- 瑞幸開(kāi)出第一萬(wàn)家店,咖啡殺到9.9元時(shí)代
- 電腦開(kāi)機(jī)密碼怎么取消?電腦開(kāi)機(jī)密碼鎖住了怎么解鎖?
- windows7一鍵還原在哪?windows7的設(shè)置在哪里找?
- 錦華新材掛牌新三板
- 無(wú)線(xiàn)路由器怎么連接?無(wú)線(xiàn)路由器怎么連接無(wú)線(xiàn)網(wǎng)絡(luò)?
- 藍(lán)牙耳機(jī)怎么連接電腦?藍(lán)牙耳機(jī)充不進(jìn)去電怎么辦?
- 谷歌推設(shè)計(jì)神器“StyleDrop”,給一張圖就能復(fù)刻作品風(fēng)格-天天訊息
- 電腦設(shè)備管理器在哪?電腦設(shè)備管理器顯卡在哪兒?
- 多地對(duì)網(wǎng)約車(chē)按下“暫停鍵”|世界最資訊
- 香腸太陽(yáng)曬干好還是烘干好_香腸是太陽(yáng)曬干好還是陰干好_全球最新
- 手機(jī)第一次充電要充多久?手機(jī)充電突然變慢是怎么回事?
- 北美票房:《蜘蛛俠:縱橫宇宙》登頂周末票房,《小美人魚(yú)》《柜魔》分居二三-當(dāng)前觀點(diǎn)
- 電腦垃圾怎么清理?電腦垃圾多了怎么清理電腦?
- 比亞迪海洋網(wǎng)車(chē)型5月銷(xiāo)量達(dá)102572輛 世界熱訊
- 2023年“全國(guó)科技工作者日”法律服務(wù)系列活動(dòng)啟動(dòng)
- 蘋(píng)果怎么換自定義圖標(biāo)?蘋(píng)果手機(jī)突然黑屏打不開(kāi)怎么辦?
- 寧德時(shí)代回應(yīng)供貨變動(dòng)傳聞:與客戶(hù)戰(zhàn)略合作關(guān)系沒(méi)有發(fā)生變化 要聞
- 蘋(píng)果電腦沒(méi)聲音按哪個(gè)鍵恢復(fù)?蘋(píng)果電腦怎么切換系統(tǒng)?
- 香腸派對(duì)怎么添加好友?香腸派對(duì)的糖果怎么免費(fèi)獲得?
- 抖音為什么要出極速版?抖音極速版和抖音有什么區(qū)別?
- 小雅智能音箱怎么使用?小雅智能音箱怎么連接手機(jī)?
- 蘋(píng)果手機(jī)下載軟件密碼忘了怎么辦?蘋(píng)果手機(jī)軟件更新不了怎么辦?
- 當(dāng)前資訊!在家也能復(fù)刻的廣式腸粉,秘訣全在這個(gè)洲星腸粉粉
- 耳機(jī)插電腦上沒(méi)聲音怎么設(shè)置?耳機(jī)沒(méi)有聲音是怎么回事?
- 黎明覺(jué)醒河豚怎么釣?黎明覺(jué)醒的安全繩怎么放?
- 蘋(píng)果11快充傷電池嗎?蘋(píng)果11快充需要多長(zhǎng)時(shí)間?
- 陳喬恩游日本,在大阪機(jī)場(chǎng)和老公Alan會(huì)合撒嬌,又親又抱甜如初戀-每日頭條
- 手提電腦開(kāi)不了機(jī)怎么辦?筆記本電腦開(kāi)機(jī)進(jìn)不了系統(tǒng)怎么辦?
- 電腦管家有必要裝嗎?電腦管家是電腦自帶的嗎?
- qq音樂(lè)一起聽(tīng)歌怎么用?qq音樂(lè)會(huì)員怎么取消自動(dòng)續(xù)費(fèi)?
- 平板怎么清理內(nèi)存垃圾?平板電腦的操作系統(tǒng)有哪些?
- qq聊天記錄怎么發(fā)給別人?qq聊天記錄的視頻在哪個(gè)文件夾?
- 順利交付!神十五航天員帶回了20多公斤實(shí)驗(yàn)樣品_焦點(diǎn)速看
- 鍵盤(pán)沒(méi)有反應(yīng)是怎么回事?電腦鍵盤(pán)失靈怎么解決?
- 朋友圈內(nèi)容太多怎么刪除?微信朋友圈可以看訪(fǎng)客記錄嗎?
- 阿里元境總經(jīng)理王矛:AI加持,元宇宙將為內(nèi)容創(chuàng)作降本提效 | 最前線(xiàn)-當(dāng)前關(guān)注
- 電話(huà)加入黑名單后還能收到信息嗎?電話(huà)黑名單發(fā)信息能收到嗎?
- 【熱聞】西門(mén)子醫(yī)療在德國(guó)福希海姆建設(shè)新工廠(chǎng),預(yù)計(jì)創(chuàng)造100個(gè)工作崗位
- 每日焦點(diǎn)!午評(píng):創(chuàng)業(yè)板指跌1.48% 景點(diǎn)及旅游、傳媒板塊活躍
- 筆記本鍵帽可以扣下來(lái)嗎?筆記本鍵帽能直接掰下來(lái)嗎?
- 未來(lái)十天西南地區(qū)東部等地多降雨 華南地區(qū)高溫天氣將緩解
- 北??党蛇~芮倍獲準(zhǔn)上市,治療ALGS膽汁淤積性瘙癢
- 陜西扶風(fēng):“云端”綻放就業(yè)夢(mèng)-每日時(shí)訊
- 打游戲用什么軸的機(jī)械鍵盤(pán)?機(jī)械鍵盤(pán)按鍵失靈怎么修?
- 快手家居數(shù)據(jù)行業(yè)迎618爆發(fā) 前三天GMV同比去年增長(zhǎng)超139% 天天熱文
- 騰訊視頻可以?huà)叽a登錄嗎?騰訊視頻可以登錄幾個(gè)設(shè)備?
- 杭州部分小區(qū)房?jī)r(jià)跌回2017年 跌了但還是賣(mài)不出去?!
- 雞蛋便宜了!未來(lái)價(jià)格怎么走? 每日視訊
- 怎么找回清空微信聊天記錄?微信聊天記錄怎么備份?
- 六五環(huán)境日·手繪海報(bào)|挑剔的TA們,為何偏愛(ài)山東? 世界熱點(diǎn)評(píng)
- 屏幕上的圓圈怎樣取消?手機(jī)屏幕失靈點(diǎn)不動(dòng)怎么辦?
- win10網(wǎng)絡(luò)連接不見(jiàn)了?win10網(wǎng)絡(luò)類(lèi)型在哪里設(shè)置?
- 教育部:加強(qiáng)實(shí)驗(yàn)教學(xué),將實(shí)驗(yàn)操作納入中考
- 手機(jī)上怎么登錄官網(wǎng)?手機(jī)官網(wǎng)的手機(jī)是正品嗎?
- ipad屏幕變暗了怎么恢復(fù)?ipad屏幕旋轉(zhuǎn)怎么設(shè)置?
- 仙佑膏藥:互聯(lián)網(wǎng)+膏藥產(chǎn)業(yè):電商與移動(dòng)互聯(lián)網(wǎng)跨界融合
- 今年云夢(mèng)2863人參加高考 快播報(bào)
- 我區(qū)發(fā)布總部經(jīng)濟(jì)高質(zhì)量發(fā)展實(shí)施意見(jiàn)_最新
- 越“聰明”的代碼,越是“一次性” 全球播資訊
- 加盟店負(fù)增長(zhǎng)凈利潤(rùn)連年大降,海瀾之家請(qǐng)張頌文能否破解“老化”難題_環(huán)球要聞 今日聚焦
- 每日視訊:重啟天涯第一步失??!7 × 24 小時(shí)直播,僅募集 14.99 萬(wàn)元!投資人潘海東:天涯已被時(shí)代拋棄,只剩下品牌和腦殘粉
- 全球今日?qǐng)?bào)丨起亞聘請(qǐng)前寶馬設(shè)計(jì)師John Buckingham,以加強(qiáng)設(shè)計(jì)能力
- 環(huán)球速看:moto razr 40 Ultra斬獲京東手機(jī)榜TOP1
- 角力動(dòng)力電池TWh時(shí)代,智能化或成制勝關(guān)鍵_全球觀天下
- 【環(huán)球快播報(bào)】眾泰董事長(zhǎng)黃繼宏辭職
- 5月新勢(shì)力蔚來(lái)、理想、小鵬、哪吒、零跑銷(xiāo)量盤(pán)點(diǎn),你看好哪家?_天天時(shí)訊
- 愛(ài)爾眼科手術(shù)器械破損生銹被罰 愛(ài)爾眼科手術(shù)器械消毒不合規(guī)被罰 每日看點(diǎn)
- 山東省煙臺(tái)市萊山區(qū):開(kāi)展“虎門(mén)硝煙日” 禁毒宣傳活動(dòng)
- 今日熱門(mén)!7月3日開(kāi)工!張店這些主干路路口要變樣……
- 農(nóng)業(yè)周觀點(diǎn):養(yǎng)豬連虧5個(gè)月,寵物618拉序幕 世界新視野
- 當(dāng)前速看:向AI提問(wèn) 這個(gè)新職業(yè)火了
- 全球今熱點(diǎn):民族團(tuán)結(jié)一家親 反詐宣傳同步行
- 王自如被強(qiáng)制執(zhí)行198萬(wàn)
- 全球熱門(mén):清廉七里河 · 每日廉語(yǔ)(324)
- win10如何設(shè)置屏保圖片(win10如何設(shè)置屏保)
- 熱資訊!亞馬遜可能會(huì)增加 Prime 移動(dòng)服務(wù)
- 起底疑吃出老鼠頭高校食堂運(yùn)營(yíng)方 #江西一高校食堂飯菜中疑吃出老鼠頭
- 環(huán)球熱議:郭明錤:蘋(píng)果 MR 頭戴設(shè)備成功關(guān)鍵因素在于能否與 AI、AIGC 高度整合 投資人更關(guān)注何時(shí)推出類(lèi) ChatGPT 服務(wù)
- 重慶市經(jīng)濟(jì)信息委開(kāi)展“滿(mǎn)天星”行動(dòng)計(jì)劃“拉網(wǎng)式”調(diào)研
- VELOTRIC完成千萬(wàn)級(jí)A+輪融資|每日?qǐng)?bào)道
- 目標(biāo)300萬(wàn)僅完成約20萬(wàn),直播也救不了天涯?
- 視焦點(diǎn)訊!海天味業(yè)增資至55.61億 增幅20%
- 嚴(yán)管施工噪音 “護(hù)航模式”助力高考
- 隱藏居民樓里的偽中醫(yī):號(hào)稱(chēng)“老中醫(yī)” 穴位卻分不清_全球關(guān)注
- 淄博太暖了吧!這樣的助考方式......助夢(mèng)高考,請(qǐng)將這條藍(lán)絲帶占屏朋友圈!
- 五菱繽果5月銷(xiāo)量18015輛 環(huán)比增長(zhǎng)10%-環(huán)球即時(shí)
- 今日?qǐng)?bào)丨2023年“慈心一日捐”活動(dòng)公示(一)
- 水立方足浴店技師山寨“閱兵”步操,網(wǎng)民:老板以前當(dāng)兵?
- 環(huán)球熱資訊!機(jī)構(gòu):電子特氣市場(chǎng)未來(lái)數(shù)年持續(xù)面臨供應(yīng)短缺風(fēng)險(xiǎn)
- 新潮創(chuàng)投于雷:半導(dǎo)體并購(gòu)不是目的,核心是服務(wù)企業(yè)長(zhǎng)期發(fā)展
- 科諾美完成近億元A輪融資_最新資訊
- 【走進(jìn)區(qū)域看發(fā)展】生態(tài)“雙城” 新顏新貌-今日?qǐng)?bào)
- 特賽發(fā)科技獲得天使輪投資
- 吉野家雙拼飯含異物被罰 吉野家餐食含異物被罰5萬(wàn) 全球看熱訊
- 全球滾動(dòng):華為手機(jī)用4G打敗5G,向世界證明什么才叫創(chuàng)新
- 【天天聚看點(diǎn)】邁入2.0時(shí)代!無(wú)人零售行業(yè)重新進(jìn)入快車(chē)道
- “采取一切必要措施”!沙特減產(chǎn)100萬(wàn)桶,意味著什么? 天天時(shí)快訊
- 省“六一”少兒文藝調(diào)演精彩呈現(xiàn)
- 人民幣兌美元中間價(jià)報(bào)7.0904 調(diào)升35個(gè)基點(diǎn) 熱頭條
- 起底葉音背后公司 起底葉音工作室
- 星鯨科技獲數(shù)千萬(wàn)元天使輪融資 今日熱議
- 北交所、全國(guó)股轉(zhuǎn)公司出臺(tái)“十八條”優(yōu)化市場(chǎng)服務(wù)—— 強(qiáng)化資本市場(chǎng)對(duì)中小企業(yè)創(chuàng)新發(fā)展|環(huán)球快資訊
- 暖心!來(lái)自銀行的“小蜜蜂驛站”......
- AI識(shí)別技術(shù)讓雪豹有了專(zhuān)屬“身份證”
- 印度列車(chē)脫軌相撞事故現(xiàn)場(chǎng)|環(huán)球新消息
- 焦點(diǎn)速訊:蘋(píng)果iOS 17發(fā)布時(shí)間正式官宣,這些功能提前知曉
- 超七千輛出租車(chē)公交車(chē)參與福建高考保障 天天快訊
- 杭州路口一車(chē)輛喇叭一直響 民警打開(kāi)車(chē)門(mén)發(fā)現(xiàn)......_獨(dú)家
- 工業(yè)富聯(lián):已著手開(kāi)發(fā)下一代AI服務(wù)器
- 外國(guó)人都在搶購(gòu)中國(guó)車(chē)!出口量反超日本 這些車(chē)有多強(qiáng)?
- 阿里云部分云服務(wù)器價(jià)格將下調(diào)
- 環(huán)球熱議:中物聯(lián):5月份我國(guó)大宗商品供應(yīng)持續(xù)增加
- 全球觀點(diǎn):科創(chuàng)50ETF期權(quán)今日上市,標(biāo)的ETF規(guī)模超650億元
- 暑期高考生學(xué)車(chē)注意事項(xiàng)|世界熱文
- 世界觀點(diǎn):注意!學(xué)生購(gòu)票有變化
- 承壓、韌性、破局 阿里影業(yè)(1060.HK)2023財(cái)年業(yè)績(jī)深度解讀
- 索尼CEO:云游戲存在延遲、服務(wù)器浪費(fèi)等障礙 環(huán)球微資訊
- 科技創(chuàng)新推動(dòng)模式變革 行業(yè)加速探索未來(lái)新水務(wù) 當(dāng)前速訊
- 騰勢(shì)汽車(chē)成為首個(gè)MPV單月冠軍的中國(guó)豪華品牌