二手车网站开发过程,短信营销哪个平台好,国内装修公司排名,网络营销模式有哪几种目录
思维导图
一、什么是观察者模式#xff1f;
二、有什么优点吗#xff1f;
三、有什么缺点吗#xff1f;
四、什么时候使用观察者模式#xff1f;
五、代码展示
①、双向耦合的代码
②、解耦实践一
③、解耦实践二
④、观察者模式
六、这个模式涉及到了哪些…目录
思维导图
一、什么是观察者模式
二、有什么优点吗
三、有什么缺点吗
四、什么时候使用观察者模式
五、代码展示
①、双向耦合的代码
②、解耦实践一
③、解耦实践二
④、观察者模式
六、这个模式涉及到了哪些知识点 思维导图 一、什么是观察者模式
又叫发布-订阅publish/Subscrib模式。定义了一种一对多的依赖关系让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时会通知所有观察者对象使他们能够自动更新自己。
观察者类似于卧底这样一个角色。在上班的时候难免会有人趁老板不在的时候做一些工作之外的事情例如炒炒股看看NBA之类的那如何应对老板突然回来这件事情呢我们就需要卧底这样一个人给我们放风老板一回来就通知这些人“老板回来了”。这其实就是一种观察者模式 Subject类它把所有对观察者对象的引用保存在一个聚集里每个主题都可以有任何数量的观察者。抽象主题提供一个接口可以增加和删除观察者对象。
Observer类抽象观察者为所有的具体观察者定义一个接口在得到主题的通知时更新自己。
ConcreteSubject类具体主题将有关状态存入具体观察者对象在具体主题的内部状态改变时给所有登记过的观察者发出通知。
ConcreteObserver类具体观察者实现抽象观察者角色所要求的更新接口以便使本身的状态与主题的状态相协调。 二、有什么优点吗
观察者模式所做的工作其实就是在解除耦合让耦合的双方都依赖于抽象而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。满足依赖倒转原则 三、有什么缺点吗
如果观察者很多的话一个一个的通知会影响效率 四、什么时候使用观察者模式
当一个对象的改变需要同时改变其他对象的时候。
而且它不知道具体有多少对象有待改变时应该考虑使用观察者模式。 五、代码展示
场景小菜公司的同事在老板外出的期间偷偷地通过网页看股票行情但是一不小心老板就回来了让老板看到工作的时候做这些总是不太好的如果避免这样的情况呢就需要前台秘书这样的一个卧底老板一回来了前台秘书童子喆就拨了个电话告诉同事。但有一次因为老板回来直接就找童子喆做一些其他事情童子喆就没来得及打电话导致同事就没被通知到“老板回来了”
①、双向耦合的代码 //前台秘书类class Secretary{//同事列表private IListStockObserver observers new ListStockObserver(); //IList接口List泛型集合数据类型是StockObserverprivate string action; //成员变量//构造方法public Secretary() { }//增加public void Attach(StockObserver observer){observers.Add(observer); //向集合里面添加同事}//通知public void Notify(){foreach (StockObserver o in observers) //foreach遍历集合数据类型 变量名 in 遍历的集合o.Update(); //一个一个的给同事通知}//前台状态public string SecretaryAction{get { return action; } //get访问器set { action value; } //set访问器}}//看股票同事类class StockObserver{private string name; //字符串成员变量private Secretary sub; //前台秘书类类型成员变量public StockObserver(string name, Secretary sub) //构造方法{this.name name; //赋值this.sub sub;}public void Update() //通知{Console.WriteLine({0}{1}关闭股票行情继续工作, sub.SecretaryAction, name); //要通知的语句}}
客户端代码
//前台小姐童子喆
Secretary tongzizhe new Secretary();//看股票的同事
StockObserver tongshi1 new StockObserver(魏关姹, tongzizhe);
StockObserver tongshi2 new StockObserver(易管查, tongzizhe);//前台记下了两位同事
tongzizhe.Attach(tongshi1);
tongzizhe.Attach(tongshi2);//发现老板回来
tongzizhe.SecretaryAction 老板回来了;//通知两个同事
tongzizhe.Notify();Console.ReadKey (); 问题前台类和看股票者类之间互相耦合。 ②、解耦实践一 抽象观察类 abstract class Observer
{protected string name;protected Secretary sub;public Observer(string name, Secretary sub) //有参的构造方法{this.name name;this.sub sub;}//通知public abstract void Update();
}
看股票的同事
class StockObserver : Observer
{//继承父类的构造方法public StockObserver(string name, Secretary sub) : base(name, sub) { }public override void Update(){Console.WriteLine({0}{1} 关闭股票行情继续工作, sub.SecretaryAction, name);}
}
看NBA的同事
class NBAObserver : Observer
{public NBAObserver(string name, Secretary sub) : base(name, sub) { }public override void Update(){Console.WriteLine({0}{1} 关闭NBA直播继续工作, sub.SecretaryAction, name);}
} 前台秘书类 class Secretary{private IListObserver observers new ListObserver(); //集合private string action; //成员变量//增加public void Attach(Observer observer) //针对抽象编程减少了与具体类的耦合{observers.Add(observer);}//减少public void Detach(Observer observer) //针对抽象编程减少了与具体类的耦合{observers.Remove(observer);}//通知public void Notify(){foreach (Observer o in observers)o.Update();}//前台状态public string SecretaryAction //属性{get { return action; }set { action value; }}}
客户端代码 //前台小姐童子喆
Secretary tongzizhe new Secretary();//看股票的同事
StockObserver tongshi1 new StockObserver(魏关姹, tongzizhe);
StockObserver tongshi2 new StockObserver(易管查, tongzizhe);//前台记下了两位同事
tongzizhe.Attach(tongshi1);
tongzizhe.Attach(tongshi2);//发现老板回来
tongzizhe.SecretaryAction 老板回来了;//通知两个同事
tongzizhe.Notify();Console.ReadKey (); ③、解耦实践二 通知者接口 interface Subject{void Attach(Observer observer); //增加void Detach(Observer observer); //减少void Notify(); //通知string SubjectState //前台状态{get;set;}} 老板 class Boss : Subject{//同事列表private IListObserver observers new ListObserver();private string action;//增加public void Attach(Observer observer){observers.Add(observer);}//减少public void Detach(Observer observer){observers.Remove(observer);}//通知public void Notify(){foreach (Observer o in observers)o.Update();}//前台状态public string SubjectState{get { return action; }set { action value; }}}
前台秘书类 class Secretary{//同事列表private IListObserver observers new ListObserver();private string action;//增加public void Attach(Observer observer){observers.Add(observer);}//减少public void Detach(Observer observer){observers.Remove(observer);}//通知public void Notify(){foreach (Observer o in observers)o.Update();}//前台状态public string SubjectState{get { return action; }set { action value; }}}
抽象观察者 abstract class Observer{protected string name; //成员变量姓名protected Subject sub; //成员变量通知者public Observer(string name, Subject sub) //构造方法{this.name name; //赋值this.sub sub;}public abstract void Update();}
看股票的同事 class StockObserver : Observer{public StockObserver(string name, Subject sub) : base(name, sub) { }public override void Update(){Console.WriteLine({0}{1} 关闭股票行情继续工作, sub.SubjectState, name);}}#endregion
客户端代码
//老板胡汉三
Boss huhansan new Boss();//看股票的同事
StockObserver tongshi1 new StockObserver(魏关姹, huhansan);
//看NBA的同事
StockObserver tongshi2 new StockObserver(易管查, huhansan);huhansan.Attach(tongshi1);
huhansan.Attach(tongshi2);huhansan.Detach(tongshi1); //魏关姹其实是没有被老板通知到所以减去//老板回来
huhansan.SubjectState 我胡汉三回来了;
//发出通知
huhansan.Notify();Console.ReadKey(); ④、观察者模式 Subject:抽象通知者/主题,一般用一个抽象类或者一个接口实现.它把所有对观察者对象的引用保存在一个聚集里,每个主题都可以由任何数量的观察者.抽象主题提供一个接口,可以增加和删除观察者对象 abstract class Subject{private IListObserver observers new ListObserver();//增加观察者public void Attach(Observer observer){observers.Add(observer);}//删除观察者public void Detach(Observer observer){observers.Remove(observer);}//通知public void Notify(){foreach (Observer o in observers)o.Update();}}
Observer类抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己.这个接口叫做更新接口.抽象观察者一般用一个抽象类或者一个接口实现.更新接口通常包含一个Update()方法,这个方法叫做更新方法.
abstract class Observer
{public abstract void Update();
}
ConcreteSubject具体主题/具体通知者,将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知.具体主题角色同一个具体子类实现.
class ConcreteSubject : Subject
{private string subjectState;//具体被观察者状态public string SubjectState{get { return subjectState; }set { subjectState value; }}
}
// ConcreteObserver具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调.具体观察者角色可以保存一个指向具体主题对象的引用.具体观察者角色通常用一个具体子类实现. class ConcreteObserver : Observer{//成员变量private string name;private string observerState;private ConcreteSubject subject;//构造方法public ConcreteObserver(ConcreteSubject subject,string name){this.subject subject; //赋值this.name name;}//重写抽象类Update方法public override void Update(){observerState subject.SubjectState; //赋值Console.WriteLine(观察者{0}的新状态是{1}, name, observerState); //控制台输出结果}//具体观察者状态public ConcreteSubject Subject {get { return subject; }set { subject value; }}}
观察者模式的动机是将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就需要维护相关对象间的一致性.我们不希望为了维持一致性而使各类紧密耦合,这样会给维护\扩展和重用都带来不便. 六、这个模式涉及到了哪些知识点
①、一个类里面有哪些东西 ②、字段和属性
字段
是什么与类相关的变量
干什么的用来保存数据
属性
是什么一个方法或一对方法
什么作用具有两个方法get、set访问器读、写值
get访问器返回与声明的属性相同的数据类型表示的意思是调用时可以得到内部字段的值或引用set访问器没有显式设置参数但它有一个隐式参数用关键字value表示它的作用是调用属性时可以给内部的字段或引用赋值
显示和隐式字段初始化
字段的初始值必须是编译时可确定的。
如果没有初始化语句字段的值会被编译器设为默认值默认值由字段的类型决定。每种值类型的默认值都是0bool型是false引用类型默认为null。
class MyClass、
{int F1; //初始化为0 -值类型string F2; //初始化为null -引用类型int F3 25; //初始化为25string F4abcd; //初始化为“abcd”//声明多个字段东逗号分隔int F1,F3 25;string F2,F4abcd;
} ③、访问修饰符
什么作用指定程序的其他部分如何访问成员
有哪些
private私有的只在类的内部可访问成员默认是这个public公有的对任何类可访问protected受保护的只允许该类的派生类访问internal内部的同一项目所有类可访问 ④、构造方法
目的对类进行初始化
特点与类同名无返回值、无void、在new时候调用
所有的类都有构造方法不带参数的构造方法称为“默认构造方法”如果你不编码则系统默认生成空的构造方法。若定义了新的构造方法那么默认的构造方法就会失效。 ⑤、方法重载
目的在不改变原方法的基础上新增功能
特点一同二不同多个方法名相同、参数类型/个数不同
class Animal
{private string name;//方法重载方法名相同、数据类型/个数不同public Animal{} //无参的构造方法public Animalstring name //有参的构造方法{this.name name;}
} ⑥、foreach循环
连续访问数组中的每一个元素。
//语法
foreachType Identifier in ArrayNameStatement//实例
int[] arr1 {10,11,12,13}foreachint item in arr1Console.WriteLine(Item Value:{0},item); ⑦、List泛型集合
arrayList集合不知道存什么类型不知道存多少个List知道存什么类型不知道存多少个。就是为了专门处理某种类型在尖括号中写什么类型这个集合就变成了什么类型的集合添加数据、插入数据、索引访问数据都是这个类型的不用考虑所有的转换问题
static void Main(string[] args)
{Listint list new Listint(); //实例化int类型//随机的往这个List集合中添加十个数字不能重复求和求最大值求最小值求平均值Random r new Random();int num 0;while (list.Count !10){num r.Next(1, 100);if (!list.Contains (num)){list.Add(num);}}Console.WriteLine(最大值{0},list.Max ());Console.WriteLine(最小值{0},list.Min ());Console.WriteLine(和为{0},list .Sum ());Console.WriteLine(平均值为:{0},list.Average ());Console.ReadKey();Liststring listStr new Liststring(); //实例化string类型listStr.Add(哈哈小杨又变帅了);
}
⑧、数组、ArrayList和List三者之间的对比 ⑨、抽象类
目的抽取相同代码实现封装思想
特点
抽象类不能实例化抽象方法是必须被子类重写的方法如果类中包含抽象方法那么类就必须定义为抽象类不论是否还包含其他一般方法 ⑩、重写
将父类实现替换为它自己的实现 虚成员 抽象成员 关键字 virtual abstract 实现体 有实现体 没有实现体被分号取代 在派生类中被覆写 可重写也可不重写使用override 必须被重写使用override ⑩①、接口
接口提出了一种契约或者说规范让使用接口的程序设计人员必须严格遵守接口提出的约定。接口就可以看做是这种标准它强制性地要求派生类必须实现接口约定的规范以保证派生类必须拥有某些特性。
特点
不能实例化不能有构造方法和字段不能有修饰符接口包含事件、索引器、方法、属性不包含方法的实现实现接口的类必须实现接口中的所有方法和属性 ⑩②、六大原则依赖倒转原则
-高层模块不应该依赖底层模块。两个都应该依赖抽象接口/抽象类。
-抽象不应该依赖细节具体类。细节应该依赖抽象。
我现在要设计一个汽车我先设计汽车大概的样子先设计轮胎根据轮胎在设计底盘根据底盘在设计车身。现在我想要修改轮胎的尺寸是不是就需要修改底盘修改车身整个全部都得修改如果我们倒过来看在设计车身根据车身在设计底盘根据底盘在设计轮胎这样的话如果轮胎的尺寸变了也不会影响到其他的部分
谁也不要依赖谁除了约定的接口大家都可以灵活自如。 针对书上所举的例子无论主板、CPU、内存、硬盘都是在针对接口设计的。CPU作为主板上一个可移动的、可扩展的部分在设计主板的时候只需要把接口定义好内部再复杂我也不让外界知道而主板只需要预留与CPU阵脚的插槽就可以了。内存、硬盘、显卡都是如此哪部分坏了直接更换那部分就行了而不会导致整个主板全部都要换。 ⑩③、六大关系
依赖使用关系一个类的使用需要另一个类的协助
实现局部变量、构造方法的参数、静态方法的调用
图形虚线箭头指向被拥有者 Animal {Public Water Grownup(Water water) {return null;}
} 关联拥有关系一个类需要使用另一个类的属性和方法
实现成员变量
图形实线箭头 class Water {public Climate m_Climate;public Water(){}
}class Climate {public Climate() {}
} 聚合整体和部分的关系部分不能脱离整体而单独存在
实现成员变量构造方法的参数赋值
图形实线空心菱形菱形指向整体 class GooseGroup {public Goose goose;Public GooseGroup(Goose goose) {this.goose goose;}
}
class Work
{private State current;public Work(){current new ForenoonState();}
}
继承子类继承父类
实现子类父类
图形实线空心三角形箭头指向父类
class Cat:Animal
{} 实现类和接口的关系类实现接口的所有特征
实现类接口
图形虚线空心三角箭头指向接口 Class WideGoose:Ifly
{ }