Práctica de implementación de DDD-restaurante a los ojos de los arquitectos | Equipo técnico de JD Cloud

Este artículo toma la escena del restaurante como línea narrativa principal, el dominio como idea central y combina el diseño arquitectónico y la metodología de diseño funcional. Es un estudio de caso que cubre todo el proceso desde el análisis del dominio hasta la implementación. El contenido se centra en la implementación, por lo que hay cierta discusión. Las correcciones son bienvenidas.

El artículo es largo y contiene información útil. Si lo lees con paciencia, definitivamente obtendrás algo.

Este artículo no se centra en los detalles de implementación del restaurante, sino en discutir ideas y métodos de diseño.

1. Diseño de dominio

Dejemos de lado la perspectiva técnica instintiva de los técnicos y analicemos las cuestiones del dominio desde una perspectiva puramente empresarial .

El núcleo del diseño de dominio es dividir y conquistar, con el propósito de lograr autonomía en el ámbito empresarial .

Así como normalmente no pones almohadas y edredones en la cocina o el baño, no pones harina de arroz en tu cama, de lo contrario te resultará muy complicado dormir, lo mismo ocurre con los sistemas de software. queremos resolver la pregunta.

1.1 Macroproceso

Si quiero diseñar un restaurante, debido a la necesidad de dividir y conquistar, primero analizaré el proceso macro , que puede ayudarnos a encontrar rápidamente áreas importantes.





Por lo tanto, obtendremos varias áreas de comportamiento claras. Dividí el restaurante en "dominio de platos", "dominio de pedidos", "dominio de cocina" y "dominio de comedor". Esta es una división de dominio a nivel empresarial. Cada área debe estar separada objetivo en el futuro analizar.

Los productos son: macroprocesos y roles participantes.

1.2 Lenguaje unificado

El lenguaje recorre todo el proceso de desarrollo, desde el análisis de la demanda hasta el diseño y desde el diseño hasta la codificación, por lo que un buen lenguaje es muy importante, un buen lenguaje que incorpora conceptos comerciales claros .

En esta etapa, necesitamos ordenar las entidades y comportamientos del negocio y sacar algunas conclusiones sobre ellos. Nuestra pregunta central es: "Quién" afecta a "Quién" a través de qué "comportamiento" . Los tres elementos son: rol, comportamiento y entidad. Mi sugerencia es encontrar primero "entidad", "rol" y "comportamiento" y clasificarlos . A menudo me concentro en roles e identidades específicas, entidades e instancias de entidades, funciones y pasos importantes incluidos.

Rol : Es un sujeto agente, un sustantivo y un tipo de entidad que inicia activamente la conducta.

Comportamiento : Es un verbo, lo que se hace y el comportamiento en sí.

Entidad : Es un sustantivo y es una entidad distinta de "rol".

Se recomienda utilizar un mapa mental para resolverlo, creo que el mapa mental resumido puede ayudarnos a identificar los elementos fundamentales.

Los productos resultantes son: sustantivos, definiciones de conceptos y mapas cerebrales relacionados.



1.3 Análisis de casos de uso

En este paso, no necesitamos entrar en un análisis detallado de los casos de uso, sino utilizar un análisis relativamente macro para comprender la relación entre roles y comportamientos .

Salida: diagrama de casos de uso

Tome la cocina como ejemplo, como se muestra en la figura.





1.4 División de dominio

Cuando analizamos el proceso macro dividimos varias áreas de comportamiento, pero eso fue a nivel empresarial. Sobre esa base, debemos ampliar la perspectiva de un área determinada, combinada con el análisis de casos de uso anterior, para dividir aún más las áreas según "correlación funcional" y "correlación de roles" .

Correlación funcional : Cualquier negocio se compone de un conjunto de casos de uso, y un determinado campo del negocio no es una excepción. Por lo tanto, la división de campos debe basarse en la correlación funcional. Por ejemplo, los casos de uso relacionados con la cocina deben pertenecer al cocina, así que identificamos el dominio de la cocina y fue una progresión natural.

Correlación de roles: el siguiente es el rol, que a menudo se usa para dividir subdominios. Un área determinada implica la participación de múltiples roles y se puede dividir en múltiples subdominios de acuerdo con la división de roles para satisfacer las necesidades personalizadas de diferentes roles. Por ejemplo, el personal de compras en la cocina es responsable de comprar verduras, los trabajadores de los cuchillos son responsables de cortar las verduras y los chefs son responsables de cocinar. Consideraremos dividir la cocina en "dominio de compras", "dominio de procesamiento" y "dominio de cocina".

