源码说明:
HINKPHP二开仿网易云课堂整站源代码,界面美观大气!整体界面及前后台登陆都非常漂亮。HINKPHP二开仿网易云课堂整站源代码,界面美观大气!整体界面及前后台登陆都非常漂亮。全开源版本,适合二次开发。

安装说明:

1、上传到网站根目录
2、用phpMyadmin导入数据库文件sasadown.sql
3、修改数据库链接文件 \Application\Admin\Conf\config.php和\Application\Home\Conf\config.php8
(记得不要用记事本修改,否则可能会出现验证码显示不了问题,建议用Notepad )

4、后台目录 /admin.php

帐号 sasadown 密码 sasadown

文件:590m.com/f/25127180-499032173-97ae15(访问密码:551685)

以下内容无关:

-------------------------------------------分割线---------------------------------------------

一、设计模式的分类
总的来说,设计模式可以分为三大类:创建型模式、结构型模式、行为型模式,具体如下图:

设计模式.png

二、工厂模式
工厂模式分为简单工厂模式、工厂方法模式和抽象工厂模式。其中简单工厂模式并不属于23种设计模式,但并不影响它的广泛使用。在JDK的源码当中,就存在着许多这样的例子。

2.1 简单工厂模式
我们先来看一段代码:

1
2
3
4
5
6
7
8
public static void main(String[] args) {
// 日历类
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
System.out.println(“当前时间为:” + simpleDateFormat.format(calendar.getTime()));
calendar.add(Calendar.HOUR,2);
System.out.println("当前时间加了两个小时后,时间是: " + simpleDateFormat.format(calendar.getTime()));
}
这段代码,大家应该比较熟悉,通过对Calendar的一系列操作,打印出当前时间和当前时间加两个小时后的时间,这里我们来看看结果:

image20210618100232505.png

结果正和我们想象的一样,两次打印出来的时间相隔两个小时。但我们今天的重点是Calendar calendar = Calendar.getInstance()这段代码,通过getInstance()方法拿到了Calendar类的实例。来看看具体的源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static Calendar getInstance(){
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}

// 代码不全,有兴趣的朋友可以去看JDK源码
private static Calendar createCalendar(TimeZone zone, Locale aLocale){
// 中间的代码省略…
Calendar cal = null;
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType(“ca”);
if (caltype != null) {
switch (caltype) {
case “buddhist”:
cal = new BuddhistCalendar(zone, aLocale);
break;
case “japanese”:
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case “gregory”:
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
// 中间的代码省略…
return cal;
}
可以看出,getInstance()方法里面调用了createCalendar()方法来得到Calendar类的实例,最后返回给调用者。而createCalendar()方法中通过switch(){case}的判断来返回所对应的Calendar类的实例,这其实就是简单工厂模式的一种应用。

看完简单工厂模式在JDK中的应用之后,我们来设计一下自己的例子:

小明家新开了一家小工厂,接了一单生意,帮助海尔(Haier)集团生产冰箱,并需要设计相应的方案。小明本身也是程序员出身,思考一会后就写出了下面的代码:

1
2
3
4
5
6
7
8
9
/**

  • 冰箱
    */
    public interface IFridge {

    // 生产冰箱
    public void createFridge();

}
1
2
3
4
5
6
7
8
9
/**

  • 海尔
    */
    public class Haier implements IFridge {
    @Override
    public void createFridge() {
    System.out.println(“生产海尔冰箱…”);
    }
    }
    客户端调用代码:

1
2
3
4
public static void main(String[] args) {
IFridge iFridge = new Haier();
iFridge.createFridge();
}
看上面的代码,父类IFridge类指向子类Haier类的引用,应用层需要依赖于Haier。如果业务扩展,后续增加格力(Gree)甚至更多,那么客户端这里的代码会越来越臃肿。所以,我们要想办法将这种依赖减弱,将创建IFridge对象的细节隐藏掉。我们用简单工厂模式优化一下:

创建Gree格力类

1
2
3
4
5
6
7
8
9
/**

  • 格力
    */
    public class Gree implements IFridge {
    @Override
    public void createFridge() {
    System.out.println(“生产格力冰箱…”);
    }
    }
    创建FridgeFactory工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**

  • 冰箱工厂
    */
    public class FridgeFactory {

    // 创建对应的 IFridge 实例
    public static IFridge createFridge(String name){
    if (“haier”.equals(name)){
    return new Haier();
    } else if (“gree”.equals(name)){
    return new Gree();
    }
    return null;
    }
    }
    修改客户端调用的代码:

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
// 海尔
IFridge haier = FridgeFactory.createFridge(“haier”);
haier.createFridge();

// 格力
IFridge gree = FridgeFactory.createFridge("gree");
gree.createFridge();

}
这样来看,虽然代码多了,但维护起来以及扩展起来就方便很多,来看一看类图:

image20210618104712505.png

当然,上面的FridgeFactory代码中依旧有些问题,如果我们需要增加生产美的(Midea)冰箱,那么我们就需要去修改createFridge()方法的代码,显然违背了开闭原则,我们来改造一下:

修改FridgeFactory工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**

  • 冰箱工厂
    */
    public class FridgeFactory {

    // 创建对应的 IFridge 实例
    public static IFridge createFridge(String className){
    try {
    if (null != className && !"".equals(className)){
    // 反射
    return (IFridge)Class.forName(className).newInstance();
    }
    }catch (Exception e){
    e.printStackTrace();
    }
    return null;
    }
    }
    修改客户端调用的代码

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
// com.xxx.Haier 换成 自己 项目中 Haier 所在的位置 海尔
IFridge haier = FridgeFactory.createFridge(“com.xxx.Haier”);
haier.createFridge();

// com.xxx.Gree  换成  自己 项目中 Gree 所在的位置  格力
IFridge gree = FridgeFactory.createFridge("com.xxx.Gree");
gree.createFridge();

}
优化之后,我们再也不需要随着业务的提升而去修改FridgeFactory类中的代码了。但是依旧有一个问题,createFridge()方法中的参数是字符串,如果有人乱填怎么办,那不就报错了,所以再来优化一下:

