首页 > 代码库 > c#设计模式·结构型模式
c#设计模式·结构型模式
看的过程中,发现好多模式都用过,只是没有总结,或者是不知道叫这个名字吧···
这里列举结构型模式,适配器、桥接、过滤、组合、装饰器、外观、享元、代理,
适配器模式:将现存的对象放到新的环境里边去,但是接口不一样,其实就是添加一个类把新的接口包装一样
之前公司的wcf服务端就是这种模式,公司很多部门,不同部门不同的业务都有自己相应的服务,之前是分开的,用的服务多的时候开服务很麻烦,现在想把他们统一起来,就可以用这种方式,wcf服务以接口定义契约,在实现类中写具体业务,可以定义一个统一的空接口,然所有的wcf接口都继承该空接口,然后统一后的类通过适配器构造相应的服务对象,然后加载,适配器里边可以通过统一的空接口反射获取对象,也可以直接通过不同服务的程序集名及类名获取对象,这样连统一接口都不用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExercisePrj.Dsignmode { //统一接口 public interface IMediaPlayer { void Play(string audioType, string filename); } //播放接口 public interface IAdvanceMediaPlayer { void PlayVlc(string filename); void PlayMp4(string filename); } public class VlcPlayer :IAdvanceMediaPlayer { public void PlayVlc(string filename) { Console.WriteLine("play vlc"); } public void PlayMp4(string filename) { } } public class Mp4Player:IAdvanceMediaPlayer { public void PlayVlc(string filename) { } public void PlayMp4(string filename) { Console.WriteLine("play mp4"); } } //适配器类 public class MediaAdapter : IMediaPlayer { IAdvanceMediaPlayer advancedMusicPlayer; public MediaAdapter(String audioType) { if (audioType=="vlc") { advancedMusicPlayer = new VlcPlayer(); } else if (audioType=="mp4") { advancedMusicPlayer = new Mp4Player(); } } public void Play(String audioType, String fileName) { if (audioType=="vlc") { advancedMusicPlayer.PlayVlc(fileName); } else if (audioType=="mp4") { advancedMusicPlayer.PlayMp4(fileName); } } } //实体类 public class AutoPaly : IMediaPlayer { MediaAdapter mediaAdapter; public void Play(String audioType, String fileName) { if (audioType == "mp3") { Console.WriteLine("play mp3"); } else if (audioType == "vlc" || audioType == "mp4") { mediaAdapter = new MediaAdapter(audioType); mediaAdapter.Play(audioType, fileName); } else { Console.WriteLine("invalid mediatype"); } } } }
桥接模式:将抽象部分和实现部分分离,使他们可以独立变化,就是吧具体操作再抽象成接口,然后实现该接口,通过关联关系吧操作和实体结合,构造实体的时候根据情况构造对应的操作的实现类,传给实体
这玩意对抽象的设计要求有点高,一不小心就得跪
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExercisePrj.Dsignmode { //桥接接口 public interface IDrawAPI { void DrawCircle(int radius, int x, int y); } //具体实现 public class GreenCircle:IDrawAPI { public void DrawCircle(int radius,int x,int y) { Console.WriteLine("draw green circle"); } } public class RedCircle : IDrawAPI { public void DrawCircle(int radius, int x, int y) { Console.WriteLine("draw red circle,x{0},y{1}",x,y); } } //实体抽象基类 public abstract class ShapeEx { protected IDrawAPI drawAPI; protected ShapeEx(IDrawAPI drawAPI) { this.drawAPI = drawAPI; } public abstract void Draw(); } //继承实体实现类 public class CircleEx : ShapeEx { public int x { get; set; } public int y { get; set; } public int radius { get; set; } private string color; //演示实现享元模式的构造函数 public CircleEx(string color):base(null) { this.color = color; drawAPI = new RedCircle(); } public CircleEx(int x, int y, int radius,IDrawAPI drawapi ):base(drawapi) { this.x = x; this.y = y; this.radius = radius; } public override void Draw() { drawAPI.DrawCircle(radius, x, y); } } }
过滤器模式:允许开发人员使用不同的标准过滤一组对象,通过逻辑运算以解耦的方式把他们连接起来,讲道理没看懂这模式有啥卵用,就是整了个过滤接口·然后用不同的实现继承该接口提一堆对象出来···这提了干啥··
这例子里边的直接用C#的linq扩展方法简单几句话就可以实现额。。。搞不懂··
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExercisePrj.Dsignmode { //实体 public class Person { public string Name { get; } public string Gender { get; } public string MaritalStatus { get; } public Person(string name,string gender,string maritalstatus) { Name = name; Gender = gender; MaritalStatus = maritalstatus; } } //过滤标准接口 public interface ICriteria { List<Person> MeetCriteria(List<Person> persons); } //不同标准实现 public class CriteriaMale:ICriteria { public List<Person> MeetCriteria(List<Person> persons) { List<Person> maleCriterial = new List<Person>(); foreach(var p in persons) { if(p.Gender=="male") { maleCriterial.Add(p); } } return maleCriterial; } } public class CriteriaFemale : ICriteria { public List<Person> MeetCriteria(List<Person> persons) { List<Person> femaleCriterial = new List<Person>(); foreach (var p in persons) { if (p.Gender == "female") { femaleCriterial.Add(p); } } return femaleCriterial; } } public class CriteriaSingle : ICriteria { public List<Person> MeetCriteria(List<Person> persons) { List<Person> Criterialsingle = new List<Person>(); foreach (var p in persons) { if (p.MaritalStatus == "Single") { Criterialsingle.Add(p); } } return Criterialsingle; } } public class AndCriteria : ICriteria { private ICriteria criteria; private ICriteria otherCriteria; public AndCriteria(ICriteria criteria, ICriteria otherCriteria) { this.criteria = criteria; this.otherCriteria = otherCriteria; } public List<Person> MeetCriteria(List<Person> persons) { List<Person> firstCriteriaPersons = criteria.MeetCriteria(persons); return otherCriteria.MeetCriteria(firstCriteriaPersons); } } public class OrCriteria :ICriteria { private ICriteria criteria; private ICriteria otherCriteria; public OrCriteria(ICriteria criteria, ICriteria otherCriteria) { this.criteria = criteria; this.otherCriteria = otherCriteria; } public List<Person> MeetCriteria(List<Person> persons) { List<Person> firstCriteriaItems = criteria.MeetCriteria(persons); List<Person> otherCriteriaItems = otherCriteria.MeetCriteria(persons); foreach (Person p in otherCriteriaItems) { if (!firstCriteriaItems.Contains(p)) { firstCriteriaItems.Add(p); } } return firstCriteriaItems; } } }
组合模式:又叫部分整体模式,有些实体存在可能的树形结构,就用这种模式,这个其实用的比较多,比如用仪器测数据,有些仪器一次就一个仪器就可以了,有些仪器可能需要几个仪器组合起来才能测,还有公司里的雇员结构也是这样的
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExercisePrj.Dsignmode { public class Employee { private String name; private String dept; private int salary; private List<Employee> subordinates; public Employee(String name, String dept, int sal) { this.name = name; this.dept = dept; this.salary = sal; subordinates = new List<Employee>(); } public void add(Employee e) { subordinates.Add(e); } public void remove(Employee e) { subordinates.Remove(e); } public List<Employee> getSubordinates() { return subordinates; } public override string ToString() { return ("Employee :[ Name : " + name+ ", dept : " + dept + ", salary :" + salary + " ]"); } } }
装饰器模式,向现有的对象添加新的功能,不改变原有结构,这玩意就是C#的扩展方法的应用场景额。。。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExercisePrj.Dsignmode { //装饰抽象类 public abstract class ShapeDecorator : IShape { protected IShape decoratedShape; public ShapeDecorator(IShape decoratedShape) { this.decoratedShape = decoratedShape; } public virtual void Draw() { decoratedShape.Draw(); } } //装饰实现类 public class RedShapeDecorator : ShapeDecorator { public RedShapeDecorator(IShape decoratedShape):base(decoratedShape) { } public override void Draw() { decoratedShape.Draw(); setRedBorder(decoratedShape); } private void setRedBorder(IShape decoratedShape) { Console.WriteLine("Border Color: Red"); } } //用扩展方法的方式直接实现 public static class ShapeExpend { public static void SetColor(this IShape shape) { Console.WriteLine("border Color: Red"); } } }
外观模式:就是用个类把一些复杂的功能包装一下··很多地方都有这个的体现··mvc传统的三层架构都是这玩意的体现···
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExercisePrj.Dsignmode { //外观类 public class ShapeMaker { private IShape circle; private IShape line; public ShapeMaker() { circle = new Circle(); line = new Line(); } public void drawCircle() { circle.Draw(); } public void drawLine() { line.Draw(); } } }
享元模式:用于减少创建对象,减少内存和提高性能,就是缓存用过的对象,下次要用就在里边找,没有就新建添加··,没用过···,可能是没做过大型的项目···
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExercisePrj.Dsignmode { //享元模式的工厂类 public class ShapeFlyweight { private static readonly Dictionary<string, ShapeEx> circleMap = new Dictionary<string, ShapeEx>(); public static ShapeEx getCircle(string color) { CircleEx circle; if (!circleMap.Keys.Contains(color)) { circle = new CircleEx(color); circleMap.Add(color, circle); Console.WriteLine("Creating circle of color : " + color); return circle; } else { circle=(CircleEx)circleMap[color]; } return circle; } } }
代理模式:相当于在类外边加壳,各种代理都是该模式的体现···主要是为了控制外界对类的操作吧。
博客园这个添加代码窗体里边的那个提交按钮没有做多次点击处理···点快点可以提交几次·····
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExercisePrj.Dsignmode { public interface IImage { void Display(); } public class RealImage:IImage { private string filename; public RealImage(string filename) { this.filename = filename; loadfile(filename); } public void Display() { Console.WriteLine("display:"+filename); } private void loadfile(string filename) { Console.WriteLine("loadfile"); } } //代理类 public class ProxyImage : IImage { private RealImage realImage; private String fileName; public ProxyImage(String fileName) { this.fileName = fileName; } public void Display() { if (realImage == null) { realImage = new RealImage(fileName); } realImage.Display(); } } }
c#设计模式·结构型模式