结构型模式:
适配器模式
将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.
主要解决的问题:
简单的说,就是需要的东西就在面前,但却不能使用,而短时间又无法改造它,于是我们就想办法适配它
在软件开发中,也就是系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配.适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况.
应用:
两个类所做的事情相同或相似,但是具有不同的接口时要使用它,就应该考虑用适配器模式
课本实例:在NBA我需要翻译
代码如下:
//翻译者类
class Translator : Player
{
//声明并实例化一个内部的外籍中锋对象,表明翻译者与外籍球员有关联
private ForeignCenter wjzf = new ForeignCenter();
public Translator(string name)
: base(name)
{
wjzf.Name = name;
}
public override void Attack()
{
wjzf.进攻();
}
public override void Defense()
{
wjzf .防守 ();
}
}
//外籍中锋
class ForeignCenter
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public void 进攻()
{
Console.WriteLine("中锋{0}进攻", name);
}
public void 防守()
{
Console.WriteLine("中锋{0}防守", name);
}
}
桥接模式
将抽象部分与它的实现部分分离,使它们都可以独立地变化
实现指的是和它的派生类用来实现自己的对象。就例子而言,就是让“手机”既可以按照品牌来分类又可以按照功能来分类。由于实现的方式多种,桥接模式的核心意图就是把这些实现独立出来,让它们各自地变化。
实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。
应用:
那么什么时候使用桥接模式呢?当系统可以从多个角度分类,每一种分类都有可能变化,那么就把这种多角度分类分离出来让他们独立变化,这样就可以减少他们之间的耦合。
课本实例:手机品牌和手机软件的关系
如图:
代码如下:
//手机软件
abstract class HandsetSoft
{
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();
}
//品牌N 品牌M具体类
class HandsetBrandN : HandsetBrand
{
public override void Run()
{
soft.Run ();
}
}
class HandsetBrandM : HandsetBrand
{
public override void Run()
{
soft.Run ();
}
}
组合模式
将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑用组合模式了
组合模式结构图:
课本实例:公司-分公司
代码如下:
//公司类,抽象类 接口
abstract class Company
{
protected string name;
public Company(string name)
{
this.name = name;
}
public abstract void Add(Company c);//增加
public abstract void Remove(Company c);//移除
public abstract void Display(int depth);//显示
public abstract void LineOfDuty();//履行职责
}
//具体公司类 树枝节点
class ConcreteCompany : Company
{
private List<Company> children = new List<Company>();
public ConcreteCompany(string name)
: base(name)
{ }
public override void Add(Company c)
{
children .Add(c);
}
public override void Remove(Company c)
{
children .Remove (c);
}
public override void Display(int depth)
{
Console.WriteLine (new string ('-',depth )+name );
foreach (Company component in children )
{
component.Display (depth + 2);
}
}
//履行职责
public override void LineOfDuty()
{
foreach (Company component in children)
{
component.LineOfDuty();
}
}
}
//人力资源部与财务部类
class HRDepartment : Company
{
public HRDepartment(string name)
: base(name)
{ }
public override void Add(Company c)
{
}
public override void Remove(Company c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + name);
}
public override void LineOfDuty()
{
Console.WriteLine("{0}员工招聘培训管理", name);
}
}
class FinanceDepartment : Company
{
public FinanceDepartment(string name)
: base(name)
{ }
public override void Add(Company c)
{
}
public override void Remove(Company c)
{
}
public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + name);
}
public override void LineOfDuty()
{
Console.WriteLine("{0}公司财务收支管理", name);
}
}
优点:
用户不需要关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而写一些选择判断语句了