En términos generales, los subdominios no tienen espacios de problemas independientes y no existen como dominios independientes.

Salida: dominio, subdominio

Tome el dominio de la cocina como ejemplo, como se muestra en la figura.





1.5 Modelado de dominio

Esta es una etapa con la que todos están familiarizados y se centra en analizar la relación entre entidades y dominios (agregación de dominios) y la relación entre entidades (agregación OO) .

El modelo de dominio es la piedra angular para realizar funciones. Sólo teniendo una comprensión esencial de las funciones podemos encontrar las entidades centrales. La relación de agregación OO entre entidades determina la escalabilidad de las funciones . La agregación OO es el punto central más importante.





combinación, agregación

Agregación: la relación de agregación es una relación débil, y el todo y las partes pueden ser independientes entre sí.

Composición: La relación de composición es una relación fuerte entre el todo y las partes. El todo y las partes tienen el mismo ciclo de vida.

Puede utilizar los siguientes casos para expresar tanto la agregación de dominios como las relaciones de agregación OO.



Salidas: agregados, entidades, objetos de valor, atributos de entidades.

(Los servicios y eventos del dominio se proporcionarán en el diseño funcional posterior)

1.6 Campos ascendentes y descendentes

Las relaciones ascendentes y descendentes en un dominio no son dependencias de dominio. Las dependencias se refieren a dependencias de capacidades, que comparten ciertas capacidades. Las relaciones de dependencia son fijas. Las relaciones ascendentes y descendentes en el dominio no son relaciones de llamadas, sino que están relacionadas con casos de uso y no describen la situación en el dominio.

La relación upstream y downstream en el campo se refiere a la relación de influencia . El upstream afecta al downstream. La influencia se divide en "influencia lógica" e "influencia de los datos". En términos generales, debemos prestar más atención a la "influencia de los datos". entonces la relación ascendente y descendente en el campo es una La restricción de la dirección del flujo de datos es la restricción del orden en que ocurren los negocios . Se utiliza para especificar los datos utilizados en este campo. Es un reflejo de la "preparación" de el campo aguas abajo confiando en el campo aguas arriba. Las restricciones razonables ascendentes y descendentes pueden ayudar a reducir las dependencias innecesarias entre campos, facilitar la reutilización de datos y reducir los cálculos repetidos.

El ascendente y descendente del dominio están relacionados con el escenario y no son estáticos. Diferentes escenarios tienen diferentes ascendentes y descendentes, y cada escenario debe explicarse de forma independiente.

Resultado: Descripciones ascendentes y descendentes de cada escenario

Ejemplo: en el escenario [Administración de platos]



 

Si determinados ingredientes en la cocina son insuficientes, o un chef está de vacaciones, afectará a la presentación de los platos y, por tanto, a los pedidos de los clientes.

Ejemplo: en el escenario [consumo del cliente]



Los pedidos de los clientes afectan los platos producidos en la cocina, afectando así el comportamiento de los trabajadores de los cuchillos y también afectan las compras.

Compare los dos diagramas siguientes para comprender los aspectos ascendentes y descendentes del campo.



De hecho, el chef no debe confiar en la función de compra del personal de compras ni en la función de corte del cuchillo. Sólo confía en los "ingredientes primarios procesados", y los "ingredientes primariamente procesados" son datos procesados. Chef, los "ingredientes procesados ​​primarios" ya han sido procesados. La ilustración anterior es solo para ilustrar un problema sobre las aguas arriba y aguas abajo del campo. Este es un problema del orden de ocurrencia del negocio y la fuente de datos .

A menudo utilizamos eventos de dominio para conectar procesos de negocio. Cuando utilizamos eventos de dominio, no solo debemos centrarnos en el desacoplamiento punto a punto, sino también hacer que el proceso de negocio se ajuste a las limitaciones ascendentes y descendentes del dominio y dejar que cada dominio se ejecute de forma independiente. , Reduzca la dependencia funcional entre dominios y reduzca el costo del dominio.El acoplamiento entre ellos reduce el impacto de los cambios comerciales.

2. Diseño de arquitectura

