A szoftverfejlesztésben a modul minta egy olyan programtervezési minta, amit a moduláris programozásban definiált szoftver modulok létrehozására használnak egy olyan programozási nyelven, ami nem rendelkezik teljes (beépített) támogatással a modul koncepció megvalósítására.

A minta több különböző módon is implementálható, a konkrét programozási nyelvtől függően, mint például az egyke minta, az objektumorientált nyelvek osztályaiban a statikus tagok vagy a procedurális nyelvek globális függvényei. A Python nyelvben a modul minta egy beépített tulajdonság, minden .py kiterjesztésű fájl automatikusan egy-egy modul is.

Definíció és struktúra

A modul programtervezési minta a moduláris programozás paradigmája szerint definiált modul fogalmának megfelelő tulajdonságokat és szintaktikai struktúrát valósítja meg olyan programozási nyelveknél, amik nem rendelkeznek teljes (beépített) támogatással a modul koncepció megvalósítására.

center|bélyegkép|640px|alt=Egy objektum modul minta UML ábrája.|Egy objektum modul minta UML ábrája.

Koncepció

A szoftverfejlesztésben, a forráskód komponensekbe szervezhető, amik egy adott funkcionalitást valósítanak meg, vagy tartalmaznak mindent ami egy adott (bővebb) feladat elvégzéséhez szükséges. A moduláris programozás ezen megközelítések egyike, ahol a modul egy ilyen forráskód komponensként fogható fel.

Sok elterjedt programozási nyelven, a „modul“ koncepciója nem teljes körűen támogatott beépített konstrukcióként.

Tulajdonságok

Ahhoz, hogy azt mondhassuk, hogy egy egyke osztály vagy bármilyen összetartozó kód-csoport implementálja ezt a mintát, a következő tulajdonságokkal kell rendelkeznie:

A kód egy részének globális vagy publikus elérésűnek kell lennie, és ennek megfelelően külső (globális/publikus) használatra tervezettnek. A további saját (private) vagy védett (protected) kódot a „fő“ (nyilvános) kód hívja (hajtja végre). A modulnak kell hogy legyen egy inicializáló metódusa, amely megfeleltethető (hasonlít) egy osztály konstruktor metódusához. Ez a képesség általánosságban nincs meg a névtereknél (namespace). A modulnak kell hogy legyen egy lezáró metódusa (finalizer), amely megfeleltethető (hasonlít) egy osztály destruktor metódusához. Ez a képesség sincs meg általában a névtereknél. A modul egyes elemei is megkövetelhetnek további inicializációs/lezáró kódokat, amiket a modul inicializáló/lezáró metódusai hajtanak végre. A legtöbb modul-elem valamilyen függvény, amelyek modulon kívüli elemeken hajtanak végre műveleteket, amely külső elemek függvény-argumentumként kerülnek átadásra. Az ilyen függvények általában „segédkódok“ (utility), „kódeszközök“ (tool) vagy „könyvtárak“ (library).

Implementációk

Az egyes programozási nyelvek szintaxisa és a szemantikája befolyásolja a minta implementációját.

Objektumorientált programozási nyelvek

Java

Habár a Java támogatja a névterek (namespace) fogalmát (ami a modul egy egyszerűsített változataként is felfogható), bizonyos esetekben előnyét élvezhetjük annak, ha a modul mintát használjuk, az egyszerű névterek helyett.

A következő példa az egyke mintát használja a modul minta megvalósítására.

Modul definíció

package consoles;

import java.io.InputStream; import java.io.PrintStream;

