常用设计模式实例解析

您所在的位置:网站首页 柠檬的原产地在哪 常用设计模式实例解析

常用设计模式实例解析

2024-06-16 08:12| 来源: 网络整理| 查看: 265

常用设计模式实例解析 一、设计模式简介二、单例模式2.1 概念2.2 单例模式实现方式2.2.1 饿汉式2.2.2 懒汉式 2.2.3 测试 三、工厂模式四、策略模式

一、设计模式简介

设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。 1995 年,GoF(Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称 GoF设计模式 。 当然,软件设计模式只是一个引导,在实际的软件开发中,必须根据具体的需求来选择:

对于简单的程序,可能写一个简单的算法要比引入某种设计模式更加容易对于大型项目开发或者框架设计,用设计模式来组织代码显然更好 二、单例模式 2.1 概念

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注: 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。

2.2 单例模式实现方式

单例模式主要由两种实现方式:懒汉式、饿汉式

2.2.1 饿汉式

描述: 程序一运行首先就把单例对象创建出来了,要用的时候直接返回即可,这种方式是单例模式中最简单的一种实现方式。但是问题也比较明显,单例在还没有使用到的时候,初始化就已经完成了。也就是说,如果程序从头到尾都没用使用这个单例的话,单例的对象还是会创建,这就造成了不必要的资源浪费。 优点: 线程安全,不用加锁,执行效率高 缺点: 类加载就实例化对象,不能延时加载而对象不一定立刻调用,容易产生垃圾对象,浪费内存 实例解析:

public class SingleObj { private static SingleObj s1 = new SingleObj(); //定义静态方法构造方法,只调用一次 private SingleObj(){} //构造方法私有化 public static SingleObj getInstance(){ return s1; } } 2.2.2 懒汉式

描述: 在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例 优点: 类加载快,可以延时加载 缺点: 线程不安全,要实现线程安全需加锁,使用 synchronized 关键字 实例解析:

public class SingleObjLanHan { private SingleObjLanHan(){} private static SingleObjLanHan s2; public synchronized static SingleObjLanHan getInstance(){ //加锁,避免多线程同时被调用 if(s2 == null) { s2 = new SingleObjLanHan(); } return s2; } } 2.2.3 测试 public class TestZuGuo { public static void main(String[] args) { //饿汉模式 SingleObj e1 = SingleObj.getInstance(); SingleObj e2 = SingleObj.getInstance(); if(e1.equals(e2)){ System.out.println(true); }else { System.out.println(false); } //打印结果为true,说明只创建了一次对象 //懒汉模式 SingleObjLanHan l1 = SingleObjLanHan.getInstance(); SingleObjLanHan l2 = SingleObjLanHan.getInstance(); if(l1.equals(l2)){ System.out.println(true); }else { System.out.println(false); } //打印结果为true,说明只创建了一次对象 } } 三、工厂模式

工厂模式(Factory Pattern)是一种创建型模式,在创建对象时不会对客户端暴露创建逻辑,是通过使用一个共同的接口来指向新创建的对象。 目的: 优化创建对象的方式 如何实现: 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行 优点:

调用者想创建一个对象,只要知道其名称就可以了扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以屏蔽产品的具体实现,调用者只关心产品的接口

缺点: 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖

实例解析:

下面模拟不同品牌的工厂生产商品的过程

①:首先创建一个产品的抽象类 Product

public abstract class Product { private String type; //品牌 private String name; //名字 private Double price; //价格 public String getType() { return type; } public String getName() { return name; } public Double getPrice() { return price; } public Product() { } public Product(String type, String name, Double price) { this.type = type; this.name = name; this.price = price; } public abstract void function(); //定义一个抽象方法,展示功能 public abstract void showMsg(); //定义一个抽象方法,展示商品信息 }

②:创建一个工厂接口 Factory ,用于生产各种类型的产品

public interface Factory { public Product newProduct(int Choose); //根据输入编号选择生产那种产品 }

③:创建格力、美的两个工厂类,继承 Factory 接口 格力工厂:

public class GeLi implements Factory{ //有三款产品: 1.空调 2.洗衣机 3.冰箱 @Override public Product newProduct(int choose) { if(choose == 1) { return new KongTiao("格力空调", "悦风", 2688.0); } else if(choose == 2){ return new XiYiJi("格力洗衣机"," XQG80",3999.0); } else if(choose == 3){ return new BiXiang("格力冰箱"," 晶弘",2799.0); }else return null; } }

美的工厂:

public class MeiDi implements Factory{ //有三款产品: 1.空调 2.洗衣机 3.冰箱 @Override public Product newProduct(int choose) { if (choose == 1) { return new KongTiao("美的空调", "智弧", 2199.0); } else if (choose ==2) { return new BingXiang("美的洗衣机","小天鹅",3299.0); }else if(choose == 3){ return new XiYiJi("美的冰箱","BCD-230WTPZM(E)",1999.0); } else { return null; } } }

④:创建空调、洗衣机、冰箱三个产品类,继承父类 Product 空调:

public class KongTiao extends Product{ public KongTiao() {} public KongTiao(String type, String name, Double price) { super(type, name, price); } @Override public void function() { System.out.println("调节温度"); } @Override public void showMsg() { System.out.println( "当前产品为:"+super.getType()+ " 名字:" +super.getName()+ " 价格:" +super.getPrice()); } }

洗衣机:

public class XiYiJi extends Product{ public XiYiJi() {} public XiYiJi(String type, String name, Double price) { super(type, name, price); } @Override public void function() { System.out.println("洗衣服"); } @Override public void showMsg() { System.out.println( "当前产品为:"+super.getType()+ " 名字:" +super.getName()+ " 价格:" +super.getPrice()); } }

冰箱:

public class BingXiang extends Product{ public BingXiang() { } public BingXiang(String type, String name, Double price) { super(type, name, price); } @Override public void function() { System.out.println("储存食物"); } @Override public void showMsg() { System.out.println( "当前产品为:"+super.getType()+ " 名字:" +super.getName()+ " 价格:" +super.getPrice()); } }

⑤创建测试类 TestFactory ,模拟生产

public class TestFactory { public static void main(String[] args) { Factory geli = new GeLi(); //实例化格力工厂 Factory meidi = new MeiDi(); //实例化美的工厂 Product product1 = geli.newProduct(1); if(product1 != null){ product1.function(); product1.showMsg(); } System.out.println("-------分割线-------"); Product product2 = meidi.newProduct(2); if (product2 !=null){ product2.function(); product2.showMsg(); } } } /* 控制台打印 调节温度 当前产品为:格力空调 名字:悦风 价格:2688.0 -------分割线------- 储存食物 当前产品为:美的洗衣机 名字:小天鹅 价格:3299.0 */

下面是重点内容:

现在有需求要生产电饭煲,则新建一个产品类 DianFanBao

public class DianFanBao extends Product{ public DianFanBao() {} public DianFanBao(String type, String name, Double price) { super(type, name, price); } @Override public void function() { System.out.println("一键煮饭"); } @Override public void showMsg() { System.out.println( "当前产品为:"+super.getType()+ " 名字:" +super.getName()+ " 价格:" +super.getPrice()); } }

假设在美的工厂生产,则在美的工厂类中加入编号4,生产电饭煲:

public class MeiDi implements Factory{ //有四款产品: 1.空调 2.洗衣机 3.冰箱 4.电饭煲 @Override public Product newProduct(int choose) { if (choose == 1) { return new KongTiao("美的空调", "智弧", 2199.0); } else if (choose ==2) { return new BingXiang("美的洗衣机","小天鹅",3299.0); }else if(choose == 3){ return new XiYiJi("美的冰箱","BCD-230WTPZM(E)",1999.0); } else if(choose == 4){ return new DianFanBao("美的电饭煲"," MB-FB40",259.0); }else { return null; } } }

这样封装好之后,生产者想要生产电饭煲,只需填入一个数字4即可产生对象显示产品相关信息 注:如果要增加工厂也是一个道理,创建一个工厂类继承Factory接口,重写接口中想要生产产品的方法即可

四、策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改,这种类型的设计模式属于行为型模式。

目的:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换 如何实现:将算法封装成一个一个的类,任意地替换 关键代码:实现同一个接口 优点:

算法可以自由切换避免使用多重条件判断扩展性良好

缺点:

策略类会增多所有策略类都需要对外暴露

示例解析: 以 上文 工厂模式 中的实例来说明 假设在测试类中不直接实例化工厂类的前提下,我想要生产空调,展示相关信息,是如何实现的呢? 这里可以将工厂类再进一步进行封装,通过输入数字编号,策略性的选择用哪家工厂生产空调

创建一个策略类 Strategy

//策略模式 public class Strategy { public Factory getFactory(String brandName){ if(brandName.equals("gl")){ return new GeLi(); }else if (brandName.equals("md")){ return new MeiDi(); }else if(brandName.equals("he")){ return new Hair(); }else if(brandName.equals("xk")){ return new XingKe(); }else { return new XingKe(); } } //zl 空调总体的知名度 1一线 2二线 3三线 // aj 空调静音效果 1 超静 2安静 3静 // jg 价格 1高 2 中 3低 public Product getByKongTiaoCondition(Integer zl,Integer aj,Integer jg){ Product product = null; if(zl == 1){ product=getFactory("gl").newProduct(1); }else if(zl == 2){ if(aj


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3