修改FridgeFactory工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**

  • 冰箱工厂
    */
    public class FridgeFactory {

    // 创建对应的 IFridge 实例
    public static IFridge createFridge(Class<? extends IFridge> clazz){
    try {
    if (clazz != null){
    return clazz.newInstance();
    }
    }catch (Exception e){
    e.printStackTrace();
    }
    return null;
    }
    }
    修改客户端调用的代码

1
2
3
4
5
6
7
public static void main(String[] args) {
// 海尔
FridgeFactory.createFridge(Haier.class).createFridge();

// 格力
FridgeFactory.createFridge(Gree.class).createFridge();

}
再来看一下类图:

image20210618110204756.png

简单工厂模式虽然好用,但也有它的局限性:工厂类的职责过重,不利于扩展更为复杂产品结构。

2.2 工厂方法模式
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。

在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符合开闭原则。

随着小明家新工厂的生意火爆,各类的订单都纷涌而至,各个牌子的厂家都想让小明家的工厂生产冰箱,小明无奈只能开了分工厂,并根据客户的品牌名给工厂取了对应的名字,其中海尔工厂生产海尔的冰箱,格力工厂生产格力的冰箱,美的工厂生产美的的冰箱。用代码演化就是下面这般:

IFridgeFactory类接口

1
2
3
public interface IFridgeFactory {
public IFridge createIFridge();
}
海尔

1
2
3
4
5
6
7
// 海尔 工厂
public class HaierFactory implements IFridgeFactory {
@Override
public IFridge createIFridge() {
return new Haier();
}
}
格力

1
2
3
4
5
6
7
// 格力 工厂
public class GreeFactory implements IFridgeFactory {
@Override
public IFridge createIFridge() {
return new Gree();
}
}
美的

