这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/2021Softwarecodedevelopmenttechnology |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/2021Softwarecodedevelopmenttechnology/homework/11833 |
这个作业的目标 | 1.学习软件设计模式的分类和各种模式的基本内容 |
2.了解软件设计原则 |
郑阿奇《软件秘笈:设计模式那点事》
1. 基本内容
1.1 什么是设计模式
设计模式代表了最佳的实践,是软件开发人员在软件开发的过程中面临的一般问题的解决方案。
1.2 设计模式的类型
- 创建型模式
- 工厂模式
- 抽象工厂模式
- 单例模式
- 建造者模式
- 原型模式
- 结构性模式
- 适配器模式
- 桥接模式
- 组合模式
- 装饰器模式
- 外观模式
- 享元模式
- 代理模式
- 行为模式
- 责任链模式
- 命令模式
- 解释器模式
- 迭代器模式
- 中介器模式
- 备忘录模式
- 观察者模式
- 状态模式
- 空对象模式
- 策略模式
- 模板模式
- 访问者模式
1.3 设计模式的六大原则
-
开闭原则
“对拓展开放,对修改关闭”。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简而言之,就是为了使程序的拓展性好,易于维护和升级。我们可以使用接口或抽象类达到这样的效果。 -
里氏代换原则
“任何基类可以出现的地方,子类一定可以出现”。只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。 -
依赖倒转原则
“面向接口编程”。依赖于抽象而不依赖于具体。 -
接口隔离原则
“使用多个隔离的接口,比使用单个接口更好”。降低类之间的耦合度。其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。 -
最少知道原则
“一个实体应当尽量少地与其他实体之间发生相互作用”,主要是为了使系统功能模块相对独立。 -
合成复用原则
“尽量使用合成或者聚合的方式,而不是使用继承”。
2. 心得体会
2.1 工厂模式
工厂模式可能是在开发中接触得最多的一种设计模式。它属于创建型模式,该模式通过向工厂传递类型来指定要创建的对象。
假设我们有一个工厂,可以生产A汽车和B汽车,那么我们就可以通过工厂传入参数来确定拿到的是A汽车还是B汽车。
/**
汽车接口
*/
public interface Car {
void run();
}
/**
A汽车
*/
public class ACar implements Car{
@Override
public void run() {
System.out.println("A car is running...");
}
}
/**
B汽车
*/
public class BCar implements Car{
@Override
public void run() {
System.out.println("B car is running...");
}
}
/**
汽车工厂
*/
public class CarFactory {
//通过传入参数来确定生产哪种汽车
public Car createCar(String carName){
if (carName.equals("ACar")){
return new ACar();
}else{
return new BCar();
}
}
}
优点:
- 易于解耦:将产品本身和产品创建过程解耦,可以使用相同的过程得到不同的产品,也就是说细节依赖抽象。
- 封装性好:使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。
- 容易进行扩展:如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险
缺点: - 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
2.2 单例模式
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。注意关键在于构造函数是私有的,这样做就可以避免外界可以直接创建新的对象,使得当前对象并不唯一。有使用过spring的同学都很清楚,单例模式在spring中被频繁地应用,因为单例模式可以节省系统资源。
代码实现:
- 懒汉式:实例在初始化的时候就已经创建好了,好处在于没有线程安全问题,坏处在于浪费内存空间(不管有没有用,都得创建这个对象)。
/**
* 单例模式的第一种实现
*/
public class Singleton {
/**
* 懒汉式
*/
private static Singleton object = new Singleton();
/**
* 构造函数私有,避免外界能够直接创建对象
*/
private Singleton(){
}
public static Singleton getInstance(){
return object;
}
}
- 饿汉式:在需要使用的时候才去创建,使用的时候如果对象为空,则创建对象,否则直接返回对象。有线程安全与线程不安全两种写法。
/**
* 单例模式的第二种实现
*/
public class Singleton {
/**
* 懒汉式
*/
private static Singleton object;
/**
* 构造函数私有,避免外界能够直接创建对象
*/
private Singleton() {
}
public static Singleton getInstance() {
if (null == object) {
object = new Singleton();
}
return object;
}
}
- 双重检验:在实现上保证了懒汉式的优点,双重判空的机制保证了线程安全并且提高了效率。
/**
* 单例模式的第三种实现
*/
public class Singleton {
/**
* 懒汉式
*/
private static volatile Singleton object;
/**
* 构造函数私有,避免外界能够直接创建对象
*/
private Singleton() {
}
public static Singleton getInstance() {
//如果对象已经存在,则不必每次都阻塞地判空
if (null == object){
//需要锁定类,因为只有类才是唯一的
synchronized (Singleton.class){
//在线程安全的情况下判断对象是否为空
if (null == object){
object = new Singleton();
}
return object;
}
}
return object;
}
}
- 静态内部类:利用了静态内部类的特性,即内部类只有在需要用到的时候才加载,这就实现了类似双重检验的机制达到延迟初始化的目的。
/**
* 单例模式的第四种实现
*/
public class Singleton {
private static class SingletonInner{
private static final Singleton object = new Singleton();
}
/**
* 构造函数私有,避免外界能够直接创建对象
*/
private Singleton() {
}
public static Singleton getInstance() {
return SingletonInner.object;
}
}
- 枚举:这是由于枚举类的特性决定的,线程安全,构造器私有。
/**
* 单例模式的第五种实现
*/
public enum Singleton {
OBJECT("object"),JAVA("java");
private String name;
Singleton(String name) {
this.name = name;
}
}
3. 编辑界面截图
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:读书笔记—-软件设计原则、设计模式 - Python技术站