有关设计的网站,手机系统流畅神器,厂家营销型网站建设,保定做网站那家好C#面试题#xff08;中级篇#xff09;#xff0c;详细讲解#xff0c;帮助你深刻理解#xff0c;拒绝背话术#xff01;-CSDN博客
简单工厂模式
优点#xff1a;
根据条件有工厂类直接创建具体的产品
客户端无需知道具体的对象名字#xff0c;可以通过配置文件创建…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 ListIObserver observers new ListIObserver();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();}
}
IState 接口定义了状态的行为方法 Handle具体的状态类需要实现该方法。ConcreteStateA 和 ConcreteStateB 类实现了 IState 接口分别代表不同的状态在 Handle 方法中处理当前状态的逻辑并可以进行状态的转换。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();}
} 优点 提高复用性可以让原本不兼容的类一起工作使得一些已经存在的类可以被复用无需对其进行修改。例如当你有一个旧的库其接口与新系统不兼容时使用适配器模式可以将其集成到新系统中。 灵活性和扩展性适配器模式符合开闭原则当需要适配新的类时只需要创建新的适配器类而不需要修改现有的代码。 解耦性将客户端和适配者解耦客户端只需要与目标接口交互而不需要关心适配者的具体实现。
缺点 增加系统复杂度引入适配器类会增加系统的类数量和代码复杂度特别是当存在多个适配器时可能会使系统变得难以理解和维护。 过多使用会导致代码混乱如果过度使用适配器模式可能会导致系统中存在大量的适配器类使得代码结构变得混乱难以把握整体的设计意图。