设计模式之中介者模式

定义:用一个中介对象来封装一系列的对象交互,用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。多个对象可以互相通信,建立一个中间的中介类完成彼此间的通信,类似于QQ功能,链接多个类似的对象。

优点:

1、降低了类的复杂度,将一对多转化成了一对一。

2、各个类之间的解耦。

3、符合迪米特原则。

缺点:中介者会庞大,变得复杂难以维护。

实现:以下案例建立一个类似于QQ的功能。单个对象通过QQMeditor于其他对象通信。

1.创建单个的对象的抽象类和实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public abstract class Colleage
{
private string _name;
private string _content;
public Colleage(string n) { _name = n; }
public string Name
{
get { return _name;}
set { _name = value; }
}

public string Content
{
get { return _content;}
set{ _content = value; }
}
public virtual void Talk(){}
}

public class ColleageA : Colleage
{
public ColleageA(string name): base(name){ }
public override void Talk()
{
base.Talk();
Debug.Log("ColleageA说: " + Content);
}
}

public class ColleageB : Colleage
{
public ColleageB(string name) : base(name) { }
public override void Talk()
{
base.Talk();
Debug.Log("ColleageB说: " + Content);
}
}

public class ColleageC : Colleage
{
public ColleageC(string name) : base(name) { }
public override void Talk()
{
base.Talk();
Debug.Log("ColleageC说: " + Content);
}
}

2.创建中介类的抽象类和实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public abstract class Meaditor
{
protected List<Colleage> Colleages = new List<Colleage>();
public virtual void AddColleage(Colleage c){}
public virtual void RemoveColleage(Colleage c){}
public virtual void Notify(Colleage student){}
public virtual void Chart(Colleage A, Colleage B){}
}

public class QQMeaditor:Meaditor
{
public override void AddColleage(Colleage c)
{
Colleages.Add(c);
}

public override void RemoveColleage(Colleage c)
{
Colleages.Remove(c);
}

public override void Notify(Colleage student)
{
int count = Colleages.Count;
for (int i = 0; i < count; i++)
{
Colleages[i].Talk();
}
}

public override void Chart(Colleage A, Colleage B)
{
A.Talk();
B.Talk();
}
}

3.创建客户端类,实现具体调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Client:MonoBehaviour
{
void Start()
{
//创建单个对象和中介对象QQ
QQMeditor qq = new QQMeditor();
ColleageA a = new ColleageA("A");
ColleageB b = new ColleageB("B");
ColleageB c = new ColleageB("C");

a.Content = "加油!";
b.Content = "-----";
c.Content = "=====";
//添加多个对象进管理数组

qq.AddColleage(a);
qq.AddColleage(b);
qq.AddColleage(c);

qq.Notify(a);
b.Content = "_________";
c.Content = "+++++++++";
qq.Chart(b, c);
}
}

设计模式之迭代器模式

定义:提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示。类似于foreach遍历的功能。提到迭代器,首先它是与集合相关的,集合也叫聚集、容器等,我们可以将集合看成是一个可以包容对象的容器,例如List,Set,Map,甚至数组都可以叫做集合,而迭代器的作用就是把容器中的对象一个一个地遍历出来。

优点:
1.简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
2.可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
3.封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。

缺点:

1.对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合。
2.由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

实现:以下将创建一个叙述导航方法的 Iterator 接口和一个返回迭代器的 Container 接口。实现了 Container 接口的实体类将负责实现 Iterator 接口。
1.创建集合抽象类:

abstract class Aggregate
{
public abstract Iterator CreateIterator();
}
2.聚集实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class ConcreteAggregate:Aggregate
{
private IList<object> items = new List<object>();

public override Iterator CreateIterator()
{
return new ConcreteIterator(this);
}

public int Count
{
get { return items.Count; }
}

public object this[int index]
{
get { return items[index]; }
set { items.Insert(index, value); }
}
}

3.迭代器抽象类:

1
2
3
4
5
6
7
abstract class Iterator
{
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}