El diseño arquitectónico consiste en resolver los problemas causados ​​por la complejidad del sistema de software, encontrar los elementos en el sistema y descubrir la relación entre ellos .

El objetivo de la arquitectura es gestionar la complejidad, la variabilidad y la incertidumbre para garantizar que los cambios en una parte de la arquitectura no tengan impactos negativos innecesarios en otras partes durante la evolución del sistema a largo plazo. Esto garantiza agilidad en el negocio y eficiencia del desarrollo, permitiendo que las partes volátiles de la aplicación cambien con frecuencia con el menor impacto posible en otras partes de la aplicación.

Tres principios del diseño arquitectónico: el principio de idoneidad, el principio de simplicidad y el principio de evolución.

2.1 Arquitectura en capas

Necesitamos construir un modelo de arquitectura de acuerdo con la capa de interfaz, la capa de dominio (capa de caso de uso de dominio, capa de modelo de dominio) , la capa de dependencia y la capa básica .

Capa de interfaz : la entrada para proporcionar servicios externos, que es la puerta de entrada hacia el norte de la capa de adaptación. No implementa ninguna lógica de negocios y no procesa transacciones, es multidominio, una capa de orquestación de procesos y un servicio de fachada.

Capa de casos de uso de dominio: es la capa de servicio de dominio, la capa de implementación de casos de uso de dominio, pertenece a un determinado dominio, es la capa de lógica de negocios y es la capa de transacciones. La lógica de negocios debe reflejarse completamente en esta capa y no dispersarse a otros niveles.

Capa de modelo de dominio: es la ubicación del modelo de dominio (entidades, objetos de valor, agregaciones). Se centra en las capacidades del modelo de dominio en sí. No incluye funciones comerciales y puede manejar transacciones. Es la capacidad de atomización y la autorrealización de los objetos de dominio .

Capa de dependencia : es la salida para conectarse a servicios externos y la puerta de entrada hacia el sur de la capa de adaptación. Incluyendo almacenamiento, puntos finales, RPC, etc., su función principal es desacoplar el dominio y el exterior, para mantener la independencia del dominio y es entre dominios.

Capa básica: capacidades técnicas generales independientes del negocio, independientes del dominio, componentes técnicos, etc.

2.2 Mapeo de arquitectura

Desde una perspectiva arquitectónica, la jerarquía de mayor a menor es: sistema -> aplicación (microservicio) -> módulo (paquete) -> submódulo.

Mapeo de dominio empresarial : Mapearemos las áreas divididas en elementos correspondientes de acuerdo con las perspectivas correspondientes. Cuando el modelo de dominio se asigna al modelo de arquitectura, las perspectivas deben ser equivalentes . Si el restaurante es el sistema, entonces la cocina es la aplicación. y si el restaurante es la aplicación, entonces la cocina es un módulo. También debe coincidir jerárquicamente, asignando la implementación de casos de uso a la capa de casos de uso y asignando la implementación del modelo de dominio a la capa del modelo de dominio.

Cuestiones técnicas y abstractas : a veces, el análisis del dominio empresarial no puede reflejar esos problemas técnicos comunes, por lo que es necesario combinar adecuadamente la perspectiva técnica y ajustar el modelo de dominio. Al mismo tiempo, debemos encontrar capacidades básicas comunes, como "agua", "electricidad", "gas", etc., y utilizarlas como consideraciones adicionales. Debemos desacoplar las cuestiones comerciales de las cuestiones técnicas, y no separar Problemas técnicos de problemas técnicos.La lógica empresarial es un desastre .

El diseño de áreas es similar al diseñador de un restaurante: él diseña varias áreas en el restaurante y cuál es el uso de las mismas.

El diseño arquitectónico es similar a un diseñador arquitectónico: diseña cómo llevar a cabo el agua, la electricidad, el gas y la construcción.

Salida: diagrama de arquitectura en capas

Tomando como perspectiva la cocina, su estructura es la siguiente



Tomando como perspectiva el restaurante, su estructura es la siguiente



El diagrama de arquitectura jerárquica refleja la distribución jerárquica lógica, en lugar de representar el significado específico de los componentes. Si el componente es una aplicación o un módulo debe determinarse en función de la situación real.

2.3 Restricciones necesarias

