using DesignPatternPrinciple.DIP;
using DesignPatternPrinciple.LOP;
using DesignPatternPrinciple.SRP;
using System;
using DesignPatternPrinciple.Homeworks;
using System.Collections.Generic;
using System.Linq;
namespace DesignPatternPrinciple
{
class Program
{
static void Main(string[] args)
{
//1.单一职责原则(Single Responsibility Principle)
//2.里氏替换原则(Liskov Substitution Principle)
//3.依赖倒置原则(Dependence Invention Principle)
//4.接口隔离原则(Interface Segregation Principle)
//5.迪米特法则(Law Of Demeter)//最少知道原则
//6.开闭原则(Open Close Principle)
//SRPShow.show();
//LOPShow.Show();
//DIPShow.show();
//子类静态变量>子类静态构造函数>子类非静态变量>父类静态变量>父类静态构造函数>父类非静态变量>父类无参构造函数>子类无参构造函数;
//Father father0 = new Father();//静态构造函数先执行,其次无参构造函数
//Father father1 = new Father(1);//静态构造函数先执行,其次带参构造函数 但是静态构造函数在上面已经执行一次,不会再执行了
//Children children = new Children();
//Children children1 = new Children(1);
Console.WriteLine("---------------");
Father father2 = new Children();
Father father3 = new Children(1);
father2.show();//如果子类是override,那么调用的是子类覆写的方法;如果子类用new,那么调用的是父类的方法
//为什么这么些,依赖倒置 实现多态
int loc = 0;
#region 作业
var objEast = (EastVentriloquism)Homework.SimpleFactory(VentriloquismEnum.East);
Homework.Show(objEast);
var objWest = (WestVentriloquism)Homework.SimpleFactory(VentriloquismEnum.West);
Homework.Show(objWest);
var objSouth = (SouthernVentriloquism)Homework.SimpleFactory(VentriloquismEnum.South);
Homework.Show(objSouth);
var objNorth = (NorthVentriloquism)Homework.SimpleFactory(VentriloquismEnum.North);
Homework.Show(objNorth);
Homework.UniqueSkill(objEast.UniqueSkill);
Homework.UniqueSkill(objWest.UniqueSkill);
Homework.UniqueSkill(objSouth.UniqueSkill);
Homework.UniqueSkill(objNorth.UniqueSkill);
Console.WriteLine("=================================事件======================");
objSouth.eventhandler += (sender, args) => Console.WriteLine("夫起大呼");
objSouth.eventhandler += (sender, args) => Console.WriteLine("妇亦起大呼");
objSouth.eventhandler += (sender, args) => Console.WriteLine("两儿齐哭");
objSouth.eventhandler += (sender, args) => Console.WriteLine("俄而百千人大呼");
objSouth.eventhandler += (sender, args) => Console.WriteLine("百千儿哭");
objSouth.eventhandler += (sender, args) => Console.WriteLine("百千犬吠");
objNorth.eventhandler += new Audience().HusbandShout;
objNorth.eventhandler += new Audience().WifeShout;
objNorth.eventhandler += new Audience().SonShout;
objNorth.eventhandler += new Audience().MansShout;
objNorth.eventhandler += new Audience().SonsShout;
objNorth.eventhandler += new Audience().DogsShout;
objWest.eventhandler += (sender, args) =>
{
var fireargs = (FireEventArgs)args;
var westven = (WestVentriloquism)sender;
Console.WriteLine($"夫起大呼,现在温度:{fireargs?.temperature},{westven.Name}燃点:{westven.IgnitionPoint}");
};
objWest.eventhandler += (sender, args) =>
{
var fireargs = (FireEventArgs)args;
var westven = (WestVentriloquism)sender;
Console.WriteLine($"妇亦起大呼,现在温度:{fireargs?.temperature},{westven.Name}燃点:{westven.IgnitionPoint}");
};
objEast.eventhandler += new EastAudience().HusbandShout;
objEast.eventhandler += new EastAudience().WifeShout;
objSouth.SetTemperature(1200);
objNorth.SetTemperature(1200);
objWest.SetTemperature(1200);
objEast.SetTemperature(1200);
MiddleVentriloquism middleVentriloquism = new MiddleVentriloquism();
middleVentriloquism.StartEvent += () => Console.WriteLine("中派表演开始事件");
middleVentriloquism.ClimaxEvent += () => Console.WriteLine("中派表演高潮事件");
middleVentriloquism.EndEvent += () => Console.WriteLine("中派表演结束事件");
middleVentriloquism.Show();
IEnumerable<int> vs = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 8, 8 };
var rst = vs.GetByRandom(5);
#endregion
}
}
#region this和base关键字区别
//this关键字代表当前对象,通过this关键字可以访问当前对象的成员。(当前对象的成员:自己本身的成员+从父类继承过来的所有的成员。)
//this关键字可以访问:本类的所有成员和父类的非私有成员。父类的私有成员确实存在,但是就是访问不到。
// this关键字仍然代表的是对象,通过它可以点出对象中的除了父类的私有成员以外的所有成员。
// this关键字只能用在实例方法中。
//作用:
//1)代表当前对象。在实例方法中使用this关键字就代表当前对象。通过this关键字可以点出本类的所有成员和父类的非私有成员。
//2)调用本类的其他的构造函数。在构造函数的后面的this代表调用本类的其他的构造函数。
//显示的访问父类的非私有成员。可以访问子类对象中的父类的非私有成员。base不代表父类对象。因为压根就没有父类对象。通过它可以访问到父类的非私有成员。
//通过this关键字访问当前对象的成员的时候:先找子类本身有没有这个成员,如果没有再找是否有从父类继承过来的。base关键字 直接就找父类中的成员。我们发现,base可以点出来的成员,通过this都可以点出来访问。
//建议:如果我们访问的确实是从父类继承过来的,那么建议用base关键字访问,这样方便代码的阅读和提高效率。只有在访问的成员确实是子类独有的,那么我们才用this关键字。
// 作用:
//1)在实例方法中,通过base关键字可以显示的访问子类对象中的非私有的父类成员。
// 2)调用父类的构造函数。在子类的构造函数的后面的base代表调用父类的构造函数。
#endregion
#region protected关键字
//protected 给基类和子类用,实例不能用,除非实例存在于自己本类中
//可以通过this 访问自己的project和 base访问父类的project
//为了给派生类中用,如果不给派生类用,直接private
public class A
{
public int a = 1;
protected int b = 2;
}
public class B : A
{
public int c = 0;
//public void show1()
//{
// A a = new A();
// this.a = a.a;
// this.c = a.b;//报错
// Console.WriteLine($"a:{a};b:{b}");
//}
public void show2()
{
B b = new B();
this.c = b.b;//在自己的类内部,是可以实例化自己,然后访问project
Console.WriteLine($"this.b:{this.b};b:{base.b}");//类内部,也可以通过base访问父类的project
}
}
public class C
{
//public void show3()
//{
// B b = new B();
// A a = new A();
// Console.WriteLine($"{a.b}{b.b}");//报错,类外部实例就用不了了
//}
}
#endregion
#region 构造函数执行顺序
public class Father
{
public Father()
{
Console.WriteLine("Father无参构造函数");
}
static Father()
{
Console.WriteLine("Father静态无参构造函数");
}
public Father(int i)
{
Console.WriteLine("Father带参构造函数");
}
public virtual void show()
{
Console.WriteLine("Father show");
}
}
public class Children : Father
{
public Children() : base()
{
Console.WriteLine("Children无参构造函数");
}
static Children()
{
Console.WriteLine("Children静态无参构造函数");
}
public Children(int i) : base(i)
{
Console.WriteLine("Children带参构造函数");
}
public override void show()
{
Console.WriteLine("Children show");
}
//public new void show()
//{
// Console.WriteLine("Children show");
//}
}
#region 验证单例
public sealed class Singleton
{
/*单例四要素:
1.私有静态属性,类型是本对象
2.私有构造函数
3.静态构造函数,实例化本对象赋值给私有静态属性
4.提供给外部的方法,返回私有静态属性
*/
//反射会破环单例--反射可以调用私有构造函数
public string Name { set; get; }
//private static Singleton singleton = new Singleton();
private static Singleton singleton = null;
static Singleton()
{
singleton = new Singleton();
}
private Singleton()
{
Console.WriteLine("私有构造函数被创建");
}
public static Singleton GetSingleton()
{
return singleton;
}
}
#endregion
#endregion
//core中接口也可以实现成员
public interface AA
{
public void show()
{
Console.WriteLine("Interface AA");
}
}
public class AAA : AA
{
}
}
1.单一职责
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.SRP
{
//单一职责原则:类T负责两个不同的职责,P1和P2。当由于职责P1需求发生改变而修改T时,有可能导致原本正常的P2职责功能发生故障
//一个类只干一件事,职责清晰
//拆分父类和子类,每个类很简单,稳定
//但是代码量增大,理解成本变高
//扩展:方法层面的单一职责;类库层面/项目层面的单一职责;系统级别的单一功能
public class SRPShow
{
public static void show()
{
Animal animal = new Brid();
animal.Breath();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.SRP
{
public abstract class Animal
{
protected string Name { set; get; }
public Animal(string name)
{
this.Name = name;
}
父类中出现了好几个子类该有的动作,而且不止一个部分出现,这个时候应该拆分
父类变成abstract 子类
//protected void Breath()
//{
// if (this.Name == "鸟")
// Console.WriteLine("呼吸空气");
// if (this.Name == "鱼")
// Console.WriteLine("呼吸水");
// if (this.Name == "蚯蚓")
// Console.WriteLine("呼吸泥土");
//}
public abstract void Breath();
public abstract void Motion();
//protected void Motion()
//{
// if (this.Name == "鸟")
// Console.WriteLine("flying");
// if (this.Name == "鱼")
// Console.WriteLine("swimming");
// if (this.Name == "蚯蚓")
// Console.WriteLine("crawling");
//}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.SRP
{
public class Brid : Animal
{
public Brid() : base("鸟")
{
}
public override void Breath()
{
Console.WriteLine("呼吸空气");
}
public override void Motion()
{
Console.WriteLine("呼吸空气");
}
}
}
2.里氏替换
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.LSP
{
//里氏替换原则:任何使用基类的地方,都可以透明的使用子类
//继承:子类拥有父类的一切属性和行为,任何出现父类的地方,都可以用子类来代替
//继承+透明(安全,不会出现行为的不一致)
/*1.父类有的,子类必须有,否则应该断掉继承;(再来一个祖父类,只包含必须有的东西)
*2.子类可以有自己的属性和行为,所以在子类出现的地方,父类不一定能代替
*3.避免重写(不new),因为如果此时有人不知道用var声明一个子类,在他并不知道父子类内容的情况下会调不到父类的方法,走的是子类的方法;
* 如果父类的方法属性有被子类改动的可能性,用abstract或者virtual,原因同上
*4.重写或实现父类的方法是,入参形参要比父类的范围大,返回值要比父类的小
*/
public class LSPShow
{
}
public class People
{
public int Id { set; get; }
public string Name { set; get; }
public virtual void Tradition()
{
Console.WriteLine("传统美德");
}
}
public class Chanese: People
{
public override void Tradition()
{
Console.WriteLine("仁义礼智信");
}
}
public class Japanese : People
{
//这么写不符合里氏替换原则,如果子类不包含父类的方法,应该断掉继承
//public virtual void Tradition()
//{
// throw new Exception();
//}
}
}
3.迪米特(最少知道原则)
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.LOP
{
/*迪米特法则(最少知道原则):一个对象应该对其他对象保持最少的了解
* 只与直接的朋友通讯
*
* 背景:面向对象语言-----万物皆对象-----要产生功能------类与类要交互-----这就耦合了
* 类与类之间的关系:
* 纵向:继承≈实现
* 横向:聚合>组合>关联>依赖(出现在方法内部的类就构成依赖)
*
* 作用:降低类与类之间的耦合
* 只和直接的朋友通讯,那就要降低依赖,就是减少在方法内部的类型(基类BCL除外)
*
* 但是会增加额外的成本
*
* 应用:
* 工作中会构建中间层/中介
* 门面模式 中介者模式 分层模式都属于这种
* 上层UI--->下层子系统(订单/支付/仓储/物流)这个架构给UI和子系统中间加一层门面,UI只依赖门面,门面去交互子系统
* 三层架构:UI--BLL(业务逻辑层)--DAL(数据交互层)
*
* 要遵循的话代码风格:
* 避免方法内部依赖
* 降低访问修饰符权限
* private
* protect
* internal
* protect internal(子类或者同类库)
*
* 迪米特法则:依赖别人更少,别人了解更少 --->逐渐自闭
*/
public class LOPShow
{
public static void Show()
{
School school = new School()
{
ID = 1,
SchoolName = "吃法大学",
classes = new List<Class>()
{
new Class ()
{
ID = 1,
ClassName = "一班",
students = new List<Student> ()
{
new Student()
{
ID = 1,
StudentName = "小王",
},
new Student()
{
ID = 2,
StudentName = "小高"
}
}
}
}
};
school.Manage();
school.Manage1();
}
}
public class School
{
public int ID { set; get; }
public string SchoolName { set; get; }
public List<Class> classes { set; get; }
//这个方法中依赖班级Class和学生Student两个类型,耦合太重,按照迪米特法则,学校直接交互的应该是班级,学生应该放到班级中去交互,写方法Manage1(),学生的管理放到班级中去
public void Manage()
{
foreach (var clas in this.classes)
{
Console.WriteLine($"{this.GetType().Name}管理{clas.ClassName}");
foreach (var stu in clas.students)
{
Console.WriteLine($"{clas.GetType().Name}管理{stu.StudentName}");
}
}
}
//这个方法遵循迪米特法则,学校类只与班级通讯
public void Manage1()
{
foreach (var clas in this.classes)
{
Console.WriteLine($"{this.GetType().Name}管理{clas.ClassName}");
clas.Manage();
}
}
}
public class Class
{
public int ID { set; get; }
public string ClassName { set; get; }
public List<Student> students { set; get; }
public void Manage()
{
foreach (var stu in this.students)
{
Console.WriteLine($"{this.GetType().Name}管理{stu.StudentName}");
}
}
}
public class Student
{
public int ID { set; get; }
public string StudentName { set; get; }
//public
}
}
4.依赖倒置
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.DIP
{
/* 依赖倒置原则:高层模块不应该依赖低层模块,二者应该通过抽象来依赖
* 依赖抽象,而不应该依赖细节
*
* 抽象指 接口/抽象类(通常情况下应该写接口,除非是有些通用功能可以在抽象类中实现;抽象类描述是什么,接口描述能干什么)
* 细节指 普通类
*
* 面向抽象编程:尽量的使用抽象,80%以上的设计模式都和抽象有关
* 属性/字段/方法参数、返回值 尽量都是抽象
*/
public class DIPShow
{
public static void show()
{
Student student = new Student()
{
Id = 1,
Name = "小王"
};
{
MI mi = new MI();
student.Use(mi);
}
{
IPhone iphone = new IPhone();
student.Use(iphone);
}
}
}
public abstract class AbstractPhone
{
public int ID { set; get; }
public string Branch { set; get; }
public abstract void Call();
public abstract void Text();
}
public class MI : AbstractPhone
{
public override void Call()
{
Console.WriteLine($"Use {this.GetType().Name} call");
}
public override void Text()
{
Console.WriteLine($"Use {this.GetType().Name} text");
}
}
public class IPhone : AbstractPhone
{
public override void Call()
{
Console.WriteLine($"Use {this.GetType().Name} call");
}
public override void Text()
{
Console.WriteLine($"Use {this.GetType().Name} text");
}
}
public class Student
{
public int Id { set; get; }
public string Name { set; get; }
//入参改为手机的抽象,这样就不用针对不同的手机写不同的方法
//当然可以用泛型+父类约束来实现,但这样其实就等于入参的类型改为抽象
//面向抽象的好处:除了满足不同的入参,还支持扩展,比如再来一个新类型的手机,只要它继承手机抽象类,上层的类不用变化,比如学生类中的Use方法不用动
//如果依赖细节,底层有变化了,变化会传递到上层
//依赖抽象,只要抽象层稳定,底层的变化不会传递到上层,这样就能支持层内部的扩展,比如新加手机,这样的程序架构就是稳定的
//但是依赖抽象支持的是通用功能,不支持某个底层的特殊功能,比如现在小米手机的Use除了打电话发短信还增加手环功能,这样就通用不了了,要么该抽象层,要么小米的Use要独立出来
//依赖倒置原则(理论基础)-------Ioc控制反转(原理的实践封装)(上层把实例化下层的步骤交给第三方)-------DI依赖注入(实现Ioc的手段)
public void Use(AbstractPhone phone)
{
Console.WriteLine($"这是 {this.Name} 的手机");
phone.Call();
phone.Text();
}
}
}
5.接口隔离
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.ISP
{
//接口隔离原则:客户端不应该依赖它不需要的接口
//一个类对另一个类的依赖应该建立在最小的接口上
//接口定义应该遵循:
//1.不能是大而全的接口,因为这样会让子类实现一些本身不需要的功能
//2.也不能定义的太碎,不能一个方法一个接口
//3.应该按照功能的密不可分性定义接口,当然,随着业务的发展,接口也可能会调整,所以在定义抽象时应该预留提前量
//4.接口合并:提高接口的内聚性,在接口内部,原本实际情况是一体的方法没必要拆开,都暴露出来,比如导航功能,定位/搜索/导航 是一体的,没必要分为三个方法暴露给子类
public class ISPShow
{
}
}
6.开闭
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.OCP
{
//开闭原则:对扩展开放,对修改关闭
// 修改:修改现有代码(修改类)
// 扩展:增加代码(类)
//开闭原则是最终追求
public class OCPShow
{
}
}
作业:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public class Homework
{
public static VentriloquismPerform SimpleFactory(VentriloquismEnum @enum)
{
switch (@enum)
{
case VentriloquismEnum.East: return new EastVentriloquism();
case VentriloquismEnum.West: return new WestVentriloquism();
case VentriloquismEnum.South: return new SouthernVentriloquism();
case VentriloquismEnum.North: return new NorthVentriloquism();
default: return null;
}
}
public static void Show<T>(T t) where T : VentriloquismPerform, ICharge
{
Type type = t.GetType();
object obj = Activator.CreateInstance(type);
foreach (PropertyInfo property in type.GetProperties())
{
Console.WriteLine($"{property.Name}-{property.GetValue(obj)}");
}
t.Start();
t.Prologue();
t.DogsBark();
t.HumanShout();
t.WindSound();
t.Conclusion();
t.Charge();
}
public static void UniqueSkill(Action action)
{
Console.WriteLine("绝活马上开始");
action.Invoke();
Console.WriteLine("绝活表演结束,大家鼓掌");
}
}
public enum VentriloquismEnum
{
East,
West,
South,
North,
}
}
抽象父类
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public abstract class VentriloquismPerform
{
public string Human { set; get; }
public string Table { set; get; }
public string Ruler { set; get; }
public string Chair { set; get; }
public string Fan { set; get; }
public void Start()
{
Console.WriteLine("表演开始了");
}
public abstract void DogsBark();
public abstract void HumanShout();
public abstract void WindSound();
/// <summary>
/// 开场白
/// </summary>
public virtual void Prologue()
{
Console.WriteLine("开始了");
}
/// <summary>
/// 结束语
/// </summary>
public virtual void Conclusion()
{
Console.WriteLine("结束了");
}
public event EventHandler eventhandler;
/// <summary>
/// 燃点
/// </summary>
public virtual int IgnitionPoint { get; } = 400;
/// <summary>
/// 设置温度
/// </summary>
/// <param name="tem"></param>
public void SetTemperature(int tem)
{
if (tem > IgnitionPoint)
{
Console.WriteLine("火起");
eventhandler?.Invoke(this, new FireEventArgs
{ temperature = tem });
}
}
//事件的触发必须在自己的类中,触发的条件和触发的流程一般写死了
//两个不写死小套路:
//1.把触发条件封装一个虚方法,可以被子类重写,这样条件就变得灵活
//2.把事件执行动作封装出去;子类想什么时候执行事件就什么时候执行,流程就可以扩展了
//这个是1的方法;子类可以根据自己的需要重写触发逻辑
protected virtual bool isOn(int tem)
{
return tem > IgnitionPoint;
}
//这个是2的方法;子类可以任何地方调用事件
protected void EventInvoke(FireEventArgs fireEventArgs)
{
eventhandler?.Invoke(this, fireEventArgs);
}
}
//事件参数类
public class FireEventArgs : EventArgs
{
public int temperature { set; get; }
}
}
接口
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public interface ICharge
{
public void Charge();
}
}
东南西北中派口技类
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public class EastVentriloquism : VentriloquismPerform, ICharge
{
private string _name = "东派";
public string Name
{
get { return _name; }
set { _name = value; }
}
public void UniqueSkill()
{
Console.WriteLine($"{_name}绝活");
}
public override void DogsBark()
{
Console.WriteLine($"{_name}犬吠");
}
public override void HumanShout()
{
Console.WriteLine($"{_name}人叫");
}
public override void WindSound()
{
Console.WriteLine($"{_name}风声");
}
public void Charge()
{
Console.WriteLine($"{_name}收费");
}
}
public class EastAudience
{
public void HusbandShout(object send, EventArgs eventArgs)
{
var fireargs = (FireEventArgs)eventArgs;
var westven = (EastVentriloquism)send;
Console.WriteLine($"夫起大呼,现在温度:{fireargs?.temperature},{westven?.Name}燃点:{westven?.IgnitionPoint}");
}
public void WifeShout(object send, EventArgs eventArgs)
{
var fireargs = (FireEventArgs)eventArgs;
var westven = (EastVentriloquism)send;
Console.WriteLine($"妇亦起大呼,现在温度:{fireargs?.temperature},{westven?.Name}燃点:{westven?.IgnitionPoint}");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public class SouthernVentriloquism : VentriloquismPerform, ICharge
{
private string _name = "南派";
public string Name
{
get { return _name; }
set { _name = value; }
}
public void UniqueSkill()
{
Console.WriteLine($"{_name}绝活");
}
public override void Prologue()
{
Console.WriteLine($"{_name}开场白");
}
public override void DogsBark()
{
Console.WriteLine($"{_name}犬吠");
}
public override void HumanShout()
{
Console.WriteLine($"{_name}人叫");
}
public override void WindSound()
{
Console.WriteLine($"{_name}风声");
}
public void Charge()
{
Console.WriteLine($"{_name}收费");
}
public override int IgnitionPoint { get; } = 800;
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public class WestVentriloquism : VentriloquismPerform, ICharge
{
private string _name = "西派";
public string Name
{
get { return _name; }
set { _name = value; }
}
public void UniqueSkill()
{
Console.WriteLine($"{_name}绝活");
}
public override void Prologue()
{
Console.WriteLine($"{_name}开场白");
}
public override void Conclusion()
{
Console.WriteLine($"{_name}结束语");
}
public override void DogsBark()
{
Console.WriteLine($"{_name}犬吠");
}
public override void HumanShout()
{
Console.WriteLine($"{_name}人叫");
}
public override void WindSound()
{
Console.WriteLine($"{_name}风声");
}
public void Charge()
{
Console.WriteLine($"{_name}收费");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public class NorthVentriloquism : VentriloquismPerform, ICharge
{
private string _name = "北派";
public string Name
{
get { return _name; }
set { _name = value; }
}
public void UniqueSkill()
{
Console.WriteLine($"{_name}绝活");
}
public override void Conclusion()
{
Console.WriteLine($"{_name}结束语");
}
public override void DogsBark()
{
Console.WriteLine($"{_name}犬吠");
}
public override void HumanShout()
{
Console.WriteLine($"{_name}人叫");
}
public override void WindSound()
{
Console.WriteLine($"{_name}风声");
}
public void Charge()
{
Console.WriteLine($"{_name}收费");
}
public override int IgnitionPoint { get; } = 800;
}
public class Audience
{
public void HusbandShout(object send, EventArgs eventArgs)
{
Console.WriteLine("夫起大呼");
}
public void WifeShout(object send, EventArgs eventArgs)
{
Console.WriteLine("妇亦起大呼");
}
public void SonShout(object send, EventArgs eventArgs)
{
Console.WriteLine("两儿齐哭");
}
public void MansShout(object send, EventArgs eventArgs)
{
Console.WriteLine("俄而百千人大呼");
}
public void SonsShout(object send, EventArgs eventArgs)
{
Console.WriteLine("百千儿哭");
}
public void DogsShout(object send, EventArgs eventArgs)
{
Console.WriteLine("百千犬吠");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public class MiddleVentriloquism : VentriloquismPerform, ICharge
{
private string _name = "中派";
public override void DogsBark()
{
Console.WriteLine($"{_name}犬吠");
}
public override void HumanShout()
{
Console.WriteLine($"{_name}人叫");
}
public override void WindSound()
{
Console.WriteLine($"{_name}风声");
}
public void Charge()
{
Console.WriteLine($"{_name}收费");
}
public void UniqueSkill()
{
Console.WriteLine($"{_name}绝活");
}
public event Action StartEvent;
public event Action ClimaxEvent;
public event Action EndEvent;
public void Show()
{
base.Start();
base.Prologue();
this.StartEvent?.Invoke();
this.DogsBark();
this.HumanShout();
this.WindSound();
this.UniqueSkill();
this.ClimaxEvent?.Invoke();
base.Conclusion();
this.Charge();
this.EndEvent?.Invoke();
}
}
}
封装一个随机取列表指定个数的Linq方法
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DesignPatternPrinciple.Homeworks
{
public static class LinqExtend
{
public static IEnumerable<T> GetByRandom<T>(this IEnumerable<T> ts, int count)
{
if (ts == null || ts.Count() <= count)
return null;
else
{
IEnumerable<T> rst = ts.OrderBy(t => Guid.NewGuid());
return rst.Take(count);
}
}
}
}