תבנית קשטן

בתכנות מונחה עצמים, תבנית קַשְׁטָן (באנגלית: Decorator pattern) היא תבנית עיצוב המאפשרת הוספת התנהגות לאובייקט, בצורה סטטית או דינאמית, ללא השפעה על התנהגות של אובייקטים אחרים מאותה מחלקה. תבנית הקשטן שימושית לעיתים קרובות כדי לשמור על ציות לעיקרון האחריות היחידה, מכיוון שהיא מאפשרת חלוקת אחריות בין מחלקות כאשר כל אחת מהן מטפלת בנושא אחר.

דוגמאות

Python 
"""
Demonstrated decorators in a world of a 10x10 grid of values 0-255. 
"""

import random

def s32_to_u16( x ):
    if x < 0:
        sign = 0xf000
    else:
        sign = 0
    bottom = x & 0x00007fff
    return bottom | sign

def seed_from_xy( x,y ): return s32_to_u16( x ) | (s32_to_u16( y ) << 16 )

class RandomSquare:
    def __init__( s, seed_modifier ):
        s.seed_modifier = seed_modifier
    def get( s, x,y ):
        seed = seed_from_xy( x,y ) ^ s.seed_modifier
        random.seed( seed )
        return random.randint( 0,255 )

class DataSquare:
    def __init__( s, initial_value = None ):
        s.data = [initial_value]*10*10
    def get( s, x,y ):
        return s.data[ (y*10)+x ] # yes: these are all 10x10
    def set( s, x,y, u ):
        s.data[ (y*10)+x ] = u

class CacheDecorator:
    def __init__( s, decorated ):
        s.decorated = decorated
        s.cache = DataSquare()
    def get( s, x,y ):
        if s.cache.get( x,y ) == None:
            s.cache.set( x,y, s.decorated.get( x,y ) )
        return s.cache.get( x,y )

class MaxDecorator:
    def __init__( s, decorated, max ):
        s.decorated = decorated
        s.max = max
    def get( s, x,y ):
        if s.decorated.get( x,y ) > s.max:
            return s.max
        return s.decorated.get( x,y )

class MinDecorator:
    def __init__( s, decorated, min ):
        s.decorated = decorated
        s.min = min
    def get( s, x,y ):
        if s.decorated.get( x,y ) < s.min:
            return s.min
        return s.decorated.get( x,y )

class VisibilityDecorator:
    def __init__( s, decorated ):
        s.decorated = decorated
    def get( s,x,y ):
        return s.decorated.get( x,y )
    def draw(s ):
        for y in range( 10 ):
             for x in range( 10 ):
                 print "%3d" % s.get( x,y ),
             print

# Now, build up a pipeline of decorators:

random_square = RandomSquare( 635 )
random_cache = CacheDecorator( random_square )
max_filtered = MaxDecorator( random_cache, 200 )
min_filtered = MinDecorator( max_filtered, 100 )
final = VisibilityDecorator( min_filtered )

final.draw()

קישורים חיצוניים

 מימוש מלא של Decorator Pattern ב Java כולל דוגמאות והסברים
 Decorator pattern description from the Portland Pattern Repository
 הסבר בהיר על [Decorator https://ernan-maisels.net/?p=124] בעברית למתכנתי #C

הערות שוליים

תכנות
הנדסת תוכנה
תבניות עיצוב