C#面試常考隨筆12:游戲開發中常用的設計模式【C#面試題(中級篇)補充】

C#面試題(中級篇),詳細講解,幫助你深刻理解,拒絕背話術!-CSDN博客

簡單工廠模式

優點:

根據條件有工廠類直接創建具體的產品

客戶端無需知道具體的對象名字,可以通過配置文件創建,靈活。

缺點:

每增加一個對象,就需要在工廠添加新的產品,修改工廠邏輯,不易拓展


?

using System;// 定義產品的抽象基類
public abstract class Product
{public abstract void Use();
}// 具體產品類A
public class ConcreteProductA : Product
{public override void Use(){Console.WriteLine("Using ConcreteProductA");}
}// 具體產品類B
public class ConcreteProductB : Product
{public override void Use(){Console.WriteLine("Using ConcreteProductB");}
}// 簡單工廠類
public class SimpleFactory
{public static Product CreateProduct(string type){switch (type){case "A":return new ConcreteProductA();case "B":return new ConcreteProductB();default:throw new ArgumentException("Invalid product type");}}
}class Program
{static void Main(){Product productA = SimpleFactory.CreateProduct("A");productA.Use();Product productB = SimpleFactory.CreateProduct("B");productB.Use();}
}

工廠方法模式

解決了簡單工廠的 開放-關閉原則

不同的子類由工廠子類創建

但是對象數量會很多

抽象工廠

抽象工廠:(相當于有多個工廠)不同廠商生產的同一產品,產品擁有相同的結構,區別在于不同的廠商和動作的細節。比如多個電腦工廠,生產不同品牌的電腦,電腦有多個配件,每個工廠都生產這些配件()。

抽象工廠有產品,繼承的工廠生產對應廠商的產品。


using System;// 定義產品A的抽象基類
public abstract class AbstractProductA
{public abstract void UseA();
}// 具體產品A1
public class ConcreteProductA1 : AbstractProductA
{public override void UseA(){Console.WriteLine("Using ConcreteProductA1");}
}// 具體產品A2
public class ConcreteProductA2 : AbstractProductA
{public override void UseA(){Console.WriteLine("Using ConcreteProductA2");}
}// 定義產品B的抽象基類
public abstract class AbstractProductB
{public abstract void UseB();
}// 具體產品B1
public class ConcreteProductB1 : AbstractProductB
{public override void UseB(){Console.WriteLine("Using ConcreteProductB1");}
}// 具體產品B2
public class ConcreteProductB2 : AbstractProductB
{public override void UseB(){Console.WriteLine("Using ConcreteProductB2");}
}// 抽象工廠類
public abstract class AbstractFactory
{public abstract AbstractProductA CreateProductA();public abstract AbstractProductB CreateProductB();
}// 具體工廠類1,負責創建產品A1和產品B1
public class ConcreteFactory1 : AbstractFactory
{public override AbstractProductA CreateProductA(){return new ConcreteProductA1();}public override AbstractProductB CreateProductB(){return new ConcreteProductB1();}
}// 具體工廠類2,負責創建產品A2和產品B2
public class ConcreteFactory2 : AbstractFactory
{public override AbstractProductA CreateProductA(){return new ConcreteProductA2();}public override AbstractProductB CreateProductB(){return new ConcreteProductB2();}
}class Program
{static void Main(){AbstractFactory factory1 = new ConcreteFactory1();AbstractProductA productA1 = factory1.CreateProductA();AbstractProductB productB1 = factory1.CreateProductB();productA1.UseA();productB1.UseB();AbstractFactory factory2 = new ConcreteFactory2();AbstractProductA productA2 = factory2.CreateProductA();AbstractProductB productB2 = factory2.CreateProductB();productA2.UseA();productB2.UseB();}
}

觀察者模式(發布-訂閱)

和事件系統的邏輯基本一致

一個發布者,多個訂閱者。把觀察者注冊進去。下圖是簡易的事件系統

