/// <summary> /// 适配器模式 Adapter PatternA /// geovindu, Geovin Du edit /// </summary> interface IRectangle { void AboutMe(); } /// <summary> /// /// </summary> class Rectangle : IRectangle { public void AboutMe() { Console.WriteLine("Actually, I am a Rectangle(三角形)."); } } /// <summary> /// /// </summary> interface ITriangle { void AboutTriangle(); } /// <summary> /// /// </summary> class Triangle : ITriangle { public void AboutTriangle() { Console.WriteLine("Actually, I am a Triangle(矩形)."); } } /* * RectangleAdapter is implementing IRectangle. * So, it needs to implement all the methods * defined in the target interface. */ /// <summary> /// /// </summary> class RectangleAdapter : Triangle, IRectangle { public void AboutMe() { //Invoking the adaptee method //For Q&A //Console.WriteLine("You are using an adapter now."); AboutTriangle(); } }
/// <summary> /// 适配器模式 Adapter PatternA /// geovindu, Geovin Du edit /// </summary> public interface ICommand { void Execute(); } /// <summary> /// /// </summary> public class SaveCommand : ICommand { public void Execute() { Console.WriteLine("Saving current file"); } } /// <summary> /// /// </summary> public class OpenCommand : ICommand { public void Execute() { Console.WriteLine("Opening a file"); } } /// <summary> /// /// </summary> public class Button { private ICommand command; private string name; public Button(ICommand command, string name) { this.command = command; this.name = name; } public void Click() { command.Execute(); } public void PrintMe() { Console.WriteLine($"I am a button called {name}"); } } /// <summary> /// /// </summary> public class Editor { public IEnumerable<Button> Buttons { get; } public Editor(IEnumerable<Button> buttons) { Buttons = buttons; } public void ClickAll() { foreach (var btn in Buttons) { btn.Click(); } } }
/// <summary> /// 适配器模式 Adapter PatternA /// geovindu, Geovin Du edit /// </summary> public interface IInteger { int Value { get; } } /// <summary> /// /// </summary> public static class Dimensions { public class Two : IInteger { public int Value => 2; } public class Three : IInteger { public int Value => 3; } } /// <summary> /// /// </summary> /// <typeparam name="TSelf"></typeparam> /// <typeparam name="T"></typeparam> /// <typeparam name="D"></typeparam> public abstract class Vector<TSelf, T, D> where D : IInteger, new() where TSelf : Vector<TSelf, T, D>, new() { protected T[] data; public Vector() { data = new T[new D().Value]; } public Vector(params T[] values) { var requiredSize = new D().Value; data = new T[requiredSize]; var providedSize = values.Length; for (int i = 0; i < Math.Min(requiredSize, providedSize); ++i) data[i] = values[i]; } public static TSelf Create(params T[] values) { var result = new TSelf(); var requiredSize = new D().Value; result.data = new T[requiredSize]; var providedSize = values.Length; for (int i = 0; i < Math.Min(requiredSize, providedSize); ++i) result.data[i] = values[i]; return result; } public T this[int index] { get => data[index]; set => data[index] = value; } public T X { get => data[0]; set => data[0] = value; } } /// <summary> /// /// </summary> /// <typeparam name="TSelf"></typeparam> /// <typeparam name="D"></typeparam> public class VectorOfFloat<TSelf, D> : Vector<TSelf, float, D> where D : IInteger, new() where TSelf : Vector<TSelf, float, D>, new() { } /// <summary> /// /// </summary> /// <typeparam name="D"></typeparam> public class VectorOfInt<D> : Vector<VectorOfInt<D>, int, D> where D : IInteger, new() { public VectorOfInt() { } public VectorOfInt(params int[] values) : base(values) { } public static VectorOfInt<D> operator + (VectorOfInt<D> lhs, VectorOfInt<D> rhs) { var result = new VectorOfInt<D>(); var dim = new D().Value; for (int i = 0; i < dim; i++) { result[i] = lhs[i] + rhs[i]; } return result; } } /// <summary> /// /// </summary> public class Vector2i : VectorOfInt<Dimensions.Two> { public Vector2i(params int[] values) : base(values) { } } /// <summary> /// /// </summary> public class Vector3f : VectorOfFloat<Vector3f, Dimensions.Three> { public override string ToString() { return $"{string.Join(",", data)}"; } }
/// <summary> /// /// </summary> public class CountryStats { [XmlIgnore] public Dictionary<string, string> Capitals { get; set; } = new Dictionary<string, string>(); public (string, string)[] CapitalsSerializable { get { return Capitals.Keys.Select(country => (country, Capitals[country])).ToArray(); } set { Capitals = value.ToDictionary(x => x.Item1, x => x.Item2); } } }
调用:
//适配器模式 Adapter Pattern Console.WriteLine("***适配器模式 Adapter Pattern Alternative Implementation Technique Demo.***\n"); IRectangle rectangle = new Rectangle(); Console.WriteLine("For initial verification purposes, printing the details from of both shapes."); Console.WriteLine("The rectangle.AboutMe() says:"); rectangle.AboutMe(); ITriangle triangle = new Triangle(); Console.WriteLine("The triangle.AboutTriangle() says:"); triangle.AboutTriangle(); Console.WriteLine("\nNow using the adapter."); IRectangle adapter = new RectangleAdapter(); Console.Write("True fact : "); adapter.AboutMe(); Console.WriteLine("*****************************"); // // for each ICommand, a Button is created to wrap it, and all // are passed to the editor var b = new ContainerBuilder(); b.RegisterType<OpenCommand>() .As<ICommand>() .WithMetadata("Name", "Open"); b.RegisterType<SaveCommand>() .As<ICommand>() .WithMetadata("Name", "Save"); //b.RegisterType<Button>(); //b.RegisterAdapter<ICommand, Button>(cmd => new Button(cmd, "")); b.RegisterAdapter<Meta<ICommand>, Button>(cmd => new Button(cmd.Value, (string)cmd.Metadata["Name"])); b.RegisterType<Editor>(); using var c = b.Build(); var editor = c.Resolve<Editor>(); editor.ClickAll(); // problem: only one button foreach (var btn in editor.Buttons) btn.PrintMe(); // var v = new Vector2i(1, 2); v[0] = 0; var vv = new Vector2i(3, 2); var result = v + vv; var u = Vector3f.Create(3.5f, 2.2f, 1); Console.WriteLine(u.ToString()); // var stats = new CountryStats(); stats.Capitals.Add("France", "Paris"); var xs = new XmlSerializer(typeof(CountryStats)); var stringBuilder = new StringBuilder(); var stringWriter = new StringWriter(stringBuilder); xs.Serialize(stringWriter, stats); //Clipboard.SetText(stringBuilder.ToString()); Console.WriteLine(stringBuilder.ToString()); var newStats = (CountryStats)xs.Deserialize( new StringReader(stringWriter.ToString())); Console.WriteLine(newStats.Capitals["France"]);
输出:
***适配器模式 Adapter Pattern Alternative Implementation Technique Demo.*** For initial verification purposes, printing the details from of both shapes. The rectangle.AboutMe() says: Actually, I am a Rectangle(三角形). The triangle.AboutTriangle() says: Actually, I am a Triangle(矩形). Now using the adapter. True fact : Actually, I am a Triangle(矩形). ***************************** Opening a file Saving current file I am a button called Open I am a button called Save 3.5,2.2,1 <?xml version="1.0" encoding="utf-16"?> <CountryStats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <CapitalsSerializable> <ValueTupleOfStringString> <Item1>France</Item1> <Item2>Paris</Item2> </ValueTupleOfStringString> </CapitalsSerializable> </CountryStats> Paris