看的過程中,發現好多模式都用過,只是沒有總結,或者是不知道叫這個名字吧··· 這裡列舉結構型模式,適配器、橋接、過濾、組合、裝飾器、外觀、享元、代理, 適配器模式:將現存的對象放到新的環境裡邊去,但是介面不一樣,其實就是添加一個類把新的介面包裝一樣 之前公司的wcf服務端就是這種模式,公司很多部門, ...
看的過程中,發現好多模式都用過,只是沒有總結,或者是不知道叫這個名字吧···
這裡列舉結構型模式,適配器、橋接、過濾、組合、裝飾器、外觀、享元、代理,
適配器模式:將現存的對象放到新的環境裡邊去,但是介面不一樣,其實就是添加一個類把新的介面包裝一樣
之前公司的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(); } } }