这个作业属于哪个课程 | 2021软件代码开发技术 |
---|---|
这个作业要求在哪里 | 读书笔记----软件设计原则、设计模式 |
这个作业的目标 | 学习设计原则与设计模式,并在以后的开发中有意识地使用合适的设计原则与设计模式 |
学习参考资料:
Design patterns :https://refactoringguru.cn/design-patterns
软件设计模式详解:https://blog.csdn.net/fuhanghang/article/details/83831883
学习内容归纳总结
设计原则
设计原则是在进行软件系统设计时所要遵循的一些经验准则,应用该准则的目的通常是为了避免某些经常出现的设计缺陷。
-
单一职责原则 (Single responsibility principle)
不要存在多于一个导致类变更的原因。对类来说的,即一个类应该只负责一项职责。
-
开闭原则(Open Close Principle)
开闭原则的意思是:对扩展开放,对修改关闭。
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。
-
里氏代换原则(Liskov Substitution Principle)
所有引用基类的地方必须能透明地使用其子类的对象。
只要父类能出现的地方,子类就可以出现,并且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类。但反之,未要求。
-
依赖倒转原则(Dependence Inversion Principle)
这个原则是开闭原则的基础,具体内容为:针对接口编程,依赖于抽象而不依赖于具体。
-
接口隔离原则(Interface Segregation Principle)
这个原则是指:使用多个隔离的接口,比使用单个接口要好。
它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。
-
迪米特法则,又称最少知道原则(Demeter Principle)
最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
-
合成复用原则(Composite Reuse Principle)
合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。
设计模式
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了 可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
设计模式分为三大类:
- 创建型模式:提供创建对象的机制,增加已有代码的灵活性和可复用性。
包括:工厂方法模式、抽象工厂模式、生成器模式、原型模式、单例模式
- 结构型模式:介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
包括:适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、代理模式
- 行为模式:负责对象间的高效沟通和职责委派。
包括:责任链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式
心得体会
我认为设计原则是我们平时进行软件设计时需要遵守的准则,谨记设计原则能避免某些经常出现的设计缺陷。但在实际的软件设计中,设计原则只是一种潜移默化影响我们的准则,更常使用的是设计模式,设计模式作为工具或模板能在软件设计中给予我们很大的帮助。
设计模式提供了一套软件设计的模板给我们使用,在软件设计的过程中,我们可以合理使用合适的软件设计模式解决各种问题,使设计出来的代码更合理,更利于维护。同时设计模式定义了一种团队成员之间能更高效沟通的通用语言,使用正确的设计模式,让团队成员高效地进行合作与开发。
在平时的学习与开发中,我使用最多的是工厂模式与单例模式。
工厂模式和抽象工厂模式
工厂方法模式是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。
工厂方法模式建议使用特殊的工厂方法代替对于对象构造函数的直接调用 (即使用
new
运算符)。 对象仍将通过new
运算符创建,只是该运算符改在工厂方法中调用。工厂方法返回的对象通常被称作 “产品”。
工厂方法模式结构:
//工厂方法模式
//省略产品Axe接口及其实现类,主要看工厂
//增加Factroy接口
public interface Factory {
Axe getAxeFactory();
}
//添加岩贼斩斧实现类
public class CrusherAxeFactory : Factory {
public Axe getAxeFactory() {
return new CrusherAxe();
}
}
//添加爆鳞斩斧实现类
public class BomberAxeFactory : Factory {
public Axe getAxeFactory() {
return new BomberAxe();
}
}
public class TestFactory {
static void Main(string[] args) {
//实例化岩贼斩斧工厂
Factory crusherAxefactory = new CrusherAxeFactory();
string crusherAxeInfo = crusherAxefactory.getAxeFactory().getAxeInfo();
//输出岩贼斩斧产品
Console.WriteLine(crusherAxeInfo);
//实例化爆鳞斩斧工厂
Factory bomberAxefactory = new BomberAxeFactory();
string bomberAxeInfo = bomberAxefactory.getAxeFactory().getAxeInfo();
//输出爆鳞斩斧产品
Console.WriteLine(bomberAxeInfo);
Console.ReadLine();
}
}
抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
抽象工厂模式建议为系列中的每件产品明确声明接口 。 然后,确保所有产品变体都继承这些接口。
抽象工厂模式结构:
//抽象工厂方法模式
//创建斩斧信息共同接口
public interface Axe {
string getAxeInfo();
}
//添加岩贼斩斧实现类
public class CrusherAxe : Axe {
public Axe getAxeInfo() {
return "岩贼龙斩斧";
}
}
//添加爆鳞斩斧实现类
public class BomberAxe : Axe {
public Axe getAxeInfo() {
return "爆鳞龙斩斧";
}
}
//创建防具信息共同接口
public interface Armor {
string getArmorInfo();
}
//添加岩贼防具实现类
public class CrusherArmor : Armor {
public Armor getArmorInfo() {
return "岩贼龙防具";
}
}
//添加爆鳞防具实现类
public class BomberArmor : Armor {
public Armor getArmorInfo() {
return "爆鳞龙防具";
}
}
//增加Factroy接口获取斩斧和防具
public interface Factory {
Axe getAxeFactory();
Armor getArmorFactory();
}
//创建岩贼龙套装工厂实现类
public class CrusherSuitFactory : Factory {
public Axe getAxeFactory() {
return new CrusherAxe();
}
public Armor getArmorFactory() {
return new CrusherArmor();
}
}
//创建爆鳞龙套装工厂实现类
public class BomberSuitFactory : Factory {
public Axe getAxeFactory() {
return new BomberAxe();
}
public Armor getArmorFactory() {
return new BomberArmor();
}
}
public class TestFactory {
static void Main(string[] args) {
//实例化岩贼龙套装工厂
Factory crusherSuitfactory = new CrusherSuitFactory();
string crusherAxeInfo = crusherSuitfactory.getAxeFactory().getAxeInfo();
string crusherArmorInfo = crusherSuitfactory.getArmorFactory().getArmorInfo();
//输出岩贼龙套装产品
Console.WriteLine(crusherAxeInfo);
Console.WriteLine(crusherArmorInfo);
//实例化爆鳞龙套装工厂
Factory bomberSuitfactory = new BomberSuitFactory();
string bomberAxeInfo = bomberSuitfactory.getAxeFactory().getAxeInfo();
string bomberArmorInfo = bomberSuitfactory.getArmorFactory().getArmorInfo();
//输出爆鳞龙套装产品
Console.WriteLine(bomberAxeInfo);
Console.WriteLine(bomberArmorInfo);
Console.ReadLine();
}
}
工厂方法模式和抽象工厂模式主要区别:
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(不支持增加新的产品;支持增加产品族)
单例模式
单例模式又叫做 Singleton模式,指的是一个类,在一个JVM里,只有一个实例存在。
三个特点:1.构造方法私有化 2.静态属性指向势力 3.public static的 getInstance方法,返回第二步的静态属性
饿汉式单例模式:通过私有化其构造方法,使得外部无法通过new 得到新的实例。
比如Zinogre(雷狼龙)只有一头,它提供了一个public static的getInstance方法,外部调用者通过该方法获取静态定义的对象,而且每一次都是获取同一个对象。
//饿汉式单例模式
public class Zinogre {
//私有化构造方法使得该类无法在外部通过new 进行实例化
private Zinogre() {
}
//准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个。
private static Zinogre instance = new Zinogre();
//public static 方法,提供给调用者获取前面定义的对象
public static Zinogre getInstance() {
return instance;
}
}
public class TestZinogre {
public static void main(String[] args) {
//通过new实例化会报错
//Zinogre g = new Zinogre();
//只能通过getInstance得到对象
Zinogre g1 = Zinogre.getInstance();
Zinogre g2 = Zinogre.getInstance();
Zinogre g3 = Zinogre.getInstance();
//都是同一个对象
System.out.println(g1==g2);
System.out.println(g1==g3);
}
}
懒汉式单例模式与饿汉式单例模式不同,只有在调用getInstance的时候,才会创建实例。
//懒汉式单例模式
public class Zinogre {
//私有化构造方法使得该类无法在外部通过new 进行实例化
private Zinogre() {
}
//准备一个类属性,用于指向一个实例化对象,但是暂时指向null
private static Zinogre instance;
//public static 方法,返回实例对象
public static Zinogre getInstance() {
//第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象
if(null==instance) {
instance = new Zinogre();
}
//返回 instance指向的对象
return instance;
}
}
public class TestZinogre {
public static void main(String[] args) {
//通过new实例化会报错
//Zinogre g = new Zinogre();
//只能通过getInstance得到对象
Zinogre g1 = Zinogre.getInstance();
Zinogre g2 = Zinogre.getInstance();
Zinogre g3 = Zinogre.getInstance();
//都是同一个对象
System.out.println(g1==g2);
System.out.println(g1==g3);
}
}
两种方式的比较:
饿汉式是立即加载的方式,无论是否会用到这个对象,都会加载。
如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。懒汉式,是延迟加载的方式,只有使用的时候才会加载。 并且有线程安全的考量。
使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。因此,如果业务上允许有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式。
总结:在以后的学习中,要学会灵活使用软件原则和软件模式,设计出更合理的代码。
博客园后台编辑截图