Ejemplos de API de Java que exigen una secuencia de acción

7

Como parte de una investigación en la que estoy trabajando, estoy buscando API públicas que solo funcionan correctamente cuando aplicas una determinada secuencia de acciones.

Por ejemplo, la java.nio.channels.SocketChannel class , desde la biblioteca estándar de Java, solo funciona correctamente con secuencias como open() -> connect() -> read() -> read() -> close() . Una demostración más completa si la forma en que se puede usar puede representarse en el siguiente gráfico:

LosejemplosadicionalesdeAPIdelabibliotecaestándardeJavaquerequierenciertassecuenciasson java.io.PrintStream (muy similar al anterior) y java.util.Iterator (que requiere una llamada next() entre cada dos llamadas remove() , por lo que se aplica una determinada secuencia).

Entonces, ¿tu API favorita para hacer X también se comporta de esa manera? Me gustaría mucho conocer las API adicionales que requieren una determinada secuencia de métodos para un uso correcto ; especialmente las clases que no son parte de la biblioteca estándar de Java. Cuanto más complejas sean las secuencias requeridas, mejor.

Algunas API requieren una secuencia que abarca varias clases, por ejemplo:

X x = new X();
x.setup();
Y y = x.createNewY();
Z z = new Z(y);
z.doSomething();

Estos ejemplos también son interesantes, pero busco secuencias que aparecen en la misma clase.

EDIT agregó una recompensa por una mayor visibilidad. Estoy seguro de que muchos de ustedes han encontrado muchas API que coincidirán con esta descripción, realmente apreciaría algunos buenos ejemplos.

    
pregunta Oak 25.11.2010 - 17:17

8 respuestas

5

Desde el framework Spring

La Interfaz del ciclo de vida obliga a la siguiente acción secuencia:

start (isRunning)* stop

que se usa en casi todos los componentes principales que conforman el marco. Afortunadamente, este ciclo de vida es administrado por el contenedor.

Desde el marco de Hibernate

El Interfaz del ciclo de vida soporta la siguiente secuencia de acción:

(onDelete, onSave, onUpdate)* onLoad

Desde la API de Servlet

Mi favorito de todos los tiempos: el ciclo de vida de un servlet :

init service destroy

con servicio delegado a las operaciones doGet, doPost, etc.

    
respondido por el Gary Rowe 30.11.2010 - 01:01
3

Quizás no entiendo bien, pero ¿encajaría lo siguiente?

  • java.lang.Thread

    debe llamar a thread.start() antes de thread.stop()

  • InputStream y OutputStream

    no debe llamar a otros métodos después de llamar a close()

respondido por el Armand 29.11.2010 - 00:36
3
  

java.sql.ResultSet

contiene operaciones que requieren un cierto orden:

comandos de movimiento ( absolute(int row) o next() ),

comandos de lectura / escritura ( getInt(int columnIndex) o updateInt(int columnIndex, int x) ),

comandos de escritura en el origen de datos ( updateRow() ),

comandos de liberación ( close() ).

    
respondido por el Ray 29.11.2010 - 09:43
2

Una próxima "mejor práctica" para manejar este problema en la fase de inicialización de objetos en Java, es usar un patrón de Generador que tenga un llamado generador en el que se toman los pasos, y luego se solicita que se construya un objeto. Si los pasos no son válidos, el generador falla.

De enlace :

Widget z = new Widget.Builder("3", 4.0).
                     manufacturer("333").
                     serialNumber("54321").build();

El Generador es una clase anidada para Widget, que luego tiene métodos llamados (devolviendo el mismo objeto de generador) hasta que se llame al método build (), que crea y devuelve el Widget necesario.

Puede reducir bastante la complejidad.

    
respondido por el user1249 28.11.2010 - 22:28
2

¿Qué pasa con el java.util.Calendar? No requiere una secuencia de acción completa, pero es un PITA real por el número de veces que necesita usarlo:

//1. get a new instance
Calendar cal=Calendar.getInstance();
//2. set the different fields
cal.set(Calendar.DATE, 12);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.YEAR, 1982);
//3. use it, for whatever
Date d=cal.getTime();

