23种设计模式学习:
一、分类:
- . 根据目的来分类:根据模式是用来完成什么工作来划分,这种方式可分为创建型模式、结构型模式和行为型模式 3 种。
- 创建型模式:用于描述“怎样创建对象”,它的主要特点是 “将对象的创建与使用分离”。GoF 中提供了单例、原型、工厂方法、抽象工厂、建造者等 5 种创建型模式。
- 结构型模式:用于描述如何将类或对象按某种布局组成更大的结构,GoF 中提供了代理、适配器、桥接、装饰、外观、享元、组合等 7 种结构型模式。
- 行为型模式:用于描述类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,以及怎样分配职责。GoF 中提供了模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器等 11 种行为型模式。
- 根据作用范围来分类:根据模式是主要用于类上还是主要用于对象上来分,这种方式可分为类模式和对象模式两种。
- 类模式:用于处理类与子类之间的关系,这些关系通过继承来建立,是静态的,在编译时刻便确定下来了。GoF中的工厂方法、(类)适配器、模板方法、解释器属于该模式。
- 对象模式:用于处理对象之间的关系,这些关系可以通过组合或聚合来实现,在运行时刻是可以变化的,更具动态性。GoF 中除了以上 4 种,其他的都是对象模式。
二、以目的不同分类学习
一)创建型模式:
1.单例模式
某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。
2. 原型模式
将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
3. 工厂模式
工厂模式的共性:
1、将创建与使用分离。定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。
2、凡是需要生成复杂对象的地方,都可以尝试考虑使用工厂模式来代替。
复杂对象指的是类的构造函数参数过多等对类的构造有影响的情况,因为类的构造过于复杂,如果直接在其他业务类内使用,则两者的耦合过重。
- 简单工厂模式(不在23种设计模式之中)
- 由工厂方法模式中删除抽象工厂类,留下具体工厂类。(工厂方法模式的简化版)
- 简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)
-
类图:
-
应用场景:
1、 当不需要关心如何创建产品的逻辑的细节,只需要产品对象时。
2.、创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。 -
优点:
1、实现解耦,高层逻辑只需得知接口,无需关系具体实现。
2.、易扩展,当有新的产品或者需要更改时,只需多创建一个具体工厂类,符合开闭原则。 -
缺点:
1.、当产品过多时,增加复杂度。 简单工厂类很庞大臃肿、耦合性高,而且增加、删除某个子类对象的创建都需要打开简单工厂类来进行修改代码也违反了开-闭原则。
//抽象产品
public interface Product {
void show();
}
//具体产品:ProductA
static class ConcreteProduct1 implements Product {
public void show() {
System.out.println("具体产品1显示...");
}
}
//具体产品:ProductB
static class ConcreteProduct2 implements Product {
public void show() {
System.out.println("具体产品2显示...");
}
}
final class Const {
static final int PRODUCT_A = 0;
static final int PRODUCT_B = 1;
static final int PRODUCT_C = 2;
}
static class SimpleFactory {
public static Product makeProduct(int kind) {
switch (kind) {
case Const.PRODUCT_A:
return new ConcreteProduct1();
case Const.PRODUCT_B:
return new ConcreteProduct2();
}
return null;
}
}
- 工厂方法模式
- 是对简单工厂方法解耦的体现,克服了简单工厂模式违背开-闭原则的缺点。
-
类图:
-
应用场景:
应对创建大量产品,修改操作较多的业务。 -
优点:
当增添产品时,没有耦合在一个工厂类中,而是单独的增添工厂类与产品类,实现了解耦。符合了开闭原则,克服了简单工厂的缺点。 -
缺点:
1、每增加一个产品类,就要添加相应的工厂类,增加代码量。
2、简单工厂中可以不关心具体产品,但工厂方法模式要知道具体的逻辑,具体的产品要由具体的工厂创造。
3、只能生产一类产品。 -
代码UML图:
public class FactoryDemo
{
/// <summary>
/// 抽象产品类
/// </summary>
public interface IPhoneProduct
{
void Telephone();
}
/// <summary>
/// 抽象工厂类
/// </summary>
public interface IFactory
{
IPhoneProduct Create();
}
/// <summary>
/// 具体工厂类
/// </summary>
public class XiaoMiFactory : IFactory
{
public IPhoneProduct Create()
{
return new XiaoMiPhone();
}
}
public class HuaWeiFactory : IFactory
{
public IPhoneProduct Create()
{
return new HuaWeiPhone();
}
}
/// <summary>
/// 具体产品类
/// </summary>
public class XiaoMiPhone : IPhoneProduct
{
public void Telephone()
{
Console.WriteLine("小米手机通话");
}
}
public class HuaWeiPhone : IPhoneProduct
{
public void Telephone()
{
Console.WriteLine("华为手机通话");
}
}
public static void Main(string[] args)
{
//指定具体的工厂
IFactory xiaomiFactory = new XiaoMiFactory();
IFactory huaweiFactory = new HuaWeiFactory();
//由工厂去完成创建具体产品
IPhoneProduct xiaomiPhone = xiaomiFactory.Create();
IPhoneProduct huaweiPhone = huaweiFactory.Create();
xiaomiPhone.Telephone();
huaweiPhone.Telephone();
}
}
- 抽象工厂模式
由来:
1、工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机,只考虑生产同等级的产品.
2、抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族。
3、由工厂方法模式添加了其他抽象产品而来。
4、产品族
- 定义 :
是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
-
类图:
-
应用场景:
1、当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
2、系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
3、系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。 -
优点:
1、可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
2、当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
3、抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。 -
缺点:
1、当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则。 -
当系统中只存在一个等级结构的产品时,抽象工厂模式将退化到工厂方法模式。
-
个人实践:
public static void Main(string[] args)
{
GTX1660S colorful1660s = Colorful.newGTX1660s();
GTX1660S calax1660s = Calax.newGTX1660s();
calax1660s.Use();
}