4.迭代器实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class ConcreteIterator:Iterator
{
/// <summary>
/// 定义了一个具体聚集对象
/// </summary>
private ConcreteAggregate aggregate;

private int current = 0;
/// <summary>
/// 初始化对象将具体聚集类传入
/// </summary>
/// <param name="aggregate"></param>
public ConcreteIterator(ConcreteAggregate aggregate)
{
this.aggregate = aggregate;
}
/// <summary>
/// 第一个对象
/// </summary>
/// <returns></returns>
public override object First()
{
return aggregate[0];
}
/// <summary>
/// 得到聚集的下一对象
/// </summary>
/// <returns></returns>
public override object Next()
{
object ret = null;
current++;
if(current<aggregate.Count)
{
ret = aggregate[current];
}
return ret;
}
/// <summary>
/// 是否到结尾
/// </summary>
/// <returns></returns>
public override bool IsDone()
{
return current >= aggregate.Count ? true : false;
}
/// <summary>
/// 返回当前聚集对象
/// </summary>
/// <returns></returns>
public override object CurrentItem()
{
return aggregate[current];
}
}

5.调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static void TestIterator() 
{
//聚集对象
ConcreteAggregate a = new ConcreteAggregate();

a[0] = "张三";
a[1] = "李四";
a[2] = "叶鹏";
//声明迭代器对象
Iterator i = new ConcreteIterator(a);

object item = i.First();
while(!i.IsDone())
{
Console.WriteLine("{0}回家吃饭",i.CurrentItem());
i.Next();
}
Console.Read();
}

设计模式之解释器模式

定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器用来解释语言中句子,解析表达式。例如a+b,用户输入a+b,解析式负责处理并返回数据,类似于运算类。
角色:
1.AbstractExpression(抽象表达式)
2.TerminalExpression(终结符表达式)
3.N*nterminalExpression(非终结符表达式)
Context(上下文)

优点:

1、可扩展性比较好,灵活。

2、增加了新的解释表达式的方式。

3、易于实现简单文法。
缺点:

1、可利用场景比较少。

2、对于复杂的文法比较难维护。

3、解释器模式会引起类膨胀。

4、解释器模式采用递归调用方法。

实现:创建一个接口 Expression 和实现了 Expression 接口的实体类。定义作为上下文中主要解释器的 TerminalExpression类、 OrExpression、AndExpression 用于创建组合式表达式。
1.创建一个表达式接口(抽象表达式)。

public interface Expression { public boolean interpret(String context);}
2.创建抽象表达式的实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class TerminalExpression implements Expression 
{
private String data;

public TerminalExpression(String data)
{
this.data = data;
}

public Override boolean interpret(String context)
{
if(context.contains(data))
{
return true;
}
return false;
}
}

public class OrExpression implements Expression
{
private Expression expr1 = null;
private Expression expr2 = null;

public OrExpression(Expression expr1, Expression expr2)
{
this.expr1 = expr1;
this.expr2 = expr2;
}

public Override boolean interpret(String context)
{
return expr1.interpret(context) || expr2.interpret(context);
}
}

public class AndExpression implements Expression
{
private Expression expr1 = null;
private Expression expr2 = null;

public AndExpression(Expression expr1, Expression expr2)
{
this.expr1 = expr1;
this.expr2 = expr2;
}

public Override boolean interpret(String context)
{
return expr1.interpret(context) && expr2.interpret(context);
}
}

3.使用 Expression 类来创建规则,并解析它们。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//规则:Robert 和 John 是男性
public static Expression getMaleExpression(){
Expression robert = new TerminalExpression("Robert");
Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
}

//规则:Julie 是一个已婚的女性
public static Expression getMarriedWomanExpression(){
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}

public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression();
System.out.println("John is male? " + isMale.interpret("John"));
System.out.println("Julie is a married women? "
+ isMarriedWoman.interpret("Married Julie"));
}

设计模式之命令模式

