1.设计模式:
设计模式就是代码设计经验
2.设计模式的类型:
分为三大类:创建型模式,结构型模式,行为模式
创建型模式:
单例模式:某个类只能有一个实例,提供一个全局的访问点。
工厂模式:一个工厂类根据传入的参数决定创建出那一种产品类的实例。
抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。
建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。
原型模式:通过复制现有的实例来创建新的实例。
结构型模式
适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。
组合模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构。
装饰模式:动态的给对象添加新的功能。
代理模式:为其他对象提供一个代理以便控制这个对象的访问。
亨元模式:通过共享技术来有效的支持大量细粒度的对象。
外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。
桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。
行为型模式
模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。
解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。
策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。
状态模式:允许一个对象在其对象内部状态改变时改变它的行为。
观察者模式:对象间的一对多的依赖关系。
备忘录模式:在不破坏封装的前提下,保持对象的内部状态。
中介者模式:用一个中介对象来封装一系列的对象交互。
命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素的新功能。
责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。
迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。
3.单例模式:
1.一个类只有一个实例
2.只提供一个全局访问点
3.自我实例化( 一个对象在其自身的定义中创建自己的实例 )
懒汉模式在第一次调用时才创建实例,适合节省资源,但需要考虑线程安全问题。
饿汉模式在类加载时就创建实例,确保线程安全,但会占用更多资源,可能在不需要时也会初始化。
饿汉模式1:
很形象,通过getxxx静态方法把静态对象返回出去
这里的对象是私有的,防止外头的人修改,起到保护的作用
返回对象
public class UserMassage {//这是饿汉模式1//创建静态对象,自我实例化public static final UserMassage usermassage = new UserMassage();//提供全局访问点public static UserMassage getUsermassage(){return usermassage;}public void show(){System.out.println("我是单例模式");}}
饿汉模式2:
public class UserMassage2 {//饿汉模式2public static final UserMassage2 usermassage;static {usermassage = new UserMassage2();}public void show(){System.out.println("我是单例模式");}
}
懒汉模式:
先把静态对象设为null
判断静态对象是否为null
为null则生产一个返回
不为null则用这个对象
public class LayManModel {//懒汉模式//私有静态变量保存实例private static LayManModel layManModel;//提供公共的获取实例的方法public static LayManModel getInstance() {//使用synch保证线程安全if (layManModel == null) {synchronized (LayManModel.class) {if (layManModel == null) {layManModel = new LayManModel();}}}return layManModel;}public void show () {System.out.println("我是懒汉模式");}}
测试代码:
1.== 用来判断地址从而判断是否是同一个对象
2.通过全局访问点来创建对象
public class Main2 {public static void main(String[] args) {LayManModel layManModel1 = LayManModel.getLayManModel();LayManModel layManModel2 = LayManModel.getLayManModel();System.out.println(layManModel1 == layManModel2);layManModel1.show();}
}
优点:
在内存中只有一个实例,避免频繁的创建和销毁实例
缺点:
没有接口,不能继承
注意事项:getUserMassage() 方法中需要使用同步锁 synchronized (UserMassage.class) 防止多线程
同时进入造成 UserMassage被多次实例化
4.工厂模式:
优点
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定
程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事 。
面条接口:
public interface MianTiao {//面条抽象类public abstract void des();}
三种产品:三种面条
拉面:
public class LaMian implements MianTiao{@Overridepublic void des() {System.out.println("我是拉面,兰州的拉面");}
}
泡面:
public class PaoMian implements MianTiao{@Overridepublic void des() {System.out.println("我是泡面,大家都不爱吃的泡面");}
}
烩面:
public class HuiMian implements MianTiao{@Overridepublic void des() {System.out.println("我是烩面,河南人爱吃的烩面");}
}
测试方法:
public class Main {//传入我要生产面public static void main(String[] args) {MianTiao miantiao = SimpleNoodlesFactory.createNoodles(LA_MIAN);miantiao.des();}
}
工厂:
public class SimpleNoodlesFactory {//简单面条工厂protected static final int PAO_MIAN = 1;protected static final int LA_MIAN = 2;protected static final int HUI_MIAN = 3;//这个方法是关键,用来生产的public static MianTiao createNoodles(int type) {switch (type) {case PAO_MIAN:return new PaoMian();case LA_MIAN:return new LaMian();default:return new HuiMian();}}
}
抽象工厂:
因为工厂和工厂不一样,这个是面条工厂,我们随着企业的扩大需要包子工厂,生产工厂的工厂就是抽象工厂,也叫二级工厂。
5.装饰模式:
装饰模式是用来替代继承的一种设计模式。它通过一种无须定义子类的方式来给对象动态增加职责,使
用对象之间的关联关系取代类之间的继承关系。降低了系统的耦合,可以动态的增加或者删除对象的职 责
接口:
public interface Showable {//展示接口public abstract void show();
}
装饰器:
public abstract class Decorator implements Showable{Showable showable ;//持有一个善于展示自己某个家伙//抽象装饰器//构造函数public Decorator(Showable showable){this.showable = showable;}//无需实现因为现在装饰器还不知道如何修饰public abstract void show();
}
装饰对象:
public class Girl implements Showable{@Overridepublic void show() {System.out.print("女友的素颜");}
}
装饰功能:
描眉:
public class MiaoMei extends Decorator{public MiaoMei(Showable showable) {super(showable);}//重写接口化妆后展示 描眉@Overridepublic void show() {System.out.print("描眉(");showable.show();System.out.print(")");}
}
涂口红:
public class TuKouHong extends Decorator{public TuKouHong(Showable showable) {super(showable);}@Overridepublic void show() {System.out.print("涂口红(");showable.show();System.out.print(")");}
}
测试方法:
这个装饰模式就是套的方式
和I/O流中的创建可像
public class Main {public static void main(String[] args) {//创建女友对象Girl girl = new Girl();//将女友放入描眉类MiaoMei lyw = new MiaoMei(girl);TuKouHong cmy = new TuKouHong(lyw);cmy.show();}
}
6.代理模式:
代理模式 指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其他相关 业务的处理。
/*
* 定义Network接口
*/
public interface Network {
public void browse(); // 定义浏览的抽象方法
}
/*
* 真实的上网操作
*/
public class Real implements Network {
//重写抽象方法
public void browse() {
System.out.println("上网浏览信息!");
}
}
/*
* 代理上网
*/
public class Proxy implements Network {
private Network network;
// 设置代理的真实操作
public Proxy(Network network) {
this.network = network; // 设置代理的子类
}
// 身份验证操作 其他操作
public void check() {
System.out.println("检查用户是否合法!");
}
//代码实现上网
public void browse() {
this.check(); // 调用具体的代理业务操作
this.network.browse(); // 调用真实的上网操作
}
}
public static void main(String args[]) {
Network net = null; // 定义接口对象
net = new Proxy(new Real()); // 实例化代理,同时传入代理的真实操作
net.browse(); // 调用代理的上网操作
}
7.观察者模式
就是举个例子:订报纸
报纸厂家和订阅报纸的人之间这种一对多的就可以称为观察者模式
报纸厂家是被观察者
订阅报纸的人是观察者
当你订阅了 一份报纸,每天都会有一份最新的报纸送到你手上,有多少人订阅报纸,报社就会发多少份报纸,报社 和订报纸的客户就是上面文章开头所说的“一对多”的依赖关系
奶厂:
接口:
public interface Subject {//订阅void attach(Observer observer);//取消订阅void detach(Observer observer);//通知变动void notifyChanged();}
实例:
public class RealSubject implements Subject{//奶厂//本奶厂下订奶的人集合private List<Observer> observerList = new ArrayList<Observer>();//添加订阅者@Overridepublic void attach(Observer observer) {observerList.add(observer);}//删除订阅者@Overridepublic void detach(Observer observer) {observerList.remove(observer);}//消息通知订阅者@Overridepublic void notifyChanged() {for (Observer observer : observerList) {observer.update();}}}
订牛奶的:
接口:
package ObserverTest;public interface Observer {/*** 接收变动通知*/void update();
}
实例:
package ObserverTest;public class RealObject implements Observer{//奶厂@Overridepublic void update() {System.out.println("通知");}
}
测试方法:
public class mainTest {public static void main(String[] args) {Subject subject = new RealSubject(); //创建奶厂Observer observer = new RealObject();//创建订阅人subject.attach(observer);//订阅人订阅 subject奶厂subject.notifyChanged();//奶厂发布消息 订阅者接收}
}
奶厂可以管理订牛奶的,删除,添加或者发布消息
订牛奶的只能接收消息
总结:
通过定义一个抽象接口 Subject(奶厂),我们可以将 奶厂 和 订奶的人 的行为统一起来。