在结构型模式中包含七种模式:适配器模式、装饰模式、桥接模式、组合模式、享元模式、代理模式、外观模式。
6. 适配器模式
将一个类的接口转换为客户希望的一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。相当于一个翻译的作用(就像姚明开始不会英语在国外打球,需要一个翻译作为适配器)
UML图:
代码
//17.4找个篮球翻译当适配器——中间调节作用
namespace 适配器
{
class Class1
{
static void Main(string[] args)
{
Player b = new ForWards("巴蒂尔");
b.Attack();
Player m = new Guards("麦蒂");
m.Attack();
//Player ym = new Center("姚明");
Player ym = new Translator("姚明"); //外籍中锋
ym.Attack();
ym.Defense();
Console.Read();
}
}
abstract class Player //球员
{
protected string name;
public Player(string name)
{
this.name = name;
}
public abstract void Attack();
public abstract void Defense();
}
class ForWards : Player //前锋
{
public ForWards(string name)
: base(name)
{ }
public override void Attack()
{
Console.WriteLine("前锋{0}进攻",name );
}
public override void Defense()
{
Console.WriteLine("前锋{0}防守",name );
}
}
class Center : Player //中锋
{
public Center(string name)
: base(name)
{ }
public override void Attack()
{
Console.WriteLine("中锋{0}进攻",name );
}
public override void Defense()
{
Console.WriteLine("中锋¤0}防守",name );
}
}
class Guards : Player //后¨®卫¨¤
{
public Guards(string name)
: base(name)
{ }
public override void Attack()
{
Console.WriteLine("后卫{0}防守",name );
}
public override void Defense()
{
Console.WriteLine("后卫{0}进攻",name );
}
}
//外籍中锋
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 );
}
}
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.进攻();
}
}
}
7. 装饰模式
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。装饰最后形成的是一个对象链,下一个装饰上一个,下一个被下下一个装饰(就像一杯白开水,加入白糖装饰之后还可以用加入咖啡装饰,之后还可以在加入茶叶装饰,之后还可以加入……形成一个链)
UML图
代码:
namespace 装饰模式
{
class Class3
{
static void Main(string[] args)
{
Person2 xc = new Person2("小菜");
Console.WriteLine("\n第一种装扮");
Sneakers2 pqx = new Sneakers2();
BigTrouser2 kk = new BigTrouser2();
TShirts2 dtx = new TShirts2();
pqx.Decorate(xc); //一条龙式的装扮,装扮有先后顺序
kk.Decorate(pqx );
dtx.Decorate(kk);
dtx.Show();
Console.WriteLine("\n第二种装扮");
LeatherShoes2 px = new LeatherShoes2();
Tie2 ld = new Tie2();
Suit2 xz = new Suit2();
px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();
Console.WriteLine("\n第三种装扮");
Sneakers2 pqx2 = new Sneakers2();
LeatherShoes2 px2 = new LeatherShoes2();
BigTrouser2 kk2 = new BigTrouser2();
Tie2 ld2 = new Tie2();
pqx2.Decorate(xc);
px2.Decorate(pqx);
kk2.Decorate(px2);
ld2.Decorate(kk2);
ld2.Show();
Console.Read();
}
}
class Person2
{
public Person2()
{ }
private string name;
public Person2(string name)
{
this.name = name;
}
public virtual void Show()
{
Console.WriteLine("装扮的{0}",name );
}
}
class Finery2 : Person2 //装饰抽象类
{
protected Person2 component;
public void Decorate(Person2 component)
{
this.component = component;
}
public override void Show()
{
if (component != null)
{
component.Show();
}
}
}
//具体装饰类
class TShirts2 : Finery2
{
public override void Show()
{
Console.Write("大体恤");
base.Show();
}
}
class Sneakers2 : Finery2
{
public override void Show()
{
Console.Write("大裤衩");
base.Show();
}
}
class BigTrouser2 : Finery2
{
public override void Show()
{
Console.Write("垮裤");
base.Show();
}
}
class LeatherShoes2 : Finery2
{
public override void Show()
{
Console.Write("西装");
base.Show();
}
}
class Tie2 : Finery2
{
public override void Show()
{
Console.Write("领带");
base.Show();
}
}
class Suit2 : Finery2
{
public override void Show()
{
Console.Write("皮鞋");
base.Show();
}
}
}
8. 桥接模式
将抽象部分与它的实现部分分离,使它们都可以独立地变换。核心意图就是将这些实现独立出来,让他们各自变化,使得每种变化不会影响其他的变化,从而达到应对变化的目的(就adidas和NIKE两个品牌与服装之间桥接起来)
UML图:
代码:
//桥接模式——将抽象部分(手机品牌)和实现部分(手机软件)分离开使他们可以独立的变化
namespace 桥接模式
{
class Class2
{
static void Main(string[] args)
{
HandsetBrand1 ab;
ab = new HandsetBrandN1();
ab.SetHandsetSoft(new HandsetGame1());
ab.Run();
ab.SetHandsetSoft(new HandsetAddressList());
ab.Run();
ab = new HandsetBrandM1();
ab.SetHandsetSoft(new HandsetGame1());
ab.Run();
ab.SetHandsetSoft(new HandsetAddressList());
ab.Run();
Console.Read();
}
}
abstract class HandsetSoft //手机软件
{
public abstract void Run();
}
class HandsetGame1 : HandsetSoft //手机游戏
{
public override void Run()
{
Console.WriteLine("运行手机游戏");
}
}
class HandsetAddressList : HandsetSoft //手机通讯录
{
public override void Run()
{
Console.WriteLine("运行手机通讯录");
}
}
abstract class HandsetBrand1 //手机品牌
{
protected HandsetSoft soft;
//设置手机软件
public void SetHandsetSoft(HandsetSoft soft)
{
this.soft = soft;
}
//运行
public abstract void Run();
}
class HandsetBrandN1 : HandsetBrand1 //手机品牌N
{
public override void Run()
{
soft.Run();
}
}
class HandsetBrandM1 : HandsetBrand1 //手机品牌M
{
public override void Run()
{
soft.Run();
}
}
//新增一个手机MP3播放器软件
class HandsetMP3 : HandsetSoft
{
public override void Run()
{
Console.WriteLine("运行手机MP3播放器");
}
}
//新增手机品牌S
class HandsetBrandS : HandsetBrand1
{
public override void Run()
{
soft.Run();
}
}
}
9. 组合模式
将对象形成树形结构以表示“部分—整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。在需求中体现部分和整体的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑使用组合模式。,组合对象可以不断的递归下去。组合模式让用户可以一致地使用组合结构和单个对象。(就像树——树枝、树叶的关系,树枝就是一个组合对象,树叶是单个对象)
UML图:
代码:
namespace 组合模式
{
class Class1
{
static void Main(string[] args)
{
ConcreateCompany root = new ConcreateCompany("北京总公司");
root.Add(new HRDepartment("总公司人力资源部"));
root.Add(new FinanceDepartment("总公司财务部"));
ConcreateCompany comp = new ConcreateCompany("上海华东分公司");
comp.Add(new HRDepartment("华东分公司人力资源部"));
comp.Add(new FinanceDepartment("华东分公司财务部"));
root.Add(comp );
ConcreateCompany comp1 = new ConcreateCompany("南京办事处");
comp1.Add(new HRDepartment("南京办事处人力资源部"));
comp1.Add(new FinanceDepartment("南京办事处财务部"));
comp.Add(comp1);
ConcreateCompany comp2 = new ConcreateCompany("杭州办事处");
comp2.Add(new HRDepartment("杭州办事处人力资源部"));
comp2.Add(new FinanceDepartment("杭州办事处财务部"));
comp.Add(comp2);
Console.WriteLine("\n结构图:");
root.Display(1);
Console.WriteLine("\n职责");
root.LineOfDuty();
Console.Read();
}
}
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 ConcreateCompany : Company //具体公司类树枝节点
{
private List children = new List();
public ConcreateCompany(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 );
}
}
}
10. 享元模式
运用共享技术有效地支持大量细粒度的对象。如果一个应用使用了大量的对象,而大量的这些对象造成很大的存储开销应该考虑使用享元模式。享元模式可以避免大量非常相似类的开销,如果发现一些实例除了几个参数外基本相同,可以大大减少需要实例化的类的数量,,把参数移到类实例的外面,方法调用是传递进去。(比如在一个汽车4S店,通过id可以查到汽车的信息,第一次查BMW 730会返回数据库宝马730的配置信息,第二次查得时候先从上次查得缓存中找,没有再找数据库,其实就是缓存的意思)
UML图:
代码:
using System.Collections; //引用哈希表
namespace 享元模型
{
class Class1
{
static void Main(string[] args)
{
int extrinsicstate = 22;
FlyweightFactory f = new FlyweightFactory();
Flyweight fx = f.GetFlyweight("X");
fx.Operation(--extrinsicstate );
Flyweight fy = f.GetFlyweight("Y");
fy.Operation(--extrinsicstate );
Flyweight fz = f.GetFlyweight("Z");
fz.Operation(--extrinsicstate);
Flyweight uf = new UnsharedConcreteFlyweight();
uf.Operation(--extrinsicstate );
Console.Read();
}
}
abstract class Flyweight
{
//具体类和享元类的接口
public abstract void Operation(int extrinsicstate);
}
class ConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("具体Flyweight:"+extrinsicstate );
}
}
class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
}
}
class FlyweightFactory //享元工厂
{
private Hashtable flyweights = new Hashtable(); //哈希表
public FlyweightFactory()
{
flyweights.Add("X",new ConcreteFlyweight());
flyweights.Add("Y", new ConcreteFlyweight());
flyweights.Add("Z", new ConcreteFlyweight());
}
public Flyweight GetFlyweight(string key)
{
return ((Flyweight )flyweights[key]);
}
}
}
11. 代理模式
为其他对象提供一种代理以控制对这个对象的访问。代理就是真实对象的代表。(例如代理别人去追一个女生)
UML图:
代码:
namespace 代理模式
{
class Class2
{
static void Main(string[] args)
{
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.Name = "李娇娇";
Proxy1 daili = new Proxy1(jiaojiao);
daili.GiveDolls();
daili.GiveFlowers();
daili.GiveChocolate();
Console.ReadLine();
}
}
interface IGiveGift //追求者(真实实体)和代理的接口,代理和真实实体有相同的功能
{
void GiveDolls();
void GiveFlowers();
void GiveChocolate();
}
class Pursuit1 : IGiveGift //追求者(真实实体)
{
SchoolGirl mm;
public Pursuit1(SchoolGirl mm)
{
this.mm = mm;
}
public void GiveDolls()
{
Console.WriteLine(mm.Name +"送你洋娃娃");
}
public void GiveFlowers()
{
Console.WriteLine(mm.Name+"送你鲜花");
}
public void GiveChocolate()
{
Console.WriteLine(mm.Name +"送你巧克力");
}
}
class Proxy1 : IGiveGift //代理
{
Pursuit1 gg;
public Proxy1(SchoolGirl mm)
{
gg = new Pursuit1(mm);
}
public void GiveDolls()
{
gg.GiveDolls();
}
public void GiveFlowers()
{
gg.GiveFlowers();
}
public void GiveChocolate()
{
gg.GiveChocolate();
}
}
}
12. 外观模式
为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。增加外观可以提供一个简单的接口,减少他们之间的依赖。通过接口可以实现一系列已经封装好的方法。(比如我们身边的移动公司,10086的客服就扮演着一个外观的角色,通过它你可以办理你需要的若干个业务)
UML图:
代码:
//外观模式将不同的层之间进行分离,层与层之间建立外观,为复杂的子系统提供一个简单的接口,耦合性大大降低
namespace 外观模式
{
class Class2
{
static void Main(string[] args)
{
Facde facde = new Facde();
facde.MethodA(); //有外观类的作用,客户可以不知道子系统的作用而通过外观类进行调用(就像基金一样,基金是由若干支股票组成的)
facde.MethodB();
Console.Read();
}
}
//四个子系统类
class SubSystemOne
{
public void MethodOne()
{
Console.WriteLine("子系统方法1");
}
}
class SubSystemTwo
{
public void MethodTwo()
{
Console.WriteLine("子系统方法2");
}
}
class SubSystemThree
{
public void MethodThree()
{
Console.WriteLine("子系统方法3");
}
}
class SubSystemFour
{
public void MethodFour()
{
Console.WriteLine("子系统方法4");
}
}
//外观类
class Facde
{
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
SubSystemFour four;
public Facde()
{
one = new SubSystemOne();
two = new SubSystemTwo();
three = new SubSystemThree();
four = new SubSystemFour();
}
public void MethodA()
{
Console.WriteLine("\n方法组A()——");
one.MethodOne();
two.MethodTwo();
four.MethodFour();
}
public void MethodB()
{
Console.WriteLine("\n方法组B()——");
two.MethodTwo();
three.MethodThree();
}
}
}