定义:通过将一系列的操作封装成一个命令对象,方便执行,同时也能够更好的让我们进行一些操作回滚,用来记录是否执行过该操作等问题。
场景:
1、当一个应用程序调用者与多个目标对象之间存在调用关系时,并且目标对象之间的操作很类似的时候。
2、例如当一个目标对象内部的方法调用太复杂,或者内部的方法需要协作才能完成对象的某个特点操作时。
3、有时候调用者调用目标对象后,需要回调一些方法。
角色:
1.Invoke:调用者对象。
Receiver:接收调用者请求执行操作的目标对象。
ICommand:用于解耦目标对象与调用者之间的抽象命令对象。

使用:首先创建作为命令的接口 Order,然后创建作为请求的 Stock 类(命令对象)。实体命令类(对应一些列操作) BuyStock 和 SellStock,实现了 Order 接口,将执行实际的命令处理。创建作为调用对象的类 Broker,它接受订单并能下订单。
1.创建一个命令接口及命令接口的实体类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface Order {
void execute();
}
public class BuyStock implements Order {
private Stock abcStock;

public BuyStock(Stock abcStock){
this.abcStock = abcStock;
}

public void execute() {
abcStock.buy();
}
}
public class SellStock implements Order {
private Stock abcStock;

public SellStock(Stock abcStock){
this.abcStock = abcStock;
}

public void execute() {
abcStock.sell();
}
}

2.创建一个请求类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Stock 
{
private String name = "ABC";
private int quantity = 10;

public void buy()
{
System.out.println("Stock [ Name: "+name+",
Quantity: " + quantity +" ] bought");
}

public void sell()
{
System.out.println("Stock [ Name: "+name+",
Quantity: " + quantity +" ] sold");
}
}

3.创建命令调用类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Broker 
{
private List<Order> orderList = new ArrayList<Order>();

public void takeOrder(Order order)
{
orderList.add(order);
}

public void placeOrders()
{
for (Order order : orderList)
{
order.execute();
}
orderList.clear();
}
}

设计模式之责任链模式

定义:为请求创建了一个接收者对象的链,使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。每个处理者必须绑定下一个事件处理者(最后一个例外),才能保证责任链往下传播。
使用场景:

1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

3、可动态指定一组对象处理请求。
角色:
1.抽象处理者角色(Handler):定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回下家的引用。
2.具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于处理者持有下家引用,因此,如果需要,具体处理者可以访问下家。
优点:

1、降低耦合度。它将请求的发送者和接收者解耦。

2、简化了对象。使得对象不需要知道链的结构。

3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。

4、增加新的请求处理类很方便。

缺点:

1、不能保证请求一定被接收。

2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。

3、可能不容易观察运行时的特征,有碍于除错。

使用:请假系统,以下案例通过条件请假天数来判断是否满足条件,满足则返回,不满足则调用下个链的判断方法。

1.抽象处理者角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
abstract class Handler
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}

private Handler successor;
//定义下家的引用
public Handler Successor
{
get { return successor; }
set { successor = value; }
}

public abstract bool PassRequest(Request request);
}

public class Request
{
  public int Day;
  public string Reason;
  public Request(int day, string reason)
  {
    Day = day;
    Reason = reason;
  }
}

2.具体处理者角色,如果有下家且条件不满足自身处理条件,就将请求传给下家,否则就处理请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class PM:Handler
{
public PM(string name): base(name){ }

public override bool PassRequest(Request request)
{
int day = request;
if (day <= 0.5)
{
return true;
}

return Successor.PassRequest(request);
}

}

class HR:Handler
{
public HR(string name): base(name){ }

public override bool PassRequest(Request request)
{
int day = request.Day;
string reason = request.Reason;
if (day > 0.5&&day<=2)
{
return true;
}

return Successor.PassRequest(request);
}
}


class Manager : Handler
{
public Manager(string name): base(name){ }

public override bool PassRequest(Request request)
{
return true;
}
}

3.具体调用:

1
2
3
4
5
6
7
Request request = new Request(3, "非正当理由");
Boss pm = new PM("pm");
Boss hr = new HR("hr");
Boss manager = new Manager("manager");
pm.Successor = hr;
hr.Successor = manager;
bool pass = pm.PassRequest(request);