1. La arquitectura en capas se vuelve más estable a medida que desciende : la capa inferior depende de la capa superior y la capa inferior no puede depender de la capa superior a la inversa (excepto los puntos de extensión). Debido a que el principio central de la arquitectura en capas es hacer flotar la lógica fácilmente cambiable y hundir la lógica común, atómica y universal, la capa inferior dependiente debe ser estable, lo que requiere que la capa superior realice más cambios comerciales. La capa inferior debe poder existir independientemente de la capa superior. Por ejemplo, el DTO definido en la capa de interfaz no se puede usar en la capa inferior, pero las entidades definidas en la capa de dominio pueden ser utilizadas por la capa superior.

2. Al utilizar el modelo de congestión, debe cumplir con los principios de la programación orientada a objetos : no agregue arbitrariamente algunas capacidades al modelo de entidad de dominio. Tomemos como ejemplo el "plato". El peso y las especificaciones son sus propios atributos. Es la capacidad del "plato" para estimular las papilas gustativas, y el "plato" puede mantener su propio estado persistente. Sin embargo, tenga en cuenta que las "verduras" no se pueden "saltear" porque cuando se "saltean", las "verduras" aún no han aparecido. Los "Caishes" no son sus propios dioses. Los "platos" deben prepararse, por lo que " Los platos" son No hay ningún "plato" antes de cocinarlo. Este es un concepto de tiempo. No pongas erróneamente la capacidad de "cocinar" en el "plato". El "agua + electricidad + gas + ingredientes + condimentos + utensilios de cocina" utilizados en "cocina" no deben estar en el rango de atributos de "plato". Todos estos elementos están en el alcance de "cocina". No permita que el modelo de dominio Incluye elementos que no le pertenecen. Los elementos y los modelos de entidades de dominio son solo una parte del dominio y solo se utilizan para implementar capacidades generales del modelo .

3. La capa de interfaz y la capa de dependencia son independientes del campo : son capas relacionadas con la tecnología y no pertenecen a ningún campo. El campo no tiene por qué tener estas dos capas. El campo también puede tener estas dos capas de forma independiente. Estas No se pueden incluir dos capas Lógica empresarial.

4. La capa de dominio es independiente del entorno : No importa si un campo es una aplicación o un módulo, debe tener una capa de caso de uso independiente y una capa de modelo independiente. Incluso si hay varios campos en la misma aplicación, deben ser se manejan de forma independiente de acuerdo con sus respectivos Mírelo, ya sea una aplicación o un módulo, la interacción entre el dominio y el exterior no puede pasar por alto la capa de dependencia y la capa de interfaz.

5. El campo debe estar mínimamente completo : divida un campo en subdominios, sub-subdominios, sub-sub-sub-sub-sub-sub-sub-sub-sub-sub-sub-sub-sub-sub-dominios, infinitamente. Después de dividir hasta cierto punto, un determinado subdominio estará incompleto. e incompleto. Los subdominios no pueden existir de forma independiente . Una división insuficiente o excesiva es incompatible con el principio de bajo acoplamiento y alta cohesión. Los subdominios solo se utilizan para distinguir límites, por lo que los subdominios en el mismo dominio no necesitan estar estrictamente desacoplados y no es necesario acceder a otros subdominios en este dominio a través de la capa de dependencia, y pueden llamarse entre sí directamente .