public final class MainModule {

private static MainModule singleton = null;

public InputStream input = null; public PrintStream output = null; public PrintStream error = null;

public MainModule() { // Szándékosan nem csinál semmit !!!

// ...

public static MainModule getSingleton() { if (MainModule.singleton == null) { MainModule.singleton = new MainModule();

return MainModule.singleton;

// ...

public void prepare() { //System.out.println("consoles::prepare();");

this.input = new InputStream(); this.output = new PrintStream(); this.error = new PrintStream();

public void unprepare() { this.output = null; this.input = null; this.error = null;

//System.out.println("consoles::unprepare();");

// ...

public void printNewLine() { System.out.println();

public void printString(String value) { System.out.print(value);

public void printInteger(int value) { System.out.print(value);

public void printBoolean(boolean value) { System.out.print(value);

public void scanNewLine() { // to-do: ...

public void scanString(String value) { // to-do: ...

public void scanInteger(int value) { // to-do: ...

public void scanBoolean(boolean value) { // to-do: ...

// ...

Használat

import consoles;

class ConsoleDemo { public static MainModule console = null;

public static void prepare() { console = MainModule.getSingleton();

console.prepare();

public static void unprepare() { console.unprepare();

public static void execute(String[] args) { console.printString("Hello World"); console.printNewLine(); console.scanNewLine();

public static void main(String[] args) { prepare(); execute(args); unprepare();

C# (C Sharp .Net)

A C#, csakúgy mint a Java, támogatja a névterek használatát, de adott esetben a modul minta alkalmazása továbbra is hasznos lehet.

A következő példa az egyke mintát használja a modul minta megvalósítására.

Modul definíció

using System; using System.IO; using System.Text;

namespace Consoles {

public sealed class MainModule { private static MainModule Singleton = null; public InputStream input = null; public OutputStream output = null; public ErrorStream error = null;

// ...

public MainModule () { // Szándékosan nem csinál semmit !!!

// ...

public MainModule getSingleton() { if (MainModule.Singleton == null)

MainModule.Singleton = new MainModule();

return MainModule.Singleton;

// ...

public void prepare() { //System.WriteLine("console::prepare();");

this.input = new InputStream(); this.output = new OutputStream(); this.error = new ErrorStream();

public void unprepare() { this.output = null; this.input = null; this.error = null;

//System.WriteLine("console::unprepare();");

// ...

public void printNewLine() { System.Console.WriteLine("");

public void printString(String Value) { System.Console.Write(Value);

public void printInteger(Integer Value) { System.Console.Write(Value);

public void printBoolean(Boolean Value) { System.Console.Write(Value);

public void ScanNewLine() { // to-do: ...

public void ScanString(String Value) { // to-do: ...

public void ScanInteger(Integer Value) { // to-do: ...

public void ScanBoolean(Boolean Value) { // to-do: ...

// ...

Használat

class ConsoleDemo { public static Consoles.MainModule Console = null;

public static void prepare()

Console = Consoles.MainModule.getSingleton();

Console.prepare();

public static void unprepare()

Console.unprepare();

public static void execute()

Console.PrintString("Hello World"); Console.PrintNewLine(); Console.ScanNewLine();

public static void main()

prepare(); execute(args); unprepare();

Prototípus alapú programozási nyelvek

JavaScript A JavaScript széleskörűen használt a WEB alapú technológiákban. Az objektumokat nem konstruktorok segítségével, hanem a prototípus klónozásával állítja elő.

Modul definíció

function ConsoleClass() { var Input = null; var Output = null; var Error = null;

// ...

this.prepare = function() { this.Input = new InputStream(); this.Output = new OutputStream(); this.Error = new ErrorStream();

this.unprepare = function() { this.Input = null; this.Output = null; this.Error = null;

// ...

var printNewLine = function() { // code that prints a new line

var printString = function(params) { // code that prints parameters

var printInteger = function(params) { // code that prints parameters

var printBoolean = function(params) { // code that prints parameters

var ScanNewLine = function() { // code that looks for a newline

var ScanString = function(params) { // code that inputs data into parameters

var ScanInteger = function(params) { // code that inputs data into parameters

var ScanBoolean = function(params) { // code that inputs data into parameters

// ...

Használat

function ConsoleDemo() { var Console = null;

var prepare = function() { Console = new ConsoleClass();

Console.prepare();

var unprepare = function() { Console.unprepare();

var run = function() { Console.printString("Hello World"); Console.printNewLine();

var main = function() { this.prepare(); this.run(); this.unprepare();

Procedurális programozási nyelvek

A modul minta, az objektumorientált nyelvek procedurális kiegészítéseként is tekinthető.

Habár a procedurális és moduláris programozási paradigmák gyakran használatosak együtt, vannak esetek, ahol egy procedurális programnyelv nem teljes mértékben támogatja a modulokat, ami miatt a modul minta implementálása szükséges.

PHP (procedurálisan)

Az alábbiakban egy a procedurális, névtér használat lehetősége előtti (5.3.0 verziót megelőző) PHP nyelvre alkalmazott példa. Ajánlott, hogy egy modul minden eleme (függvénye), el legyen látva egy a modul-fájl vagy a modul nevéhez kapcsolódó előtaggal, az esetleges azonosító ütközések elkerülése érdekében.

Modul definíció

<?php // filename: console.php

function console_prepare() { // code that prepares a "console"

function console_unprepare() { // code that unprepares a "console"

// ...

function console_printNewLine() { // code that ouputs a new line

function console_printString(/* String */ Value) { // code that prints parameters

function console_printInteger(/* Integer */ Value) { // code that prints parameters

function console_printBoolean(/* Boolean */ Value) { // code that prints parameters

function console_scanNewLine() { // code that looks for a new line

function console_scanString(/* String */ Value) { // code that stores data into parameters

function console_scanInteger(/* Integer */ Value) { // code that stores data into parameters

function console_scanBoolean(/* Boolean */ Value) { // code that stores data into parameters

?>

Használat

<?php // filename: consoledemo.php

require_once("console.php");

function consoledemo_prepare()

console_prepare();

function consoledemo_unprepare()

console_unprepare();

function consoledemo_execute()

console_printString("Hello World"); console_printNewLine(); console_scanNewLine();

function consoledemo_main()

consoledemo_prepare(); consoledemo_execute(); consoledemo_unprepare();

?>

C

Az alábbi példa a procedurális, névterek nélküli C nyelvre vonatkozik. Ajánlott, hogy egy modul minden eleme (függvénye), el legyen látva egy a modul-fájl vagy a modul nevéhez kapcsolódó előtaggal, az esetleges azonosító ütközések elkerülése érdekében.

Modul definíció header

// filename: "consoles.h"

#include <stdio.h> #include <string.h> #include <ctype.h>

void consoles_prepare(); void consoles_unprepare();

// ...

void consoles_printNewLine();

void consoles_printString(char* Value); void consoles_printInteger(int Value); void consoles_printBoolean(bool Value);

void consoles_scanNewLine();

void consoles_scanString(char* Value); void consoles_scanInteger(int* Value); void consoles_scanBoolean(bool* Value);

Modul definíció törzs

// filename: "consoles.c"

#include <stdio.h> #include <string.h> #include <ctype.h> #include <consoles.h>

void consoles_prepare() { // code that prepares console

void consoles_unprepare() { // code that unprepares console

// ...

void consoles_printNewLine() { printf("\n");

void consoles_printString(char* Value) { printf("%s", Value);

void consoles_printInteger(int Value) { printf("%d", &Value);

void consoles_printBoolean(bool Value) { if (Value) { printf("true"); } else { printf("false");

void consoles_scanNewLine() { getch();

void consoles_scanString(char* Value) { scanf("%s", Value);

void consoles_scanInteger(int* Value) { scanf("%d", Value);

void consoles_scanBoolean(bool* Value) { char temp; scanf("%s", temp);