1
2
3
4
5
6
7
8
9
/**

  • 美的
    */
    public class Midea implements IFridge {
    @Override
    public void createFridge() {
    System.out.println(“生产美的冰箱…”);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    // 美的
    public class MideaFactory implements IFridgeFactory {
    @Override
    public IFridge createIFridge() {
    return new Midea();
    }
    }
    客户端调用:

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
// 格力
new GreeFactory().createIFridge().createFridge();

// 海尔
new HaierFactory().createIFridge().createFridge();// 美的
new MideaFactory().createIFridge().createFridge();

}

网易云课堂整站源码 THINKPHP二开仿网易云课堂相关推荐

  1. [整站源码]thinkphp家纺针织床上用品类网站模板+前后端源码

    模板介绍: 本模板自带eyoucms内核,无需再下载eyou系统,原创设计.手工书写DIV+CSS,完美兼容IE7+.Firefox.Chrome.360浏览器等:主流浏览器:结构容易优化:多终端均可 ...

  2. [整站源码]thinkphp古筝古琴书画培训类网站模板+前后端源码

    模板介绍: 本模板自带eyoucms内核,无需再下载eyou系统,原创设计.手工书写DIV+CSS,完美兼容IE7+.Firefox.Chrome.360浏览器等:主流浏览器:结构容易优化:多终端均可 ...

  3. [整站源码]thinkphp美肤微形美容仪器网站模板+前后端源码

    模板介绍: 本模板自带eyoucms内核,无需再下载eyou系统,原创设计.手工书写DIV+CSS,完美兼容IE7+.Firefox.Chrome.360浏览器等:主流浏览器:结构容易优化:多终端均可 ...

  4. LsNAV最新精仿技术导航网完整版整站源码

    介绍: 适用范围:最新精仿技术导航网完整版整站源码 演示地址:(以截图为准) 运行环境:PHP.MYSQL 安装说明:上传服务器解压后运行install即可安装 该导航网具有收录网站+资源发布功能于一 ...

  5. 酷动网博客整站源码+Panda PRO主题+7000条完整数据

    介绍: 说实话这些资源不值钱 图片应该是没有的,我测试的时候是没有显示 酷动网博客博客已经有7000+文章,模板使用的是pandapro-自己修复了很多 有夜间模式,自适应,有海报,支持多种社区分享 ...

  6. 某Q娱乐网emlog程序整站源码

    介绍: 修改主目录config.php数据库 导入数据库小Q娱乐网数据文件.sql 后台账号密码为小Q/asd123- 网盘下载地址: http://kekewl.org/NDr9Ti3w55Y0 图 ...

  7. 漂亮的仿大婶娱乐网模板 娱乐资源网整站源码 laysns内核

    介绍: 漂亮的laysns内核仿大婶娱乐网模板娱乐资源网整站源码打包,PHP+Mysql 网盘下载地址: https://zijiewangpan.com/AzKGCYOfeiZ 图片:

  8. 织梦自适应php源码,HTML5自适应仿WP大学织梦整站源码 v1.0

    HTML5自适应仿WP大学织梦整站源码简介 HTML5自适应仿WP大学织梦整站源码v1.0是一个自适应手机端和PC端的最新版织梦V5.7为内核的网站模板,软件兼容主流浏览器,模板包含安装说明,并包含测 ...

  9. php高仿互站网源码,2020新版友价高仿互站网源码 虚拟交易商城整站源码

    2020新版友价高仿互站网源码 虚拟交易商城站长服务平台整站源码 本套源码自带数据,压缩包大小是2.15G,解压密码是:www.ym3.net,来自于知吗网站整站打包,感兴趣的朋友可自行下载研究.另外 ...

  10. Laysns内核仿qq技术网址导航网整站源码

    介绍: Laysns内核仿qq技术网址导航网整站源码基于laysns开发,打包的也只是模板文件,使用前需要自行下载安装laysns主程序,然后再将模板文件夹上传到template文件夹下替换即可使用. ...

最新文章

  1. 1600802071
  2. sqoop配置与使用
  3. 三分钟了解Mysql的表级锁——《深究Mysql锁》
  4. mqtt 传文件断开连接的原因_MQTT PythonClient断开连接不当
  5. 进入51cto之后的发展方向
  6. Memcached总结三:Memcached常用命令及使用说明
  7. PowerCenter Designer小结
  8. 调整了canvas的高度页面变化后还原_Web 页面录屏实现
  9. Nginx设置TCP上游服务器的SSL配置
  10. C#LeetCode刷题之#443-压缩字符串​​​​​​​(String Compression)
  11. 零门槛!ZBLibrary仿微信朋友圈自定义View,就是这么简单!
  12. Spring Data Jpa的@DynamicInsert注解和@DynamicUpdate注解
  13. 解释汇编中的AUGW LABEL WORD、ADDW LABEL WORD
  14. 反射java 入门_[java 基础]反射入门
  15. js实现身份证验证功能
  16. 离散数学编程实现真值表输出
  17. 「00后缩写黑话翻译器」登上GitHub热榜
  18. Xposed框架的安装包和卸载包的默认下载路径以及网站下载地址
  19. android studio拨打电话代码,AndroidStudio实现拨打电话和发短信(kotlin)
  20. 最全的100个Python精选库,建议收藏!

热门文章

  1. word文件做一半未响应_Word经常出现未响应怎么办?
  2. 行人重识别实验笔记3-JDAI fast-reid项目配置
  3. php中的rtrim_PHP函数rtrim()使用中的怪异现象
  4. 读书笔记之《价值》张磊
  5. 【高等数学】空间直线的参数方程详解以及其参数t的意义
  6. 2022年全球与中国汽车MEMS加速度计市场现状及未来发展趋势
  7. PC版免费京东全民营业自动化做任务脚本(多号版)
  8. CCNA配置试验之八 帧中继——点到点子接口(point-to-point)
  9. 一键开关电路设计(一)
  10. 20145322 何志威《网络对抗》shellcode注入Return-to-libc攻击深入