设计模式之代理模式

定义:一个类代表另一个类的功能。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。通过一个中间层完成两个模块之间的交互。

通过上面的图片,我们可以看到,通过增加代理来解耦A与C之间的调用,这样可以封装原来C调用A的一些相关细节,转换成C直接调用B中封装后
的代理方法,则等同于访问A。

优点: 1、职责清晰。 2、高扩展性。 3、智能化。
缺点:1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

使用:以下案例通过代理类ProxyImage实现对实体类的一些操作。代理类需要和实体类继承自同一个接口
1.创建图片接口:

public interface Image
{
void display();
}
2.创建实现接口的实体类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class RealImage implements Image 
{
private String fileName;
public RealImage(String fileName)
{
this.fileName = fileName;
loadFromDisk(fileName);
}

public Override void display() {
System.out.println("Displaying " + fileName);
}

private void loadFromDisk(String fileName){
System.out.println("Loading " + fileName);
}
}

public class ProxyImage implements Image{
private RealImage realImage;
private String fileName;

public ProxyImage(String fileName){
this.fileName = fileName;
}

public Override void display() {
if(realImage == null){
realImage = new RealImage(fileName);
}
realImage.display();
}
}

3.当被请求时,使用 ProxyImage 来获取 RealImage 类的对象。

Image image = new ProxyImage(“test_10mb.jpg”);
image.display();

设计模式之享元模式-对象池

定义:复用我们内存中已存在的对象,降低系统创建、销毁对象实例的性能消耗。
对象池:
1、根据对象类型动态的创建对象实例。
2、根据对象池中的配置,在对象池中找到空闲的实体提供给程序调用,减少创建对象的次数。
3、我们需要设计每个类型的缓冲池,通过把对象进行缓存,提供性能。如果对象池中的对象长期不会调用,那么我们会提供一个销毁对象的机制。

优点:通过共享对象节省总体资源。
使用:以下例子创建一个子弹的复用机制,使子弹不用频繁创建。
1.创建子弹的接口及实体类:

1
2
3
4
5
6
7
8
9
public interface IBullet
{

}

public class Bullet : IBullet
{

}

2.创建子弹的复用管理类:子弹销毁时调用CollectBullet,创建时调用GetBullet。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class BulletControl
{
public List<Bullet> BulletList = new List<Bullet>();

public void CollectBullet(Bullet bullet)
{
     bullet.SetActive(false);
BulletList.Add(bullet);
}
public Bullet GetBullet()
{
if (BulletList.Count == 0)
{
return new Bullet();
}
else
{
Bullet b = BulletList[0];
BulletList.Remove(b);
       b.SetActive(false);
return b;
}
}
}

设计模式之装饰者模式

定义:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
角色:
Component:抽象构件角色,定义一个抽象接口,以规范准备接收附加责任的对象。
ConcreteComponent:具体组件,这是被装饰者,定义一个将要被装饰增加功能的实体
Decorator:装饰角色,持有一个构件对象的实例,并定义了抽象构件定义的接口。
ConcreteDecorator:负责给构件添加增加的功能。

优点:在不想增加很多子类的情况下扩展类。
缺点:多层装饰比较复杂。

使用:开发一个简单的播放器,我们通过第一次装饰可以为播放器增加播放音乐的功能,具体包括播放所有的音频格式文件,通过第二次装饰,我们可以为这个播放器添加播放视频格式文件的功能。

1.Compenent接口定义:

public interface IPlayer
{
void Play();
}
2.被装饰者ConCreatCompenent实现:

1
2
3
4
5
6
7
public class Player : IPlayer 
{
public void Play()
{
throw new NotImplementedException();
}
}

3.装饰器接口Decorator实现:

public interface IDecorator : IPlayer
{
}
4.装饰器的抽象基类Decorator实现:

1
2
3
4
5
6
7
8
9
public abstract class DecoratorBase : IDecorator 
{
protected IPlayer play = null;
public DecoratorBase(IPlayer player)
{
this.play = player;
}
public abstract void Play();
}

5.音乐播放器装饰器 和视频播放器装饰类 ConcreteDecorator实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MusicDecorator : DecoratorBase 
{
public MusicDecorator(IPlayer play)
: base(play)
{
}
public override void Play()
{
throw new NotImplementedException();
}
}
p ublic class VedioDecorator : DecoratorBase
{
public VedioDecorator(IPlayer play)
: base(play)
{
}
public override void Play()
{
throw new NotImplementedException();
}
}

6.具体调用:由于装饰角色传入一个构件对象的实例,所以装饰的对象的装饰可以精确到具体的装饰角色。

1
2
3
4
5
6
static void Main(string[] args) 
{
IPlayer play = new Player();
play = new MusicDecorator(play);
play = new VedioDecorator(play);
}

设计模式之桥接模式

定义:将抽象部分与实现部分分离,使它们都可以独立的变化。桥接模式的主要目的是将一个对象的变化因素抽象出来,不是通过类继承的方式来满足这个因素的变化,而是通过对象组合的方式来依赖因素的抽象,这样当依赖的因素的具体实现发生变化后,而我们的具体的引用却不用发生改变,因为我们的对象是依赖于抽象的,而不是具体的实现。

结构图:

1.创建桥接实现接口:

public interface DrawAPI
{
public void drawCircle(int radius, int x, int y);
}
2.创建实现了 DrawAPI 接口的实体桥接实现类:

1
2
3
4
5
6
public class GreenCircle implements DrawAPI 
{
public Override void drawCircle(int radius, int x, int y)
{
}
}

3.使用 DrawAPI 接口创建抽象类 Shape:

1
2
3
4
5
6
7
8
9
public abstract class Shape 
{
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI)
{
this.drawAPI = drawAPI;
}
public abstract void draw();
}

4.创建实现了 Shape 接口的实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Circle extends Shape 
{
private int x, y, radius;

public Circle(int x, int y, int radius, DrawAPI drawAPI) {
super(drawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}

public void draw() {
drawAPI.drawCircle(radius,x,y);
}
}

设计模式之适配器模式

定义:两个不兼容的接口之间的桥梁,这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

角色:
1.Target:定义Client使用的与特定领域相关的接口;
2.Adaptee:现在需要适配的已经存在的接口;
3.Adapter:对Adaptee 的接口与Target接口进行适配

优点:适配器模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
使用:以下案例实现:旧系统中提供一个查询服务方法Query();但是我新系统定义底层的数据访问服务层的时候,却是使用的GetList()方法,通过适配器完成在新系统GetList()时调用并返回旧系统的Query();。

1.旧系统的查询服务:

1
2
3
4
5
6
7
  public class Query :IQuery 
{
public object Query()
{
return new object();
}
}

2.新系统的的查询服务接口:

public interface ISelect
{
object GetList();
}
3.通过类适配器完成转配操作:

1
2
3
4
5
6
7
public class QueryAdapter : Query, ISelect 
{
public object GetList()
{
return base.Query();
}
}

4.通过对象适配器完成转配操作:

1
2
3
4
5
6
7
8
public class QueryAdapter :  ISelect 
{
private Query query = new Query();
public object GetList()
{
return query.Query();
}
}

对象适配器:不是通过继承的方式,而是通过对象组合的方式来进行处理的,我们只要学过OO的设计原则的都知道,组合相比继承是推荐的方式。
类适配器:通过继承的方式来实现,将旧系统的方法进行封装。对象适配器在进行适配器之间的转换过程中,无疑类适配器也能完成,但是依赖性会加大,并且随着适配要求的灵活性,可能通过继承膨胀的难以控制。 一般来说类适配器的灵活性较差,对象适配器较灵活,是我们推荐的方式,可以通过依赖注入的方式,或者是配置的方式来做。类适配器需要继承自要适配的旧系统的类,无疑这不是一个好的办法。