6. La capa de servicio del dominio es la capa de casos de uso del dominio : son lo mismo, ambas se utilizan para implementar casos de uso en el dominio. No considere los servicios de dominio y los casos de uso del dominio como dos capas independientes, y no considere los servicios de dominio y los modelos de dominio como la misma capa . De lo contrario, la lógica se dispersará (parte de ella está en la capa de servicio de dominio, parte parte está en la capa del modelo de dominio, y parte de ella está (puede estar en la capa de casos de uso), lo que también dará lugar a responsabilidades poco claras de cada capa y hará que sea fácil confundirse. Si la lógica de negocios está escrita en el modelo de dominio, hará que la lógica de negocios se hunda aún más. La incertidumbre de la lógica de negocios es demasiado grande y no es adecuada para hundirse, lo que viola el principio de la arquitectura en capas. Los modelos de dominio corresponden a entidades y los servicios de dominio corresponden a casos de uso.

7. La capa de casos de uso del dominio solo puede aceptar casos de uso que coincidan con su propio dominio : El propósito de dividir los dominios es distinguir las responsabilidades de cada dominio, por lo que deben seguir estrictamente sus responsabilidades. Anteriormente hemos aclarado la diferencia entre casos de uso. y dominios La relación debe observarse estrictamente.

8. La capa del modelo de dominio sigue el principio de dependencia mínima : solo puede depender de los recursos necesarios. Los recursos necesarios se refieren a los recursos que necesita el modelo de dominio para realizar sus propias capacidades, excluyendo los recursos incluidos en la implementación de la lógica empresarial. Por ejemplo, el modelo de dominio debe depender de la base de datos para la persistencia y puede depender de los recursos de acceso a datos, pero no debe depender de otros recursos del dominio, ni de los recursos RPC, etc.

2.4 División de microservicios

La división de servicios toma como referencia la división de dominios, que depende principalmente de en qué granularidad queramos dividir, esto debe cumplir con el principio de bajo acoplamiento y alta cohesión y no destruir la relación de agregación de entidades de dominio .

Salida: microservicios

Por ejemplo, un restaurante: es necesario dividir el restaurante: el "dominio de platos", el "dominio de pedidos" y el "dominio de cocina" del restaurante tienen espacios problemáticos independientes.

Por ejemplo, la cocina: no hay necesidad de separar la cocina. El acoplamiento entre los chefs y los cuchilleros es muy alto. Ambos están cocinando. Después de la separación, es incompleta. No hay necesidad de separarla.

El restaurante se divide en tres microservicios: Cocina, Categoría y Orden. Por supuesto, también hay dos servicios que no son de dominio: servicio de fachada de restaurante y servicio básico de restaurante.

Generalmente, la capa de dependencia no se utilizará como un servicio independiente, sino que se integrará en los servicios de dominio en forma de componentes.



 

3. Diseño funcional (implementación de casos de uso)

Si el diseño de dominio es el diseñador del restaurante, el diseño arquitectónico es el arquitecto del restaurante, entonces el diseño funcional es el chef o camarero del restaurante.

Cualquier diseño debe implementarse en un diseño funcional. Si el chef no cumple con las reglas e insiste en ir al baño a lavar verduras, el resultado final seguirá siendo un desastre, lo que finalmente conducirá al fracaso del diseño. ser implementado.

El diseño funcional es la forma de lograr "abierto a la expansión y cerrado a la modificación" y es un vínculo esencial para guiar la implementación de la investigación y el desarrollo.

3.1 Concepto de función

Cuando se itera la función, la función sufrirá algunos cambios, por lo que su significado puede cambiar, por lo que debemos revisar el concepto de función nuevamente y realizar los ajustes oportunos.

Por ejemplo, si implementamos una función de "hacer arroz frito con huevos" y luego implementamos una función de "hacer huevos fritos con chile", entonces deberíamos actualizar la función a "sofreír" o incluso "preparar platos".

Aclarar el concepto de función es el requisito previo para el diseño funcional.

Salida: actualizar la biblioteca de idiomas, actualizar el mapa cerebral

3.2 Ubicación de los casos de uso

En el capítulo de análisis de dominio, hemos aclarado la relación entre casos de uso y roles, y la relación entre casos de uso y dominios .

Sin embargo, cuando se agrega una nueva función, aún debemos reevaluarla para asegurarnos de que esté en la posición correcta.

Salida: Actualizar el diagrama de casos de uso

3.3 Tormenta de eventos

Necesitamos profundizar en los detalles de la función, y el método preferido es la tormenta de eventos, que es adecuada para deconstruir funciones complejas.

El papel de Event Storm no se limita al análisis funcional, sino que creo que es muy adecuado para el análisis funcional. Una imagen de Event Storm contiene mucho contenido, que es exactamente lo que necesita el diseño funcional.

Divida la función en subfunciones (pasos). (para uso posterior)

Identifique los roles y áreas involucradas en este paso. (Se implementará en el capítulo 3.6 posterior)

Concatenar flujo de pasos y eventos de dominio. (Se implementará en el capítulo 3.6 posterior)

Identifique las entidades de dominio que participan en este paso. (Se implementará en el siguiente capítulo 3.7)

Salida: modelo de tormenta de eventos

3.4 Análisis de casos de uso

Primero, debemos prestar atención a los puntos en común y las diferencias para garantizar la escalabilidad de las funciones.

Confirme la generalización + puntos de diferencia del caso de uso y realice la expansión de funciones.

Encuentre pasos comunes para lograr la reutilización lógica.

Salida: diagrama de análisis de casos de uso

Ejemplo: preparar platos (hacer verduras mixtas, hacer guiso al wok, hacer huevos revueltos, hacer arroz al vapor, hacer arroz frito)





3.5 Diagrama de estructura de clase de implementación de caso de uso (clase de servicio de dominio)

Concéntrese en el diseño de clases de la capa de casos de uso para lograr "cerrado para modificación y abierto para expansión".

El diagrama de estructura de clases de casos de uso es un mapeo del diagrama de análisis de casos de uso .

Salida: diagrama de estructura de clases de la capa de casos de uso



3.6 Diagrama de flujo de casos de uso

Vamos un paso más allá e implementamos el modelo de tormenta de eventos al nivel de código.

Asignamos los pasos a la clase de implementación, y el paso es un método de la clase . Aclaramos aún más qué clase y método implementarán el paso, estipulando así el dominio en el que se ubica el paso.

Conectamos pasos y eventos de dominio para definir el proceso de implementación empresarial. Se recomienda utilizar un diagrama de carriles de natación para expresar el contenido anterior. El componente vertical del carril es la clase de implementación del caso de uso.

Este es un mapeo de procesos de negocios reales .

Salida: diagrama de flujo de casos de uso

Tomando huevos revueltos como ejemplo, el diagrama de flujo del caso de uso es el siguiente



Imagínese, si coloca la lógica empresarial en el modelo de dominio (como la agregación), ¿cómo lograr "abierto a la expansión y cerrado a la modificación"? Obviamente es difícil: la lógica funcional y el modelo de entidad de dominio no son el mismo tipo de problemas técnicos.

3.7 Diagrama de actividades (diagrama de secuencia)

Implementamos además el modelo de tormenta de eventos a nivel de código. Usamos diagramas de secuencia para reflejar las dependencias y las relaciones de llamada, especificamos la relación entre los pasos y los modelos de entidades de dominio y explicamos con más detalle cómo se implementan los casos de uso.

En este momento, por simplicidad, podemos cerrar el carril de la clase de servicio de dominio (capa de caso de uso).

Salidas: Diagrama de secuencia, diagrama de actividades.

 






 

4. Implementación de codificación

Implementación de codificación... Decidí... ser vago... jajaja.

Pero recapitulemos lo que hemos visto antes, ¿es suficiente? Si diferentes desarrolladores codifican según el diseño, ¿escribirán códigos diferentes?


 

Nombre del sistema

sistema de restaurante

Aplicaciones relacionadas

Aplicación de cocina, aplicación de vajilla, aplicación de pedidos, aplicación de fachada, aplicación básica

Diagrama de arquitectura del sistema



Modelo de dominio de aplicación de cocina



Capa de casos de uso de aplicaciones de cocina

Módulo de chef, módulo de habilidades con el cuchillo, módulo de comprador de alimentos

Módulo de chef de capa de caso de uso de aplicación de cocina (estructura de clase de servicio)



Aplicación de cocina - capa de caso de uso - módulo chef (métodos en la clase, significado del método, proceso de ejecución)



Aplicación de cocina - capa de casos de uso - módulo chef (dependencias de métodos, relaciones de llamadas)








Finalmente, nuestro objetivo es "resolver los problemas causados ​​por la complejidad del software", y la forma de lograr este objetivo es "diseñar una guía para la implementación de la investigación y el desarrollo".

Autor: JD Technology Dong Jian

Fuente: Comunidad de desarrolladores de JD Cloud Indique la fuente al reimprimir

Broadcom anunció la terminación del programa de socios de VMware existente , el sitio B se bloqueó dos veces, el incidente de nivel uno "3.29" de Tencent... Haciendo un balance de los diez principales incidentes de tiempo de inactividad en 2023, se lanzó Vue 3.4 "Slam Dunk", Yakult confirmó que se filtraron datos de 95G. MySQL 5.7, Moqu, Li Tiaotiao... Haciendo un balance de los proyectos y sitios web (de código abierto) que se "detendrán" en 2023 Se publica oficialmente el "Informe de desarrolladores de código abierto de China 2023" Mirando hacia atrás en el IDE de hace 30 años: solo TUI, color de fondo brillante... Julia 1.10 lanzado oficialmente Rust 1.75.0 lanzado NVIDIA lanzó GeForce RTX 4090 D especialmente para la venta en China
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4090830/blog/10567975
Recomendado
Clasificación