zoukankan      html  css  js  c++  java
  • C# 设计模式·创建型模式

    面试问到这个··答不出来就是没有架构能力···这里学习一下···面试的时候直接让我说出26种设计模式··当时就懵逼了··我记得好像之前看的时候是23种的 还有3个是啥的···

    这里先列出几种创建型模式,工厂、抽象工厂、单例,建造者、原型,后续在更新

    工厂模式:缺点是每增加一个类型就得增加一个工具类和对象工厂类(反射可以避免修改这个···)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Reflection;
    
    namespace ExercisePrj.Dsignmode
    {
        public class ShapeFactory
        {
         
            public static  IShape CtreateShape(string shape)
            {
                if (shape == "Line")
                {
                    return new Line();
                }
                else if (shape == "Circle")
                {
                    return new Circle();
                }
                return null;
                
    
            }
    //反射的实现方式,规定一个统一的类命名方式,通过反射初始化
    public static IShape CtreateWithReflection(string shape) { Assembly assembly = Assembly.GetExecutingAssembly(); var ishape = assembly.CreateInstance("ExercisePrj.Dsignmode."+shape); return ishape as IShape; } } public interface IShape { void Draw(); } public class Line: IShape { public void Draw()//隐式封闭实现,子类可以隐藏不能重写,类调用会执行这个 { Console.WriteLine("draw line"); } void IShape.Draw()//显示实现,接口调用会执行这个 { Console.WriteLine("IShape.DrawLine"); } } public class Circle:IShape { public void Draw() { Console.WriteLine("draw Circle"); } } }

    抽象工厂模式,简单讲就是比上边更流弊的工厂模式···这里有用到上边的类型

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        //抽象工厂类
        public  abstract class AbstractFactory
        {
           public  abstract IShape GetShape(string shape);
           public  abstract IColor GetColor(string color);
        }
        //工厂类子类
        public class ShapeFactoryEx:AbstractFactory
        {
            public override IShape GetShape(string shape)
            {
                return ShapeFactory.CtreateShape(shape);//偷个懒
            }
            public override IColor GetColor(string color)
            { return null; }
        }
        public class ColorFactory : AbstractFactory
        {
            public override IShape GetShape(string shape)
            {
                return null;
            }
            public override IColor GetColor(string color)
            {
                if(color=="blue")
                {
                    return new Blue();
                }
                else if (color=="red")
                {
                    return new Red();
                }
                return null;
            }
        }
        //工厂创造器
        public  class FactoryProducer 
        {
            public static AbstractFactory getFactory( string SType)
            {
                if(SType=="shape")
                {
                    return new ShapeFactoryEx();
                }
                else if(SType=="color")
                {
                    return new ColorFactory();
                }
                return null;
            }
        }
        public  interface IColor
        {
            void Fill();
        }
        public class Blue:IColor
        {
            public void Fill()
            {
                Console.WriteLine("Blue");
            }
        }
        public class Red : IColor
        {
            public void Fill()
            {
                Console.WriteLine("Red");
            }
        }
    
    }

    单例模式:平时用的时候连锁都没加···上次面试的时候,人家问在多线程里边会出啥问题···当时就没反应过来·,说这有啥问题的·都是一个对象调方法就是··完事才想起来,如果初始化的函数在多线程里边就是线程不安全了··简直蒙蔽··这里列好几种写法

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        public class Singleton
        {
            private Singleton() { }
            //private static Singleton m_Singleton;
            //private static readonly object lockvalue = new object();
            //public static Singleton GetInstance()
            //{
            //    //return m_Singleton ?? new Singleton();//不加锁 线程不安全
            //    if (m_Singleton == null)
            //    {
            //        lock (lockvalue)//枷锁//这里还可以加双锁,就是在里边判断是不是空
            //        {
            //            return new Singleton();
            //        }
    
            //    }
            //    return m_Singleton;
            //}
    
            public static readonly Singleton Instance = new Singleton();//据说这个是最流弊的写法··跟下边的写法是一个意思··
            //public static readonly Singleton Instance=null
            //static Singleton()
            //{
            //    Instance = new Singleton();
            //}
        }
    }

     建造者模式,将一个复杂的构造与其表示分开,使用同样的构建创建不同的表示··感觉就是做了可变动的组合,然后用一个类去构造这个变动组合类,一边排列组型或者菜单之类的应用场景都适合

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        //构建类
        public class MealBuilder
        {
            public Meal prepareVegMeal()
            {
                Meal meal = new Meal();
                meal.addItem(new VegBurger());
                meal.addItem(new Coke());
                return meal;
            }
    
            public Meal prepareNonVegMeal()
            {
                Meal meal = new Meal();
                meal.addItem(new ChickenBurger());
                meal.addItem(new Pepsi());
                return meal;
            }
        }
        //实体接口
        public interface Item
        {
            string name { get;}
            float price { get; }
            IPacking packing();
        }
        //实体关联接口
        public interface IPacking
        {
            string pack();
        }
        //不同实体
        public class Wrapper:IPacking
        {
            public string pack()
            {
                return "Wrapper";
            }
        }
        public class Bottle:IPacking
        {
            public string pack()
            {
                return "Bottle";
            }
        }
        public abstract class Burger:Item
        {
            public IPacking packing()
            {
                return new Wrapper();
            }
            public abstract string name { get; }
            public abstract float price { get;  }
        }
        public abstract class ColdDrink:Item
        {
            public IPacking packing()
            {
                return new Bottle();
            }
            public abstract string name { get;  }
            public abstract float price { get; }
        }
        public class VegBurger:Burger
        {
            public override string name { get;  }
            public override float price { get; }
            public VegBurger()
            {
                name = "Veg Burger";
                price = 25.0f;
            }
        }
        public class ChickenBurger: Burger
        {
            public override string name { get; }
            public override float price { get; }
            public ChickenBurger()
            {
                name = "Chicken Burger";
                price = 50.0f;
            }
        }
    
        public class Coke : ColdDrink
        {
            public override string name { get; }
            public override float price { get; }
            public Coke()
            {
                name = "Coke";
                price = 30.0f;
            }
            
        }
        public class Pepsi : ColdDrink
        {
            public override string name { get; }
            public override float price { get; }
            public Pepsi()
            {
                name = "Pepsi";
                price = 35.0f;
            }
    
        }
        //不同的组合类
        public class Meal
        {
            private List<Item> Items = new List<Item>();
            public void addItem(Item item)
            {
                Items.Add(item);
            }
            public float getCost()
            {
                float cost = 0;
                foreach(var item in Items)
                {
                    cost += item.price;
                }
                return cost;
            }
            public void ShowItems()
            {
                foreach(var item in Items)
                {
                    Console.WriteLine("name={0},packing={1},price={2}", item.name, item.packing().pack(), item.price);
                }
            }
        }
    }

    原型模式,就是克隆··是为了避免创建新对象,采用克隆的方式··,讲道理一般实现的克隆是直接new对象然后赋值,这也没法避免啊···,网上写的好多实现方式都是浅复制,这玩意浅复制能行么,如果对象里边的属性或者字段都是基元类型,这无所谓修改的时候就相当于直接指定新的引用对象·,如果不是·哪克隆出来的所有对象里边的引用类型都得单独new,不然可能都得指向一个对象了,·····python有deepcopy, C#好像没有这个····这里是在网上查的用序列化和反序列的方式实现深复制,这样不用new对象···得注意克隆方式

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ExercisePrj.Dsignmode
    {
        //
        public class ApplianceCach
        {
            private static Dictionary<string, Appliance> ApplianceMap = new Dictionary<string, Appliance>();
            public static Appliance GetApplicance(string shapeId)
            {
                Appliance cachAppliance = ApplianceMap[shapeId];
                return (Appliance)cachAppliance.Clone();
            }
            public static void loadCache()
            {
                Fridge fridge = new Fridge();
                fridge.ID = "1";
                ApplianceMap.Add(fridge.ID, fridge);
    
                Television tv = new Television();
                tv.ID = "2";
                ApplianceMap.Add(tv.ID, tv);
    
            }
        }
        [Serializable]
        public abstract class Appliance:ICloneable
        {
            protected string type;
            private string id;
            public string Type { get { return type; } }
            public string ID { get { return id; } set { id = value; } }
    
            public abstract void DoWork();
           public  object Clone()
            {
                object obj = null;
                //将对象序列化成内存中的二进制流  
                BinaryFormatter inputFormatter = new BinaryFormatter();
                MemoryStream inputStream;
                using (inputStream = new MemoryStream())
                {
                    inputFormatter.Serialize(inputStream, this);
                }
                //将二进制流反序列化为对象  
                using (MemoryStream outputStream = new MemoryStream(inputStream.ToArray()))
                {
                    BinaryFormatter outputFormatter = new BinaryFormatter();
                    obj = outputFormatter.Deserialize(outputStream);
                }
                return obj;
    
            }
        }
    
        public class Fridge :Appliance
        {
            public Fridge()
            {
                type = "Fridge";
            }
            public override void DoWork()
            {
                Console.WriteLine("do some fridge job");
            }
    
        }
        public class Television:Appliance
        {
            public Television()
            {
                type = "Television";
            }
            public override void DoWork()
            {
                Console.WriteLine("do some Television job");
            }
        }
    }
  • 相关阅读:
    NGUI版虚拟摇杆
    设计模式 --外观模式(Facade)
    JavaScript提高:005:ASP.NET使用easyUI TABS标签显示问题
    提高工作效率:15个实用的项目管理工具
    前端开发面试题集锦(一)
    SWF代码分析与破解之路 (YueTai VIP视频信息获取工具) Socket续篇
    Android Studio 设置项目Module编码,解决Android Studio项目执行时乱码问题
    HDU2256-Problem of Precision(矩阵构造+高速幂)
    oracle初始安装大小
    强制杀oracle进程
  • 原文地址:https://www.cnblogs.com/onegarden/p/7157252.html
Copyright © 2011-2022 走看看