结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
1. 适配器模式(Adapter)
将一个类的借口转换成客户希望的另外的一个接口。Adapter模式使得原本由于接口不兼容二不能一起工作的那些类可以一起工作。
适配器的使用场景:在想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该使用适配器模式,通常用于软件开发后期火维护期。
//这是客户所期待的接口。目标可以是具体的或是抽象的类,也可以是接口
class Target
{
public virtual void Request()
{
Console.WriteLine("普通请求!");
}
}
//需要适配的类
class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("特殊请求");
}
}
//在内部包装一个Adaptee对象,把源接口转换成目标接口
class Adapter:Target
{
private Adaptee adaptee = new Adaptee();
public override void Request()
{
adaptee.SpecificRequest();
}
}
//客户端代码
static void Main(string[] args)
{
Target target = new Adapter();
target.Request();
Console.Read();
}
2.外观模式
外观模式为子系统中一组接口提供一个一致的界面,此模式定义一个高层接口,这个接口使得这一子系统更加容易使用。
何时使用外观模式:
首先,在设计初期阶段,应该要有意识的将不同的两个层分离,层与层之间建立外观Facade;
其次,在开发阶段,子系统往往因为不断的重构而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。
第三,自爱维护一个遗留的大型系统时,可能这个系统已经难以维护和扩展,可以为新系统开发一个外观模式,来提供设计粗糙火高复杂的遗留代码的比较清晰简单的接口,让心系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。
class SubSystemOne
{
public void MethodOne()
{
Console.WriteLine("子系统方法一");
}
}
class SubSystemTwo
{
public void MethodTwo()
{
Console.WriteLine("子系统方法二");
}
}
class SubSystemThree
{
public void MethodThree()
{
Console.WriteLine("子系统方法三");
}
}
class Facade
{
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
public Facade()
{
one = new SubSystemOne();
two = new SubSystemTwo();
three = new SubSystemThree();
}
public void MethodA()
{
Console.WriteLine("lll");
one.MethodOne();
two.MethodTwo();
}
public void MethodB()
{
Console.WriteLine("lll");
two.MethodTwo();
three.MethodThree();
}
}
static void Main(string[] args)
{
Facade facade = new Facade();
facade.MethodA();
facade.MethodB();
}
3.装饰模式
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生产子类更加灵活。
插入题外话
这里画类图的软件是https://www.processon.com/ ,其画类图的具体介绍可以看博客【UML 建模】在线UML建模工具 ProcessOn 使用详解,关于类图中属性的表示,方法的表示和类与类之间关系的表示可以看文章https://www.cnblogs.com/shindo/p/5579191.html

https://www.processon.com/view/link/5fdd6b165653bb4ccf300676
class Program
{
static void Main(string[] args)
{
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
}
}
abstract class Component
{
public abstract void Operation();
}
class ConcreteComponent:Component
{
public override void Operation()
{
Console.WriteLine("具体对象的操作");
}
}
abstract class Decorator:Component
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if(component!=null)
{
component.Operation();
}
}
}
class ConcreteDecoratorA : Decorator
{
private string addedState;
public override void Operation()
{
base.Operation();
addedState = "new state";
Console.WriteLine("具体修饰对象A的操作");
}
}
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddBehavior();
Console.WriteLine("具体修饰对象B的操作");
}
void AddBehavior()
{
}
}
装饰模式的优点是把类中的装饰功能从类中搬移去除,这样可以简化原有的类,装饰模式的装饰顺序很重要。
装饰模式总结:
装饰模式是为已有功能动态添加更多功能的一种方式
何时使用:
当系统需要新功能时,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。装饰模式提供了一种非常好的解决方案,他把每个要装饰的功能放在单独的类中,并让这个类包转它所需要装饰的对象,因此,当需要执行特殊行为时,客户端代码就可以在运行时根据需要有选择的,按顺序的使用装饰类包装对象了。
好处:
把类中的装饰功能从类中搬移去除,这样可以简化原有的类。
4.代理模式
为其他对象提供一种代理以控制对这个对象的访问。

5.桥接模式
桥接模式就是将抽象部分与它的实现部分分离,使他们都可以独立的变化。这里就用到一个合成/聚合复用原则,优先使用对象合成/聚合,而不是类继承,这样有助于每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
举例手机功能的扩展

该模式下需要写2个抽象类“手机品牌和手机软件”。
abstract class HandasetSoft
{
public abstract void Run();
}
//手机游戏
class HandsetGame:HandsetSoft
{
public override void Run()
{
console.writeline("运行手机游戏");
}
}
//通讯录
class HandsetAddressList:HandsetSoft
{
public override void Run()
{
console.writeline("");
}
}
//手机品牌类
abstract class HandsetBrand
{
protected HandsetSoft soft;
//设置手机软件
public void SetHandsetSoft(HandsetSoft soft)
{
this.soft=soft;
}
//运行
public abstract void Run();
}
class HandsetBrandN:HandsetBrand
{
public override void Run()
{
soft.Run();
}
}
class HandsetBrandM:HandsetBrand
{
public override void Run()
{
soft.Run();
}
}
//客户端调用代码
static void Main(string[] args)
{
HandsetBrand ab;
ab1=new HandsetBrandN();
ab1.SetHandsetSoft(new HandsetGame());
ab1.Run();
ab1.SetHandsetSoft(new HandsetAddressList());
ab1.Run();
ab2=new HandsetBrandN();
ab2.SetHandsetSoft(new HandsetGame());
ab2.Run();
ab2.SetHandsetSoft(new HandsetAddressList());
ab2.Run();
}
以下是理论形式

abstract class Implementor
{
public abstract void Operation();
}
ConcreteImplementorA和ConcreteImplementorB等派生类
class ConcreteImplementorA:Implementor
{
public override void Operation()
{
console.writeline("具体实现A的方法执行");
}
}
class ConcreteImplementorB:Implementor
{
public override void Operation()
{
console.writeline("具体执行B的方法执行");
}
}
class Abstraction
{
protected Implementor implementor;
public void SetImplementor(Implementor implementor)
{
this.implementor=implementor;
}
public virtual void Operation()
{
implementor.Operation();
}
}
class RefinedAbstraction:Abstraction
{
public override void Operation()
{
implementor.Operation();
}
}
static void Main(string[] args)
{
Abstraction ab=new RefinedAbstraction();
ab.SetImplementor(new concreteImplementorA());
ab.Operation();
ab.SetImplementor(new concreteImplementorB());
ab.Operation();
}
6.组合模式
组合模式将对象组合成树形结构以表示,’部分-整体‘的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
7.享元模式
运用共享技术有效的支持大量细粒度的对象。
本文详细介绍了结构型设计模式中的七种模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式和享元模式。通过实例解释了每种模式的应用场景、优缺点及其实现方式。

1040

被折叠的 条评论
为什么被折叠?