Y, por no hablar de la API de transacciones de Java, cuando Bean administró:

@Stateless
@TransactionManagement(BEAN)
public class ExampleBean {

    @Resource
    private SessionContext ctx;

    public void foo() {
        UserTransaction utx = ctx.getUserTransaction();

        // start a transaction
        utx.begin();

        // Do work

        // Commit it
        utx.commit();
    }
}

La clasificación de JAXB

//1. get context
JAXBContext jc = JAXBContext.newInstance( Foo.class );
//2. create Marshaller instance
Marshaller m = jc.createMarshaller();
//3. set properties
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
  Boolean.TRUE);
//at last, marshall
m.marshal( foo, System.out );

y poco formal:

//1. get context
JAXBContext jc = JAXBContext.newInstance( Foo.class );
//2. create Unmarshaller instance
Unmarshaller u = jc.createUnmarshaller();
//3. optional: set properties, format validation, schema validation, etc
u.setValidating( true );
//4. unmarshall
Foo foo = (PurchaseOrder)u.unmarshal(
       new FileInputStream( "po.xml" ) );
    
respondido por el Tomas Narros 30.11.2010 - 16:51
1

El documento académico " ESP: verificación del programa sensible al camino en tiempo polinomial " incluye ejemplos para la apertura y cerrar archivos, además de verificar llamadas a fprintf. Y el concepto funciona con los FSM generales, y esto puede estar más cerca de lo que está buscando.

El bono es que el sistema ESP verifica que en realidad obedeces estas reglas. También relacionado con esta línea de investigación es BLAST .

Si desea requisitos que sean más explícitos en el lenguaje de programación, consulte tipo sensible al flujo Calificadores . Lo que puede ser útil, por ejemplo, para verificar que una cadena "contaminada" se haya limpiado antes de ser utilizada en una consulta SQL.

Dependiendo de la naturaleza de su proyecto, debe buscar en el clásico push antes de un peek o un pop en una pila. No estoy seguro de qué tan bien los enfoques anteriores podrían manejar ese caso, porque es importante contar el número de llamadas realizadas.

    
respondido por el Macneil 28.11.2010 - 18:48
1

El C ++ STL tiene una variedad de reglas sobre cuándo se invalidan los iteradores. Por ejemplo, agregar un elemento a un vector puede hacer que todos los iteradores en ese vector se invaliden.

Cualquier biblioteca de contenedores debe tener casos especiales para contenedores vacíos.

He tratado con una base de datos api, IBPP, que requería una llamada - > Start () al objeto de la transacción, antes de crear cualquier declaración asociada con la transacción. Eventualmente llamaría - > Commit (); (o - > Rollback () si las cosas no fueron bien) Otras API son similares, pero probablemente un poco más complejas debido a problemas como la confirmación automática.

Ciertamente he tratado con el código interno que actuó de esa manera. Sin embargo, lo considero un error.

El módulo pygame en python requiere que se llame a .init () y luego a .display.set_mode () para configurar un modo de gráficos.

Todo lo que puedo pensar tiene versiones relativamente triviales de esto. No puedo pensar en ningún caso que tenga una versión realmente compleja como la que realmente quieres.

    
respondido por el Winston Ewert 29.11.2010 - 02:22
0

¿Te gusta analizar un documento XML?

DocumentBuilderFactory dbf = DocumentBuilderFactory.getInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File("file.xml"));
    
respondido por el TMN 30.11.2010 - 19:54

Lea otras preguntas en las etiquetas

Comentarios Recientes

respuesta que contiene información específica de la tarea: solicitud POST y respuesta (madura) Respuesta basada en la operación Respuesta favorecida por el usuario / intención de responder a la opción (incorrecta): Acción de la interfaz de token → Protocolo orientado al servicio responseOOP respuesta específica (respuesta no válida) → Métodos DLiteral de API que en realidad no requieren secuencias de acción adicionales (no disponibles o pueden pasarse como el único argumento) → QC # JAXB Data Provider... Lee mas