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");
        }
    }
}
原文地址:https://www.cnblogs.com/onegarden/p/7157252.html