23种设计模式-结构型模式总结

结构型模式总结

结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。

一. 适配器模式

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
模式中角色:
目标接口(Target):客户所期待的接口,目标可以是具体的或抽象的类,也可以是接口。
需要适配的类(Adaptee):需要适配的类或适配者类。
适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
适配器模式有两种实现方式,一种称为类适配,就是将适配器的实现类继承被适配对象;另外一种是对象适配,就是使用组合的方式,将被适配对象注入适配器的实现类,下面分别是两种实现方式的类图和案例。建议多用组合少用继承。

1.1 类适配

adapter1
代码案例:

package cn.design.adapter;
/*
* 被适配的类(被调用的类)
*/
public class Adaptee {
    public void request(){
        System.out.println("可以完成客户端的请求!");
    }
}


package cn.design.adapter;
/*适配器接口*/
public interface IAdapter {
    void handleReq();
}


package cn.design.adapter;
/*适配器接口的实现类*/
public class AdapterImpl extends Adaptee implements IAdapter {
    @Override
    public void handleReq() {
        super.request();
    }
}


package cn.design.adapter;
/*客户端用户*/
public class Client {
    public void test(IAdapter t){
        t.handleReq();
    }
    public static void main(String[] args) {
        Client c = new Client();
        Adaptee a = new Adaptee();
        //继承被适配对象的方式
        IAdapter t = new AdapterImpl();

        //组合的方式(在适配器实现类中注入被适配对象)
        //IAdapter t = new AdapterImpl2(a);
        c.test(t);
    }
}
1.2 对象适配

adapter2
代码案例:

package cn.design.adapter;
/*适配器接口的实现类*/
public class AdapterImpl2 implements IAdapter {
    private Adaptee adaptee;
    public AdapterImpl2(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    @Override
    public void handleReq() {
        adaptee.request();
    }
}


package cn.design.adapter;
/*客户端用户*/
public class Client {
    public void test(IAdapter t){
        t.handleReq();
    }

    public static void main(String[] args) {
        Client c = new Client();
        Adaptee a = new Adaptee();
        //继承被适配对象的方式
        //IAdapter t = new AdapterImpl();

        //组合的方式(在适配器实现类中注入被适配对象)
        IAdapter t = new AdapterImpl2(a);
        c.test(t);
    }
}

二. 桥接模式

如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”。与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系类似一条连接两个独立继承结构的桥,故名桥接模式。 首先看这样一个案例,处理电脑分类销售的问题。
按照多继承结构,有如下结构图:
多继承结构
多继承结构存在着扩展性问题(类个数膨胀问题),如果要增加一个新的电脑类型,则在该类型下要增加各个品牌的子类,如果要增加一个新的品牌,也需要在各个电脑类型下面增加子类。
在这种结构下,一个联想笔记本类,有两个引起这个类变化的原因,电脑品牌和电脑类型,这违反了单一职责原则。
不妨将这两个维度抽象成两个抽象对象,将品牌抽象为一个接口,将类型抽象为一个抽象类(因为要添加属性,所以使用抽象类。)
抽象维度

1. 类图

在这里插入图片描述

2. 代码实现

package cn.design.bridge;
/*品牌的抽象接口*/
public interface IBrand {
    void sales();
}

class LenovoImpl implements IBrand{
    @Override
    public void sales() {
        System.out.println("销售联想电脑!");
    }
}

class DellImpl implements IBrand{
    @Override
    public void sales() {
        System.out.println("销售戴尔电脑!");
    }
}


package cn.design.bridge;
/*电脑类型的维度*/
public class IComputerType {
    protected IBrand brand;

    public IComputerType(IBrand brand) {
        this.brand = brand;
    }

    void sale(){
        brand.sales();
    }
}

class DesktopImpl extends IComputerType {
    /*
    * 因为父类写了有参构造方法,就没有默认的无参数构造方法,
    * 而子类中必须有一个构造方法去访问父类的构造方法,否则父类的数据就没有初始化
    * */
    public DesktopImpl(IBrand brand) {
        super(brand);
    }

    @Override
    void sale() {
        super.sale();
        System.out.println("销售台式机!");
    }
}

class LaptopImpl extends IComputerType {
    public LaptopImpl(IBrand brand) {
        super(brand);
    }