using System;
using System.Collections.Generic;// 定義觀察者接口
public interface IObserver
{void Update(string message);
}// 定義主題接口
public interface ISubject
{void RegisterObserver(IObserver observer);void RemoveObserver(IObserver observer);void NotifyObservers();
}// 具體主題類
public class ConcreteSubject : ISubject
{private List<IObserver> observers = new List<IObserver>();private string message;public void RegisterObserver(IObserver observer){observers.Add(observer);}public void RemoveObserver(IObserver observer){observers.Remove(observer);}public void NotifyObservers(){foreach (var observer in observers){observer.Update(message);}}public void SetMessage(string newMessage){message = newMessage;NotifyObservers();}
}// 具體觀察者類
public class ConcreteObserver : IObserver
{private string name;public ConcreteObserver(string name){this.name = name;}public void Update(string message){Console.WriteLine($"{name} received message: {message}");}
}class Program
{static void Main(){// 創建主題ConcreteSubject subject = new ConcreteSubject();// 創建觀察者ConcreteObserver observer1 = new ConcreteObserver("Observer 1");ConcreteObserver observer2 = new ConcreteObserver("Observer 2");// 注冊觀察者subject.RegisterObserver(observer1);subject.RegisterObserver(observer2);// 主題發布消息subject.SetMessage("New message from the subject!");// 移除一個觀察者subject.RemoveObserver(observer2);// 主題再次發布消息subject.SetMessage("Another message from the subject!");}
}

狀態模式

特點:

和FSM有限狀態機是相似邏輯,可以說FSM是狀態模式的運用

將狀態相關的行為封裝到不同的狀態類中,使得狀態的變化和對象行為的變化能夠獨立進行,符合開閉原則。

游戲中角色的不同狀態(如奔跑、跳躍、攻擊等)可用狀態模式實現,每個狀態有不同行為邏輯

using System;// 定義狀態接口
public interface IState
{void Handle(Context context);
}// 具體狀態類A
public class ConcreteStateA : IState
{public void Handle(Context context){Console.WriteLine("Handling state A. Transitioning to state B.");context.State = new ConcreteStateB();}
}// 具體狀態類B
public class ConcreteStateB : IState
{public void Handle(Context context){Console.WriteLine("Handling state B. Transitioning to state A.");context.State = new ConcreteStateA();}
}// 上下文類
public class Context
{private IState state;public Context(IState initialState){this.state = initialState;}public IState State{get { return state; }set{state = value;Console.WriteLine($"State changed to {state.GetType().Name}");}}public void Request(){state.Handle(this);}
}class Program
{static void Main(){// 創建初始狀態IState initialState = new ConcreteStateA();// 創建上下文對象Context context = new Context(initialState);// 執行請求,觸發狀態轉換context.Request();context.Request();}
}
  1. IState?接口:定義了狀態的行為方法?Handle,具體的狀態類需要實現該方法。
  2. ConcreteStateA?和?ConcreteStateB?類:實現了?IState?接口,分別代表不同的狀態,在?Handle?方法中處理當前狀態的邏輯,并可以進行狀態的轉換。
  3. Context?類:維護一個當前狀態的引用?state,通過?Request?方法調用當前狀態的?Handle?方法,同時提供了?State?屬性用于改變當前狀態。

優點

  • 可維護性高:將不同狀態的行為封裝到不同的狀態類中,使得代碼結構清晰,易于理解和維護。當需要添加新的狀態時,只需要創建一個新的狀態類并實現相應的行為,而不需要修改現有的代碼。
  • 可擴展性強:符合開閉原則,對擴展開放,對修改關閉。可以方便地添加新的狀態和狀態轉換邏輯,而不會影響其他狀態類和上下文類。
  • 狀態轉換清晰:狀態的轉換邏輯集中在狀態類中,使得狀態轉換的規則更加清晰,易于管理和調試。

缺點

  • 類的數量增加:每個狀態都需要一個對應的狀態類,當狀態較多時,會導致類的數量增加,增加了系統的復雜性。
  • 狀態之間的耦合:狀態類之間可能存在一定的耦合,特別是在狀態轉換時,一個狀態類可能需要知道其他狀態類的信息,這可能會影響代碼的可維護性。

?裝飾器模式

動態地給對象添加額外職責。游戲中給角色添加裝備或增益效果可使用裝飾器模式

?

using System;// 定義組件接口
public interface IComponent
{void Operation();
}// 具體組件類
public class ConcreteComponent : IComponent
{public void Operation(){Console.WriteLine("ConcreteComponent: Performing basic operation.");}
}// 裝飾器抽象類
public abstract class Decorator : IComponent
{protected IComponent component;public Decorator(IComponent component){this.component = component;}public virtual void Operation(){if (component != null){component.Operation();}}
}// 具體裝飾器類A
public class ConcreteDecoratorA : Decorator
{public ConcreteDecoratorA(IComponent component) : base(component){}public override void Operation(){base.Operation();AddedBehaviorA();}private void AddedBehaviorA(){Console.WriteLine("ConcreteDecoratorA: Adding additional behavior A.");}
}// 具體裝飾器類B
public class ConcreteDecoratorB : Decorator
{public ConcreteDecoratorB(IComponent component) : base(component){}public override void Operation(){base.Operation();AddedBehaviorB();}private void AddedBehaviorB(){Console.WriteLine("ConcreteDecoratorB: Adding additional behavior B.");}
}class Program
{static void Main(){// 創建具體組件IComponent component = new ConcreteComponent();// 使用具體裝飾器A包裝組件IComponent decoratedComponentA = new ConcreteDecoratorA(component);// 使用具體裝飾器B包裝經過裝飾器A包裝的組件IComponent decoratedComponentB = new ConcreteDecoratorB(decoratedComponentA);// 調用操作方法decoratedComponentB.Operation();}
}

優點:

  • 裝飾類和被裝飾類可以獨立發展,不會相互耦合。

  • 裝飾模式是繼承的一個替代模式,裝飾模式可以動態擴展一個實現類的功能。

缺點:

  • 多層裝飾比較復雜。

適配器模式

將一個類的接口轉換成客戶希望的另一個接口。適配器模式主要有類適配器模式和對象適配器模式兩種實現方式。

對象適配器:相當于把對象作為一個屬性

類適配器:相當于繼承

對象:

using System;// 目標接口,客戶端所期望的接口
public interface ITarget
{void Request();
}// 適配者類,需要被適配的類
public class Adaptee
{public void SpecificRequest(){Console.WriteLine("Adaptee: Specific request.");}
}// 適配器類,實現目標接口并持有適配者對象
public class Adapter : ITarget
{private Adaptee adaptee;public Adapter(Adaptee adaptee){this.adaptee = adaptee;}public void Request(){adaptee.SpecificRequest();}
}class Program
{static void Main(){// 創建適配者對象Adaptee adaptee = new Adaptee();// 創建適配器對象并傳入適配者對象ITarget adapter = new Adapter(adaptee);// 通過適配器調用目標接口方法adapter.Request();}
}

類:

using System;// 目標接口
public interface ITargetClassAdapter
{void Request();
}// 適配者類
public class AdapteeClassAdapter
{public void SpecificRequest(){Console.WriteLine("AdapteeClassAdapter: Specific request.");}
}// 適配器類,繼承適配者類并實現目標接口
public class ClassAdapter : AdapteeClassAdapter, ITargetClassAdapter
{public void Request(){SpecificRequest();}
}class ProgramClassAdapter
{static void Main(){// 創建類適配器對象ITargetClassAdapter adapter = new ClassAdapter();// 通過適配器調用目標接口方法adapter.Request();}
}

優點

  1. 提高復用性:可以讓原本不兼容的類一起工作,使得一些已經存在的類可以被復用,無需對其進行修改。例如,當你有一個舊的庫,其接口與新系統不兼容時,使用適配器模式可以將其集成到新系統中。

  2. 靈活性和擴展性:適配器模式符合開閉原則,當需要適配新的類時,只需要創建新的適配器類,而不需要修改現有的代碼。

  3. 解耦性:將客戶端和適配者解耦,客戶端只需要與目標接口交互,而不需要關心適配者的具體實現。

缺點

  1. 增加系統復雜度:引入適配器類會增加系統的類數量和代碼復雜度,特別是當存在多個適配器時,可能會使系統變得難以理解和維護。

  2. 過多使用會導致代碼混亂:如果過度使用適配器模式,可能會導致系統中存在大量的適配器類,使得代碼結構變得混亂,難以把握整體的設計意圖。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/894772.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/894772.shtml
英文地址,請注明出處:http://en.pswp.cn/news/894772.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數字人|通過語音和圖片來創建高質量的視頻

簡介 arXiv上的計算機視覺領域論文&#xff1a; AniPortrait: Audio-Driven Synthesis of Photorealistic Portrait Animation AniPortrait&#xff1a;照片級真實感肖像動畫的音頻驅動合成 核心內容圍繞一種新的人像動畫合成框架展開。 研究內容 提出 AniPortrait 框架&a…

數據結構實戰之線性表(三)

目錄 1.順序表釋放 2.順序表增加空間 3.合并順序表 4.線性表之鏈表實現 1.項目結構以及初始代碼 2.初始化鏈表(不帶頭結點) 3.鏈表尾部插入數據并顯示 4.鏈表頭部插入數據 5.初始化鏈表&#xff08;帶頭結點&#xff09; 6.帶頭結點的鏈表頭部插入數據并顯示 7.帶頭結…

Docker使用指南(一)——鏡像相關操作詳解(實戰案例教學,適合小白跟學)

目錄 1.鏡像名的組成 2.鏡像操作相關命令 鏡像常用命令總結&#xff1a; 1. docker images 2. docker rmi 3. docker pull 4. docker push 5. docker save 6. docker load 7. docker tag 8. docker build 9. docker history 10. docker inspect 11. docker prune…

C++基礎day1

前言&#xff1a;謝謝阿秀&#xff0c;指路阿秀的學習筆記 一、基礎語法 1.構造和析構: 類的構造函數是一種特殊的函數&#xff0c;在創建一個新的對象時調用。類的析構函數也是一種特殊的函數&#xff0c;在刪除所創建的對象時調用。 構造順序&#xff1a;父類->子類 析…

嘗試ai生成figma設計

當聽到用ai 自動生成figma設計時&#xff0c;不免好奇這個是如何實現的。在查閱了不少資料后&#xff0c;有了一些想法。參考了&#xff1a;在figma上使用腳本自動生成色譜 這篇文章提供的主要思路是&#xff1a;可以通過腳本的方式構建figma設計。如果我們使用ai 生成figma腳本…

iOS 老項目適配 #Preview 預覽功能

前言 iOS 開發者 最憋屈的就是UI 布局慢,一直以來沒有實時預覽功能,雖然swiftUI 早就支持了,但是目前主流還是使用UIKit在布局,iOS 17 蘋果推出了 #Preview 可以支持UIKit 實時預覽,但是僅僅是 iOS 17,老項目怎么辦呢?于是就有了這篇 老項目適配 #Preview 預覽 的文章,…

【分布式架構理論2】分布式架構要處理的問題及解決方案

文章目錄 1. 應用服務拆分2. 分布式調用3. 分布式協同4. 分布式計算5. 分布式存儲6. 分布式資源管理與調度7. 高性能與可用性優化8. 指標與監控 將分布式架構需要解決的問題按照順序列舉為如下幾步 問題分類具體內容應用服務拆分分布式是用分散的服務和資源代替集中的服務和資…

【PyQt】pyqt小案例實現簡易文本編輯器

pyqt小案例實現簡易文本編輯器 分析 實現了一個簡單的文本編輯器&#xff0c;使用PyQt5框架構建。以下是代碼的主要功能和特點&#xff1a; 主窗口類 (MyWindow): 繼承自 QWidget 類。使用 .ui 文件加載用戶界面布局。設置窗口標題、狀態欄消息等。創建菜單欄及其子菜單項&…

Unity中的虛擬相機(Cinemachine)

Unity Cinemachine詳解 什么是Cinemachine Cinemachine是Unity官方推出的智能相機系統&#xff0c;它提供了一套完整的工具來創建復雜的相機運動和行為&#xff0c;而無需編寫大量代碼。它能夠大大簡化相機管理&#xff0c;提高游戲開發效率。 Cinemachine的主要組件 1. Vi…

【PyQt】getattr動態訪問對象的屬性

問題 使用qtdesigner設計好大體的軟件結構&#xff0c;需要使用代碼進行批量修改控件樣式,self.ui.x 會被解釋為訪問 self.ui 中名為 x 的屬性&#xff0c;而不是將 x 作為變量名來解析&#xff0c;此時需要通過字符串動態訪問 self.ui 中的按鈕對象 for i in range(20):x f…

【電腦系統】電腦突然(藍屏)卡死發出刺耳聲音

文章目錄 前言問題描述軟件解決方案嘗試硬件解決方案嘗試參考文獻 前言 在 更換硬盤 時遇到的問題&#xff0c;有時候只有卡死沒有藍屏 問題描述 更換硬盤后&#xff0c;電腦用一會就卡死&#xff0c;藍屏&#xff0c;顯示藍屏代碼 UNEXPECTED_STORE_EXCEPTION 軟件解決方案…

DEEPSEKK GPT等AI體的出現如何重構工廠數字化架構:從設備控制到ERP MES系統的全面優化

隨著深度學習&#xff08;DeepSeek&#xff09;、GPT等先進AI技術的出現&#xff0c;工廠的數字化架構正在經歷前所未有的變革。AI的強大處理能力、預測能力和自動化決策支持&#xff0c;將大幅度提升生產效率、設備管理、資源調度以及產品質量管理。本文將探討AI體&#xff08…

【大模型LLM面試合集】大語言模型架構_Transformer架構細節

Transformer架構細節 1.Transformer各個模塊的作用 &#xff08;1&#xff09;Encoder模塊 經典的Transformer架構中的Encoder模塊包含6個Encoder Block. 每個Encoder Block包含兩個?模塊, 分別是多頭?注意?層, 和前饋全連接層. 多頭?注意?層采?的是?種Scaled Dot-Pr…

【華為OD-E卷 - 113 跳格子2 100分(python、java、c++、js、c)】

【華為OD-E卷 - 跳格子2 100分&#xff08;python、java、c、js、c&#xff09;】 題目 小明和朋友玩跳格子游戲&#xff0c;有 n 個連續格子組成的圓圈&#xff0c;每個格子有不同的分數&#xff0c;小朋友可以選擇以任意格子起跳&#xff0c;但是不能跳連續的格子&#xff…

訂單狀態監控實戰:基于 SQL 的狀態機分析與異常檢測

目錄 1. 背景與問題 2. 數據準備 2.1 表結構設計 3. 場景分析與實現 3.1 場景 1:檢測非法狀態轉換

說一下JVM管理的常見參數

Java虛擬機&#xff08;JVM&#xff09;有許多常見參數&#xff0c;用于控制其行為和性能。以下是一些常見的JVM參數及其說明&#xff1a; 1. 內存管理參數 -Xms<size> START 設置初始堆內存大小。例如&#xff0c;-Xms512m表示初始堆大小為512MB。 -Xmx<size>…

驗證工具:GVIM和VIM

一、定義與關系 gVim&#xff1a;gVim是Vim的圖形界面版本&#xff0c;提供了更多的圖形化功能&#xff0c;如菜單欄、工具欄和鼠標支持。它使得Vim的使用更加直觀和方便&#xff0c;尤其對于不習慣命令行界面的用戶來說。Vim&#xff1a;Vim是一個在命令行界面下運行的文本編…

4 HBase 的高級 shell 管理命令

4 HBase 的高級 shell 管理命令 1.status 例如&#xff1a;顯示服務器狀態 hbase(main):058:0> status node012.whoami 顯示 HBase 當前用戶&#xff0c;例如&#xff1a; hbase> whoami3.list 顯示當前所有的表 hbase> list4.count 統計指定表的記錄數&#xff0c…

Web - CSS3基礎語法與盒模型

概述 這篇文章是關于 Web 前端 CSS3 的基礎語法與盒模型的講解。包括 CSS3 層疊性及處理沖突規則、偽元素和新增偽類元素、屬性選擇器等。還介紹了文本與字體屬性&#xff0c;如段落和行相關屬性、字體文本屬性。最后闡述了盒子模型&#xff0c;如元素隱藏、行內與塊元素轉換、…

國防科大:雙目標優化防止LLM災難性遺忘

&#x1f4d6;標題&#xff1a;How to Complete Domain Tuning while Keeping General Ability in LLM: Adaptive Layer-wise and Element-wise Regularization &#x1f310;來源&#xff1a;arXiv, 2501.13669 &#x1f31f;摘要 &#x1f538;大型語言模型&#xff08;LLM…