行为型-策略模式

1.产品增加多个行为时,在父类中添加一个方法,在子类中都要实现一遍,增加了代码量和冗余
a)对行为的封装,也就是使用面向接口编程
b)会形成行为族,实现多个行为接口
c)父类是对行为对象的声明
2.类图
3.实现。

 public class GoodFly : IFly
    {
        public void fly()
        {
            Console.WriteLine("Good Good Fly");
        }
    }
 public abstract class Duck
    {
        protected IFly fly;
        protected IQuack quack;
        public Duck() { }

        public void Fly()
        {
            fly.fly();
        }

        public void Quack()
        {
            quack.quack();
        }
    }
 public class RedDuck : Duck
    {
        public RedDuck() {
            fly = new GoodFly();
            quack = new GaGaQuack();
        }
    }
Duck redDuck = new RedDuck();
            redDuck.Fly();
            redDuck.Quack();
            Console.ReadKey();

创建型-抽象工厂

1.来源:生产多个不同的产品,形成产品族。
缺点:新增一个产品比较复杂,得让所有的工厂实现,如果扩展一个工厂/产品族就比较简单
2.类图:
微信截图_20200216232032
3.实现:
“`
public class HuaWeiFactory : IFactory
{
public IPhone CreatePhone()
{
return new HuaWeiPhone();
}

    public IRouter CreateRouter()
    {
        return new HuaWeiRouter();
    }
}


public class XiaoMiFactory : IFactory
{
public IPhone CreatePhone()
{
return new XiaoMiPhone();
}

    public IRouter CreateRouter()
    {
        return new XiaoMiRouter();
    }
}

“`

创建型-工厂方法

1.来源:
a)在简单工厂中,使用条件语句来区分调用哪个对象,如果增加产品,还需要修改条件语句。
b)更多的分离创建者与使用者
c)增加新商品,不需要修改原来的代码,只要新建产品和工厂方法
缺点:当生产过多同类的其他产品或者其他不同类的产品时,不方便管理
2.类图:
微信截图_20200216190500
3.实现:
“`
ICar wlhg = new WuLHGFactory().Create();
wlhg.Wheel();

ICar bmw = new BMWFactory().Create();
bmw.Wheel();
Console.ReadKey();
“`

创建型–简单工厂

不属于GOF23种设计模式,但比较常用(主要使用条件语句实现,局限性:有新增时,需要增加条件判断,未完全做到开闭原则),根据设计原则来说:工厂方法模式,但根据实际使用来说,常常使用简单工厂模式
1.来源
a)依赖倒置(DIP):依赖抽象,而不是细节/具体
b)面向抽象(抽象类和接口),同一个方法可以在不同的类型中实现,下层的变化不会影响上层的变化
c)创建者和调用者分离
2.实现一:只使用switch
“`
//工厂
public static IRace CreateRace(RaceType raceType)
{
IRace race = null;
switch (raceType)
{
case RaceType.Human:
race= new Human();
break;
case RaceType.NE:
race = new NE();
break;
case RaceType.Undead:
race = new Undead();
break;
}
return race;
}

    public enum RaceType
    {
        Human,
        NE,
        Undead
    }

“`

<code>//调用
IRace race = SimpleFactory.CreateRace(SimpleFactory.RaceType.NE);
race.RaceKing();</code>
3.可配置:把简单工厂的参数配置到可编辑文件中
```
//使用System.Configuration获取App.config下的配置(这里用此方法,netcore一般有json)
public string GetAppSettings()
{
string setting= ConfigurationManager.AppSettings["RaceConfig"];
return setting;
}
```
```
   //使用可配置文件
public static IRace CreateRaceConfig()
{
string race = new Common().GetAppSettings();
RaceType type=(RaceType)Enum.Parse(typeof(RaceType), race);
return CreateRace(type);
}
```
4.可配置,可扩展:把简单工厂的参数配置到可编辑文件中,并可以使用扩展,把依赖细节放到了配置文件中。
a)反射:可加载程序集,步骤:
“`
//使用可配置文件及反射
public static IRace CreateRaceConfigReflection()
{
string race = new Common().GetAppSettingsReflection();
Assembly assembly = Assembly.LoadFrom(race.Split(‘,’)[1]+”.dll”);//通过加载dll相对路径(需要把dll复制到此程序目录下)
Type type = assembly.GetType(race.Split(‘,’)[0]);

        return (IRace)Activator.CreateInstance(type);
    }

“`
5.简单工厂与IOC容器

创建型-单例

1.解决问题来源:
a)同方法—共享变量
b)同类—共享变量
c)不同类–公开静态变量
d)但都没有强制保证只有一个实例
“`
public static Common instance = new Common();//同类;加public在不同类共享
static void Main(string[] args)
{
//Common instance = new Common();同方法
for (int i = 0; i < 3; i++)
{
//Common instance = new Common();//原方法
instance.Show();
}

        CommonShow();

        Other other = new Other();
        other.OtherShow();

        Console.ReadKey();
    }

2.三板斧保证强制只一个简单实例
a)私有化构造函数----避免重复构造
b)公开静态方法提供实例--外部才能调用
c)同类的静态变量共享--保证变量唯一

//最基本的写法
private Common()
{
Console.WriteLine(“我是Common构造函数————“);
}

    static Common instance = null;

    public static Common CreateInstance()
    {
        if (instance == null)
        {
            instance = new Common();
        }
        return instance;
    }
    public  void Show()
    {
        Console.WriteLine("请开始你的表演");
    }

3.双判断锁实例,在多线程下,普通单例模式会创建多次对象,为解决此问题。
a)加锁:

//Task.Run开启多线程
Task.Run(() =>
{
Common instance = Common.CreateInstance();
instance.Show();
});

//lock锁
static readonly object single_lock = new object();
public static Common CreateInstance()
{
lock (single_lock)
{
if (instance == null)
{
instance = new Common();
}
}
return instance;
}
b)双判断锁,当多线程创建对象后,再有后面的线程再次使用时,还是会进入锁排队,为了解决此问题:
static Common instance = null;
static readonly object single_lock = new object();
public static Common CreateInstance()
{
if (instance == null)//多了一次判断
{
lock (single_lock)
{
Console.WriteLine(“lock排队……”);
if (instance == null)
{
instance = new Common();
}
}
}
return instance;
}
“`
4.懒汉实例:需要的时候才创建
双判断锁属性此类型
5.饿汉实例:首先创建,方便要用的时候立刻使用。由CLR保障。
a)利用静态构造函数实现
b)利用静态属性实现
6.——————————静态方法/属性,使用static修饰————–
a)静态方法只能访问静态数据方法
b)属于类的,而不是任何一个对象
c)static方法中不能使用this关键字,因为this是对象
d)所有静态初始化程序都在第一次访问类之前运行