    @Override
    void sale() {
        super.sale();
        System.out.println("销售笔记本!");
    }
}


package cn.design.bridge;

public class Client {
    public static void main(String[] args) {
        //销售联想笔记本电脑
        IComputerType c = new LaptopImpl(new LenovoImpl());
        c.sale();
    }
}

三. 装饰模式

职责:动态的为一个对象增加新的功能。
装饰模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。
装饰模式的核心组件:
抽象构件(Component):真实对象和装饰对象具有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
具体构件(ConcreteComponent):也就是真实对象。
装饰者(Decorator):持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实对象。这样,就能在真实对象调用前后增加新的功能。
具体装饰角色(ConcreteDecorator):负责给构件对象增加新的功能。

1. 类图

decorator

2. 代码实现

package cn.design.decorator11;
/*抽象组件*/
public interface ICar {
    void move();
}

/*具体构件*/
class Car implements ICar{
    @Override
    public void move() {
        System.out.println("陆地上跑");
    }
}

/*装饰者*/
class SuperCar implements ICar{

    protected ICar car;

    public SuperCar(ICar car) {
        this.car = car;
    }

    @Override
    public void move() {
        car.move();
    }
}

/*具体装饰者*/
class FlyCar extends SuperCar{

    public FlyCar(ICar car) {
        super(car);
    }

    public void fly() {
        System.out.println("天上飞!");
    }

    @Override
    public void move() {
        super.move();
        fly();
    }
}


/*具体装饰者*/
class SwimCar extends SuperCar{

    public SwimCar(ICar car) {
        super(car);
    }

    public void swim() {
        System.out.println("水中游!");
    }

    @Override
    public void move() {
        super.move();
        swim();
    }
}

package cn.design.decorator11;

public class Client {
    public static void main(String[] args) {
        Car car = new Car();
        car.move();

        System.out.println("增加的功能,飞行----------");

        FlyCar flyCar = new FlyCar(car);
        flyCar.move();
    }
}

装饰者模式总结:装饰者模式降低了系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构件类和具体装饰类可以独立的变化,以便增加新的具体构件类和具体装饰类。
优点:扩展对象功能,比继承灵活,不会导致类个数急剧增加;可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象;具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构建子类和具体装饰子类。
缺点:产生很多小对象。大量小对象占据内存,一定程度上影响性能。
装饰者模式和桥接模式的区别:
两个模式都是为了解决过多子类对象问题。但是他们的诱因不一样,桥接模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能。

四. 组合模式

组合模式(Composite Pattern)将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户可以使用一致的方法操作单个对象和组合对象。这里以一个模拟杀毒软件的案例进行说明。
组合模式的核心组件:
抽象构件(Component):定义了叶子构件和容器构件的共同的特点。
叶子构件(Leaf):无子节点。
容器构件(Composite):有容器特征,可以包含子节点。

1. 类图

composite

2. 代码实现

package cn.design.composite10;
/*
* 模拟杀毒软件执行过程
* */

import java.util.ArrayList;
import java.util.List;

/*抽象组件*/
public interface AbstractFile {
    void killVirus(); //杀毒
}

class ImageFile implements AbstractFile {

    private String name;

    public ImageFile(String name) {
        this.name = name;
    }

    @Override
    public void killVirus() {
        System.out.println("---图像文件:" + name +",进行查杀!");
    }
}

class TxtFile implements AbstractFile {

    private String name;

    public TxtFile(String name) {
        this.name = name;
    }

    @Override
    public void killVirus() {
        System.out.println("---文本文件:" + name +",进行查杀!");
    }
}

class VideoFile implements AbstractFile {

    private String name;

    public VideoFile(String name) {
        this.name = name;
    }

    @Override
    public void killVirus() {
        System.out.println("---视频文件:" + name +",进行查杀!");
    }
}

class Folder implements AbstractFile {

    private String name;
    private List<AbstractFile> childList = new ArrayList<AbstractFile>();

    public Folder(String name) {
        this.name = name;
    }

    public void add(AbstractFile a){
        childList.add(a);
    }
    public void remove(AbstractFile a){
        childList.remove(a);
    }
    public AbstractFile getChild(int index){
        return childList.get(index);
    }

