python创建型设计模式学习——工厂方法模式
2017-01-04 12:06
525 查看
应用情形
如果子类的某个方法要根据情况,来决定用什么类去实例化相关对象,可以考虑工厂方法模式。此模式可以单独使用,也可以再无法预知对象类型的时候使用,例如待初始化的对象类型要从文件中读入或者由用户输入。参照书上例子,根据用户的调用,创建国际跳棋或者国际象棋的棋盘。
import io import itertools import os import sys import tempfile import unicodedata
定义棋盘常量
#跳棋、棋盘背景类型 BLACK, WHITE = ("BLANK", "WHITE") #国际象棋,棋子类型 DRAUGHT, PAWN, ROOK, KNIGHT, BISHOP, KING, QUEEN = ("DRAUGHT", "PAWN", "ROOK", "KNIGHT", "BISHOP", "KING", "QUEEN")
最顶层调用代码
if __name__ == "__main__": main() def main(): checkers = CheckersBoard() print(checkers) chess = ChessBoard() print(chess)
根据平台定义控制台输出
if sys.platform.startswith("win"): def console(char, background): return char or " " sys.stdout = io.StringIO() else: def console(char, background): return "\x1B[{}m{}\x1B[0m".format( 43 if background == BLACK else 47, char or " ")
补充知识点
python 继承的实现:
一种是如上篇文章说的使用
class absClass(mateclass=abc.ABCMeta)
一种是在文档中直接说明
书上这个例子用到的方法:
凡是需要有子类重新实现的方法都抛出NotImplementedError异常。
抽象棋盘父类的实现:
class AbstractBoard: def __init__(self,rows,columns): #创建一个rows行columns列的二维列表,并将元素初始化None #[[列1,列2,列3,.....], #[列1,列2,列3,.....], #[列1,列2,列3,.....], # ..... #] self.board = [[None for _ in range(columns)] for _ in range(rows)] #通过工厂方法populate_board()来实例化棋子 self.populate_board() #定义工厂方法,由子类来实现,创建棋盘对象 def populate_board(self): raise NotImplementedError() #打印棋盘,将由子类调用 def __str__(self): squares = [] for y,row in enumerate(self.board): for x, piece in enumerate(row): square = console(piece, BLANK if(y + x) % 2 else WHILE) squares.append("\n") return "".join(squares)
知识点补充 itertools 模块小结
http://www.wklken.me/posts/2013/08/20/python-extra-itertools.html
itertools.islice(iterable,start,stop,step):对迭代器做类似于切片操作
itertools.cycle(iterable):无限迭代操作之一,将传入的迭代对象无限迭代
itertools.chain(iterable1,iterable2):将两个可迭代对象连接合并
国际跳棋棋盘子类实现
class CheckersBoard(AbstractBoard): def __init__(self): self.populate_board() def populate_board(self): def black(): return create_piece(DRAUGHT,BLANK) def white(): return create_piece(DRAUGHT,WHITE) rows = ( # 4 black rows (None, black()), (black(), None), (None, black()),(black(), None), # 2 blank rows (None, None), (None, None), # 4 white rows (None, white()), (white(), None), (None, white()), (white(), None) ) #根据模板初始化棋盘列表 self.board = [list(itertools.islice( itertools.cycle(squares), 0, len(rows))) for squares in rows]
国际象棋棋盘类实现
class ChessBoard(AbstractBoard): def __init__(self): super.__init()__(8,8) #按照模板创建国际象棋棋盘 def populate_board(self): for row, column in ((0, BLANK),(7, WHITE)): for columns ,kind in (((0, 7), ROOK), ((1, 6), KNIGHT), ((2, 5), BISHOP), ((3,), QUEEN), ((4,), KING)): for column in columns: self.board[row][column] = create_piece(kind, color) for column in range(8): for row, color in ((1, BLACK), (6, WHITE)): self.board[row][column] = create_piece(PAWN, color)
棋子创建函数
def create_piece(kind, color): color = "White" if color == WHITE else "Black" name = {DRAUGHT: "Draught", PAWN: "ChessPawn", ROOK: "ChessRook", KNIGHT: "ChessKnight", BISHOP: "ChessBishop", KING: "ChessKing", QUEEN: "ChessQueen"}[kind] #这里使用动态创建实例的优雅(装逼)方式 return globals()[color + name]()
知识点补充 用内置函数type来创建类
Class = type(类型名称,含有基类名称的数组,含有类属性的字典)
globals()[类型名称] = Class
__slots__的用法,如果定义了slots,那么创建的实例中就不出现私有的dict,__slots__ = () 保证了实例中不会有任何数据
http://blog.csdn.net/tianqio/article/details/2374086
棋子父类
class Piece(str): __slots__ = ()
动态创建各种棋子类
for code in itertools.chain((0x26C0,0x26c2),range(0x2654, 0x2660)): char = chr(code) name = unicodedata.name(char).title().replace(" ", "") if name.endswith("sMan"): name = name[:-4] # 先写lambda表达式,然后用char填充外围lambda,创建new()函数(相当于是创建并调用外围lambda,创建了new()函数 new = (lambda char:lambda Class: Piece.__new__(Class, char))(char) # 所有的lambda函数都叫lambda,于是起个名字 new.__name__ = "__new__" #创建类 Class = type(name, (Piece,), dict(__slots=()), __new__=new) globals()[name] = Class
相关文章推荐
- C#面向对象设计模式学习笔记(4) - Factory Method 工厂方法模式(创建型模式)
- python创建型设计模式学习——抽象工厂模式
- 设计模式学习笔记--工厂方法模式(Factory Method Pattern)【创建型模式】
- 设计模式学习(创建型模式)—工厂方法模式(Factory Method)
- 面向对象设计模式学习---Singleton模式(创建型)
- 设计模式笔记 4.Factory Method 工厂方法模式(创建型模式)
- 面向对象设计模式学习---Abstract Factory模式(创建型)
- 设计模式学习之创建型模式学习总结
- 设计模式学习整理之创建型模式
- 23种设计模式学习之东拼西凑-------工厂方法模式
- 设计模式学习总结-创建型模式
- 设计模式学习笔记——创建型(总结)
- 设计模式学习系列之UML图(创建型模式)
- 面向对象设计模式学习---Builder模式(创建型)
- 设计模式学习笔记(六)——创建型模式总结
- 设计模式学习整理之创建型模式
- .Net设计模式学习笔记(七):创建型模式专题总结(Creational Pattern)
- 设计模式学习的阶段性总结(创建型设计模式part)
- 设计模式学习--工厂方法模式
- 学习笔记:创建型设计模式简单对比