设计模式介绍
<table><tbody>设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结,它与具体的语言无关,是一种思想,掌握了面向对象的思想,才可以更好的理解设计模式,而反之亦然。
在java中总共有23种设计模式,这些设计模式分别分为如下几种类型:
创建型模式:针对对象的创建方式
结构型模式:针对对象的组成结构的操作
行为型模式:针对对象的行为的操作设置
其中,创建型模式有6种,分别为简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、创建者模式(Builder)、原型模式(Prototype)、单例模式(Singleton)
结构型模式有7种,分别为外观模式/门面模式(Facade门面模式)、适配器模式(Adapter)、代理模式(Proxy)、装饰模式(Decorator)、桥梁模式/桥接模式(Bridge)、组合模式(Composite)、享元模式(Flyweight)
行为型模式有10种,分别为模板方法模式(Template Method)、观察者模式(Observer)、状态模式(State)、策略模式(Strategy)、职责链模式(Chain of Responsibility)、命令模式(Command)、访问者模式(Visitor)、调停者模式(Mediator)、备忘录模式(Memento)、迭代器模式(Iterator)、解释器模式(Interpreter)
以下分别对这三种模式的部分常用模式进行生活案例与程序案例分析:
/<tbody>/<table>创建型模式
1. 单例模式
<table><tbody>生活案例:国家施行的计划生育政策, 规定一对夫妇只生一胎,刚结婚时,确定生一胎,生完后无论如何不能再生,否则违背国家政策。
程序概念:所谓单例设计模式简单说就是无论程序如何运行,采用单例设计模式的类(Singleton类)永远只会有一个实例化对象产生。具体实现步骤如下:
(1) 构造方法私有化(采用private修饰)。
(2) 使用静态方法调用得到单例模式对象。
代码如下所示:
class Singleton {
private static Singleton instance = new Singleton();// 饿汉式
public static Singleton getInstance() {
return instance;
}
private Singleton() { // 构造方法封装为私有化
}
}
public class Test2 {
public static void main(String args[]) {
Singleton s = Singleton.getInstance(); //两个对象一致
Singleton s = Singleton.getInstance();
}
}
/<tbody>/<table>2. 简单工厂模式
<table><tbody>生活案例:一个卖肉工厂可以生产猪肉、狗肉、羊肉、牛肉等,工厂很清楚有哪些的产品,所以我们只需要工厂提供即可
程序概念:简单工厂又叫静态工厂,由一个工厂对象决定创建哪一个产品对象
代码案例如下:
public class Factory{
public static int PIG_TYPE = 1;
public static int DOG_TYPE = 2;
public static Animal getAnimal(int flag) {
if(flag==PIG_TYPE){
return new Pig(); //获取猪肉对象
}else if(flag==DOG_TYPE){
return new Dog(); //获取狗肉对象
}
return null;
}
}
public class Test2 {
public static void main(String args[]) {
//获得狗肉对象
Animal a = Factory.getAnimal(Factory.DOG_TYPE);
}
}
/<tbody>/<table>结构型模式
1. 代理模式
<table><tbody>生活案例:小强喜欢小红,但自己不敢表白,然后叫老王代理自己表白,并且叫老王每天代理自己给小红送花、送早餐...
程序概念:代理模式就给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用
代码案例如下:
interface Network { // 定义Network接口
public void browse(); // 定义浏览的抽象方法
}
class Real implements Network { // 真实的上网操作
public void browse() { // 覆写抽象方法
System.out.println("上网浏览信息!");
}
}
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 class Test2 {
public
Network net = new Proxy(new Real()); //传入代理的真实操作
net.browse(); // 调用代理的上网操作
}
}
/<tbody>/<table>2. 适配器模式
<table><tbody>生活案例:姚明刚进NBA时,因为不会说英语,听不懂指挥战术,这是一个很麻烦的事;那么,有下面两个方案可解决问题:1.让姚明苦练英语,显然不能达到立竿见影效果;2. 让NBA的教练学好中文,显然也不合适;那么应该怎么办呢?很简单,找一个翻译进行中英文对接把战术中的内容进行翻译即可;
程序概念:如果一个类要实现一个具有很多抽象方法的接口,但是本身只需要实现接口中的部分方法便可以达成目的,所以此时就需要一个中间的过渡类,但此过渡类又不希望直接使用,所以将此类定义为抽象类最为合适,再让以后的子类直接继承该抽象类便可选择性的重写所需要的方法,而此抽象类便是适配器类。
代码案例如下:
interface Window {// 定义Window窗口接口,表示窗口操作
public void open();// 窗口打开
public void close();// 窗口关闭
public void iconified();// 窗口最小化
public void deiconified();// 窗口恢复
public void activated();// 窗口活动
}
// 定义抽象类实现接口,在此类中覆写方法,但是所有的方法体为空
abstract
public void open() {};// 窗口打开
public void close() {};// 窗口关闭
public void iconified(){};// 窗口最小化
public void deiconified(){};// 窗口恢复
public void activated(){};// 窗口活动
}
// 子类继承WindowAdapter抽象类,选择性实现需要的方法
class WindowImpl extends WindowAdapter {
System.out.println("窗口打开");// 实现open()方法
}
public void close() {
System.out.println("窗口关闭");// 实现close()方法
}
}
public class Test2 {
public static void main(String args[]) {
Window win = new WindowImpl(); // 实现接口对象
win.open(); // 调用方法
win.close();
}
}
/<tbody>/<table>行为型模式
1. 观察者模式
<table><tbody>生活案例:小强交了两个女朋友,每次需要洗衣服了,就通知两个女朋友来帮他完成洗衣服的任务;下次有需求变更,比如洗袜子任务,那么通知女朋友后,女朋友们能够继续完成这一变更任务
程序概念:观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己
代码案例如下:
class Boy{
private List<girl> list = new ArrayList<>();/<girl>
public void
list.add(girl);
}
public void notifyWash(String msg){
for(Girl girl : list){
girl.wash(msg); //交给女朋友们洗衣服
}
}
}
class Girl{
public void wash(String msg){
System.out.println(msg);
}
}
public class Test2 {
public
Boy boy = new Boy();
Girl girl1 = new Girl();
Girl girl2 = new Girl();
boy.add(girl1); //监听一号女朋友
boy.add(girl2); //监听二号女朋友
boy.notifyWash("赶紧去洗衣服!");
}
}
/<tbody>/<table>2. 策略模式
<table><tbody>生活案例:商场搞促销活动,初级会员打9折,我需要程序员改代码;然后中级会员8折,又得改一次;高级会员,依然要改;如果每次提出需要程序都更新一次,那么这个程序的设计肯定有问题;我们可以改变策略,先把初级、中级、高级会员一一封装起来;用到哪种促销活动则去计算不同折扣
代码案例如下:
interface MemberStrategy {
public double calcPrice(double booksPrice);
}
class PrimaryMemberStrategy implements MemberStrategy {
@Override
System.out.println("对于初级会员的没有折扣");
return booksPrice;
}
}
class AdvancedMemberStrategy implements MemberStrategy {
@Override
public double calcPrice(double booksPrice) {
System.out.println("对于高级会员的折扣为20%");
return booksPrice * 0.8;
}
}
private MemberStrategy strategy; //持有一个具体的策略对象
public Price(MemberStrategy strategy){
this.strategy = strategy; //传入具体的策略对象
}
public double quote(double booksPrice){
return this.strategy.calcPrice(booksPrice);
}
}
public class Test {
public static void main(String[] args) {
//选择并创建需要使用的策略对象
MemberStrategy strategy = new AdvancedMemberStrategy();
//创建环境
Price price = new Price(strategy);
//计算价格
double quote = price.quote(300);
System.out.println("图书的最终价格为:" + quote);
}
}
/<tbody>/<table>