    @Override
    public void killVirus() {
        System.out.println("--- 文件夹:" + name +",进行查杀!");

        for(AbstractFile file : childList){
            file.killVirus();
        }
    }
}


package cn.design.composite10;

public class Client {
    public static void main(String[] args) {

        Folder f1 = new Folder("我的文件夹");
        AbstractFile f2, f3, f4;
        f2 = new ImageFile("我的大头贴.jpg");
        f3 = new TxtFile("文本文件.txt");
        f4 = new VideoFile("笑傲江湖.avi");

        f1.add(f2);
        f1.add(f3);
        f1.add(f4);
        f1.killVirus();
    }
}

组合模式总结:组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。
当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行。其中,使用了递归调用的机制对整个结构进行处理。

五. 外观模式

外观(Facade)模式的定义:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
外观(Facade)模式是“迪米特法则”的典型应用,它有以下主要优点。
降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。

1. 类图

facade

2. 代码实现

package cn.design.facade;

/*外观角色*/
public class Facade {
    private SubSystem01 obj1=new SubSystem01();
    private SubSystem02 obj2=new SubSystem02();
    private SubSystem03 obj3=new SubSystem03();
    public void method() {
        obj1.method1();
        obj2.method2();
        obj3.method3();
    }
}

//子系统角色
class SubSystem01
{
    public  void method1()
    {
        System.out.println("子系统01的method1()被调用!");
    }
}
//子系统角色
class SubSystem02
{
    public  void method2()
    {
        System.out.println("子系统02的method2()被调用!");
    }
}
//子系统角色
class SubSystem03
{
    public  void method3()
    {
        System.out.println("子系统03的method3()被调用!");
    }
}


package cn.design.facade;

public class Client {
    public static void main(String[] args) {
        Facade f = new Facade();
        f.method();
    }
}

六. 享元模式

享元(Flyweight)模式的定义:运用共享技术来有効地支持大量细粒度对象的复用。它通过共享已经存在的又橡来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
享元模式的主要优点是:相同对象只要保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。
其主要缺点是:
为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。
读取享元模式的外部状态会使得运行时间稍微变长。
享元模式中存在以下两种状态:
内部状态,即不会随着环境的改变而改变的可共享部分;
外部状态,指随环境改变而改变的不可以共享的部分。享元模式的实现要领就是区分应用中的这两种状态,并将外部状态外部化。下面来分析其基本结构和实现方法。
享元模式的核心构件:
抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

1. 类图

flyweight

2. 代码实现

package cn.design.flywight13;

/*抽象享元角色,是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。*/
public interface IFlyweight {
    public void operation(UnsharedConcreteFlyweight outState);
}

/*具体享元角色*/
class ConcreteFlyweight implements IFlyweight{
    private String key;

    public ConcreteFlyweight(String key) {
        this.key = key;
    }

    @Override
    public void operation(UnsharedConcreteFlyweight outState) {
        System.out.print("具体享元"+key+"被调用,");
        System.out.println("非享元信息是:"+outState.getInfo());
    }
}

package cn.design.flywight13;
/*非享元角色,存放外部状态信息,以参数的形式注入具体享元类的相关方法中*/
public class UnsharedConcreteFlyweight {
    private String info;

    public UnsharedConcreteFlyweight(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}


package cn.design.flywight13;
import	java.util.HashMap;
import java.util.Map;

/*享元工厂角色*/
public class FlyweightFactory {
    //享元池
    private Map<String, IFlyweight> flyweightsMap = new HashMap < String, IFlyweight>();

    //获取享元对象
    public IFlyweight getFlyweight(String key){
        //如果享元池中已经存在请求的对象,直接从享元池中获取
        if(flyweightsMap.get(key)!=null){
            return flyweightsMap.get(key);
        }else{//如果享元池中还没有请求的享元对象,创建享元对象,并添加到享元池中,并返回该对象
            IFlyweight flyweight = new ConcreteFlyweight(key);
            flyweightsMap.put(key, flyweight);
            return flyweight;
        }
    }
}


package cn.design.flywight13;

public class Client {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        IFlyweight f01 = factory.getFlyweight("黑色棋子");
        f01.operation(new UnsharedConcreteFlyweight("坐标为(10, 10)"));
    }
}

适用场景 :
在以下情况下可以考虑使用享元模式:
(1) 一个系统有大量相同或者相似的对象,造成内存的大量耗费。
(2) 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
(3) 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,应当在需要多次重复使用享元对象时才值得使用享元模式

七. 代理模式

代理模式提供了间接对目标对象进行访问的方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的功能上,增加额外的功能补充,即扩展目标对象的功能。
通过代理,控制对对象的访问!
可以详细控制访问某个(某类)对象的方法,在调用该方法前做前置处理,调用这个方法后做后置处理(即:AOP的微观实现!)
代理模式分为静态代理、动态代理,静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了。动态代理是在程序运行时通过反射机制动态创建的。但是类图结构是一样的。

1. 类图

proxy

2. 代码实现

2.1 静态代理
package cn.design.proxy07.staticProxy;
/*抽象接口*/
public interface IStar {
    //面签
    void confer();
    //签合同
    void signContract();
    //订票
    void bookTicket();
    //唱歌(这是主要业务方法)
    void sing();
    //收钱
    void collectMoney();
}


package cn.design.proxy07.staticProxy;
/*真实代理类*/
public class ProxyImpl implements IStar {
    private IStar realStar;

