设计模式:适配器与装饰器
装饰器模式
我们常常面临一个问题,在原有的功能上进行扩展,如何优雅的进行实现?
有人会说,给这个类加一个新方法不就得了。这不就违背了开闭原则吗?类应该对扩展开放,对修改封闭。
一般常见有两种方式,一是直接继承于想要扩展的类,那么我们就能够在原有功能的基础上,扩展更多的方法。下面将进行简单实现:
class Phone
{
void Call()
{
}
void SendMessage()
{
}
}
class MusicPhone : Phone
{
void PlayMusic()
{
}
}
class GamePhone : Phone
{
void PlayGame()
{
}
}
我们申明了一个手机类,它初始只有两个功能,打电话和发短信。
然后我们通过继承,给这个手机增加了播放音乐的功能。同时,我们还造了一部能玩游戏的手机。
缺点
装饰器模式能够很好的帮助我们对一个类进行扩展,并且符合开闭原则。但是随着功能越来越多,静态的通过继承来进行实现,会造成代码量迅速膨胀
同时通过以下方法也是可行的,并且可以有效解决继承带来的弊端。:
interface IPhone
{
void Call();
void SendMessage();
}
class Phone : IPhone
{
public void Call()
{
}
public void SendMessage()
{
}
}
class MediaPhone : IPhone
{
private readonly IPhone _phone;
public MediaPhone(IPhone phone)
{
_phone = phone;
}
void PlayMusic()
{
}
void PlayGame()
{
}
public void Call()
{
_phone.Call();
}
public void SendMessage()
{
_phone.SendMessage();
}
}
通过关联某一个类,然后在此基础上进行扩展。
C#还有一个装饰模式利器,那就是静态扩展方法。同样还是手机的例子:
class Program
{
static void Main(string[] args)
{
var phone = new Phone();
phone.PlayMusic();
}
}
class Phone
{
void Call()
{
}
void SendMessage()
{
}
}
static class PhoneExtension
{
public static void PlayMusic(this Phone phone)
{
}
}
通过一个静态类,实现一个静态方法,就可以达到扩展的目的,这种方式被官方类库广泛使用,最常见的就是Linq程序集下对IEnumable接口的扩展了。
适配器模式
如果装饰器模式是为了扩展,那么适配器模式就是为了兼容。
虽然我们普遍存在接口,只要我们依赖同样的接口,就能无需关心实现。但是如果接口层次不兼容如何解决呢?修改接口的话,会对代码进行侵入性的更改。
通过适配器模式,可以较好的解决这个问题。
还是手机的例子:
class Program
{
static void Main(string[] args)
{
var phone = new Phone();
IWatch adapter = new WatchAdapter(phone);
TellMeTime(adapter);
}
static void TellMeTime(IWatch watch)
{
watch.ShowTime();
}
}
interface IPhone
{
void Call();
void SendMessage();
void ShowTime();
}
class Phone : IPhone
{
public void Call()
{
}
public void SendMessage()
{
}
public void ShowTime()
{
}
}
interface IWatch
{
void ShowTime();
}
class WatchAdapter : IWatch
{
private readonly IPhone _phone;
public WatchAdapter(IPhone phone)
{
_phone = phone;
}
public void ShowTime() => _phone.ShowTime();
}
我们的程序需要一个手表来显示时间,但是现在没有手表,找来找去,发现只有手机可以用,并且用它来显示时间也是合适的。可是TellMeTime方法接收的参数是IWatch类型,手机并没有实现这个接口。此时我们就可以使用一个Adapter来封装一下手机,并且实现IWatch接口,即可满足我们的需求。
总结
装饰器模式主要应用于扩展,扩展丰富了类的功能,但却并不是类的一部分。他们之间是没有必然关系的。
适配器是为了解决两个不兼容的类或接口,使他们能够正常的进行功能配合而生。
- 0
- 0
-
分享