    public ProxyImpl(IStar realStar) {
        this.realStar = realStar;
    }
    @Override
    public void confer() {
        System.out.println("ProxyImpl.confer()");
    }

    @Override
    public void signContract() {
        System.out.println("ProxyImpl.signContract()");
    }

    @Override
    public void bookTicket() {
        System.out.println("ProxyImpl.bookTicket()");
    }
    /*
    * 客户真正需要的动作是唱歌
    */
    @Override
    public void sing() {
        /*前置增强*/
        System.out.println("唱歌前的准备");
        realStar.sing();
        /*后置增强*/
        System.out.println("善后工作");
    }
    @Override
    public void collectMoney() {
        System.out.println("ProxyImpl.collectMoney()");
    }
}


package cn.design.proxy07.staticProxy;
/*真实被代理对象*/
public class RealStarImpl implements IStar {
    @Override
    public void confer() {
        System.out.println("RealStar.confer()");
    }

    @Override
    public void signContract() {
        System.out.println("RealStar.signContract()");
    }

    @Override
    public void bookTicket() {
        System.out.println("RealStar.bookTicket()");
    }

    @Override
    public void sing() {
        System.out.println("RealStar(周杰伦本人).sing()");
    }

    @Override
    public void collectMoney() {
        System.out.println("RealStar.collectMoney()");
    }
}


package cn.design.proxy07.staticProxy;
/*客户端调用*/
public class Client {
    public static void main(String[] args) {
        IStar realStar = new RealStarImpl();
        ProxyImpl proxy = new ProxyImpl(realStar);

        proxy.confer();
        proxy.signContract();
        proxy.bookTicket();
        proxy.sing();
        proxy.collectMoney();
    }
}

静态代理总结:
优点:可以做到在不修改目标对象的功能前提下,对目标功能扩展.
缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.
而动态代理方式可以解决上面的问题。

2.2 动态代理

动态代理又分为JDK动态代理和CGlib动态代理。

2.2.1 JDK动态代理

JDK动态代理的主要特点就是能够在程序运行时JVM才为被代理对象生成代理对象。相比较于静态代理,在代码结构上,主要在代理实现类有区别。

package cn.design.proxy07.dynamicProxy;
/*抽象明星类*/
public interface IStar {
    //面签
    void confer();
    //签合同
    void signContract();
    //订票
    void bookTicket();
    //唱歌(这是主要业务方法)
    void sing();
    //收钱
    void collectMoney();
}


package cn.design.proxy07.dynamicProxy;

/*真实被代理对象*/
public class RealStarImpl implements IStar {
    @Override
    public void confer() {
        System.out.println("RealStar.confer()");
    }

    @Override
    public void signContract() {
        System.out.println("RealStar.signContract()");
    }

    @Override
    public void bookTicket() {
        System.out.println("RealStar.bookTicket()");
    }

    @Override
    public void sing() {
        System.out.println("RealStar(周杰伦本人).sing()");
    }

    @Override
    public void collectMoney() {
        System.out.println("RealStar.collectMoney()");
    }
}


package cn.design.proxy07.dynamicProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandler implements InvocationHandler {

    //注入目标对象
    private RealStarImpl star;

    public ProxyHandler(RealStarImpl star) {
        this.star = star;
    }

    /*
    * 参数说明:
    * proxy就是目标对象,method就是调用目标对象中方法,args就是调用目标对象中方法的参数。
    * 比如说:代理对象.method1(),这时proxy就是目标类,method1就是method,args就是method1方法参数。
    * */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //执行了invoke方法就相当于把目标对象的所有方法都交给代理类去调用,这里star是目标对象,args是参数,可以有很多参数。
        method.invoke(star,args);
        return null;
        /*
        如果调用的方法有返回值的话,定义一个Object对象接收返回值
        Object obj = null;
        obj = method.invoke(star,args);
        return obj;
        */
    }
}


package cn.design.proxy07.dynamicProxy;

import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args) {
        RealStarImpl star = new RealStarImpl();
        ProxyHandler handler = new ProxyHandler(star);
        /*
        * 参数说明:
        * loader: 代表与目标对象相同的类加载器-------目标对象.getClass().getClassLoader()
        * interfaces: 代表目标对象实现的的接口字节码对象数组----数组是因为目标类可以有多个接口
        * handler: 具体的代理的操作,InvocationHandler接口
        * */
        IStar proxy = (IStar) Proxy.newProxyInstance(RealStarImpl.class.getClassLoader(), new Class [] {IStar.class}, handler);
        proxy.sing();
    }
}
2.2.2 CGlib动态代理

使用JDK动态代理有一个限制,就是被代理的对象必须实现一个或多个接口,若想代理没有实现接口的类,就需要使用Cglib实现。
CGLib采用了非常底层的字节码技术,**其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。**但因为采用的是继承,所以不能对final修饰的类进行代理。
由于Cglib是第三方提供的所以使用的时候需要导入相关的jar包,有两个包如图:
CGlib导包
代码细节不再赘述。
代理模式和装饰者模式的区别主要是:在装饰者模式中,用户直接调用的还是某个类对象的本身,至于要装饰哪些功能,是由用户自己决定的;在代理模式中,用户直接调用的是代理类了,至于代理对于被调用的那个类对象做了哪些操作,用户是一无所知的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 设计模式是软件开发中常用的一种解决方案,它们是一些经过实践验证的可复用设计思想。设计模式允许开发人员在类和对象的结构上灵活地更改,并提供了一种优雅的解决方案来应对各种软件开发问题。 GOF(Gang of Four)是指Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位软件工程师,他们在《设计模式:可复用面向对象软件的基础》一书中总结了23种常见的设计模式,这本书因此而获得了“设计模式圣经”的称号。 这本书以案例为基础,深入浅出地讲解了每个设计模式的原理和应用场景,并提供了C++实现源码。 其中,创建型设计模式包括单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式。这些模式都提供了一种方式来创建对象,使得程序在实例化对象时更加灵活和可扩展。 结构型设计模式包括适配器模式、装饰器模式、代理模式、组合模式、享元模式和外观模式。这些模式关注如何通过类和对象的组合来创建更大的结构,并提供了一种优雅的方式来简化系统的复杂性。 行为型设计模式包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式和中介者模式。这些模式关注对象之间的通信和交互,它们提供了一种优雅的方式来实现松耦合和可维护的代码。 总之,设计模式是软件开发中非常重要的一部分,它们提供了一种通用的解决方案来处理常见的设计问题。通过学习和应用设计模式开发人员可以提高代码的可复用性、可扩展性和可维护性,并加快开发进度。 ### 回答2: 设计模式是软件开发中常用的解决问题的一种思维方式或者说是一种已被证实有效的解决问题的方法。GOF 23种设计模式是由四位著名的软件工程师提出并总结出的一套经典的设计模式。 GOF 23种设计模式分别是创建型模式、结构型模式和行为型模式。创建型模式包括简单工厂模式、工厂方法模式、抽象工厂模式、单例模式、建造者模式和原型模式。结构型模式包括适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式和代理模式。行为型模式包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式和解释器模式。 GOF 23种设计模式具有不同的应用场景和优势。通过学习和理解这些设计模式开发者可以更加灵活地应对各种软件开发中的问题。同时,掌握这些设计模式也有助于提高代码的可读性、可维护性和可扩展性。 附带C语言实现源码是一种更加具体的学习和理解设计模式的方法。通过查看实现源码,可以更加直观地看到设计模式在实践中的应用。这些源码可以作为学习的参考,帮助开发者更好地理解设计模式的思想和使用方式。 总之,设计模式是软件开发中非常重要的一部分,通过学习GOF 23种设计模式并理解其应用场景和优势,可以提高软件开发的效率和质量。附带C语言实现源码能够更加具体地帮助开发者理解设计模式的实际应用。 ### 回答3: 设计模式是软件工程中常用的一种设计思想或模板,可以用于解决特定的问题和提供可重用的解决方案。GOF(Gang of Four)提出了23种设计模式,并在书籍《设计模式:可复用面向对象软件的基础》中进行了详细的解析和说明。 这本书详细地介绍了23种设计模式,包括创建型模式、结构型模式和行为型模式。通过阅读这本书,读者可以了解每种设计模式的特点、适用场景和实现方法。另外,书中还通过示例代码的方式演示了每种设计模式的具体实现,并提供了附带的C语言实现源码。 这本书对于理解设计模式的概念和思想非常有帮助。它不仅提供了23种设计模式的名字和简介,还详细解释了每种模式的适用场景和应用案例。读者可以通过学习这些设计模式,了解如何将它们应用于自己的软件开发工作中,提高代码的可重用性和可维护性。 书中的C语言实现源码是帮助读者理解和实践设计模式的重要资源。通过阅读源码,读者可以更加深入地理解每种设计模式的具体实现细节,并进一步提升自己的编程能力。 总之,通过学习《设计模式:可复用面向对象软件的基础》这本书,读者可以全面了解设计模式的概念、分类和实现方法,并通过阅读附带的C语言实现源码来加深对设计模式的理解和应用。这将对提升软件设计和开发的能力和水平非常有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值