[已注销]对《大话设计模式》的笔记(16)

大话设计模式
  • 书名: 大话设计模式
  • 作者: 程杰
  • 页数: 368
  • 出版社: 清华大学出版社
  • 出版年: 2007-12-1
  • 第16页
    为了使各个运算符之间的耦合度达到最小,将运算符号(加减乘除)抽象成一个Operation类,然后在各个子类中分别实现GetResult方法。
    为了不在主程序中用一个冗长的分支来实例化对象,需要使用简单工厂模式(像一个工厂一样制造出我们想要用的对象),其本质就是把分支写在一个factory类静态函数中。
    #!/usr/bin/python
    # Filename: operation.py
    
    class Operation:
    	def __init__(self):
    		self.numberA = 0
    		self.numberB = 0
    	#implements GetResult in sublclass
    
    class OperationAdd(Operation):
    	def __init__(self):
    		Operation.__init__(self)
    	def GetResult(self):
    		result = self.numberA + self.numberB
    		return result
    
    class OperationSub(Operation):
    	def __init__(self):
    		Operation.__init__(self)		
    	def GetResult(self):
    		result = self.numberA - self.numberB
    		return result
    
    class OperationMul(Operation):
    	def __init__(self):
    		Operation.__init__(self)
    	def GetResult(self):
    		result = self.numberA * self.numberB
    		return result
    
    class OperationDiv(Operation):
    	def __init__(self):
    		Operation.__init__(self)
    	def GetResult(self):
    		try:
    			result = self.numberA / self.numberB
    			return result
    		except:
    			print 'divide by zero'
    
    class OperationFactory:
    	'''make out subclasses according to the
    	string given'''
    	@staticmethod
    	def createOperate(strOper):
    		if strOper == '+':    
    			oper = OperationAdd()   #create an instance of OperationAdd here
    			return oper
    		elif strOper == '-':
    			oper = OperationSub()
    			return oper
    		elif strOper == '*':
    			oper = OperationMul()
    			return oper
    		elif strOper == '/':
    			oper = OperationDiv()
    			return oper
    		else:
    			print 'the operation does not exist'
    
    控制台代码
    #!/usr/bin/python
    # Filename: simplefactory.py
    
    import operation
    import string
    
    numberA = raw_input('please input numberA\n')
    numberB = raw_input('please input numberB\n')
    strOper = raw_input('please input an operation\n')
    
    oper = operation.OperationFactory.createOperate(strOper)
    oper.numberA = string.atoi(numberA)
    oper.numberB = string.atoi(numberB)
    result = oper.GetResult()
    print 'the result is',result
    
    2011-04-18 19:51:53 回应
  • 第29页
    一切皆对象,算法本身也是一个对象,可以互相替换。把不同的算法封装成一个类,在必要的时候对具体的算法进行实例化就行了(可以用简单工厂),而调用算法的方式可以完全相同。这样一来就大大减小了算法类和使用算法类之间的耦合!
    策略模式(Strategy):它定义了算法的家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。 -Disign Pattern
    简单工厂+策略模式(python):
    算法类:
    #!/user/bin/python
    # Filename: cash.py
    
    import string
    
    class CashSuper:
    	def acceptCash(self, cash):
    		pass
    
    class CashNormal(CashSuper):
    	def acceptCash(self, cash):
    		return cash
    
    class CashRebate(CashSuper):
    	rebate = 1.0
    	def __init__(self, strReb):
    		self.rebate = string.atof(strReb)
    	def acceptCash(self, money):
    		return money * self.rebate
    
    class CashReturn(CashSuper):
    	condition = 0
    	returnMoney = 0 
    	def __init__(self, strCon, strRet):
    		self.condition = string.atoi(strCon)
    		self.strRet = string.atoi(strRet)
    	def acceptCash(self, money):
    		if(money >= self.condition):
    			return (money - (money / self.condition)*self.returnMoney)
    
    使用算法类:
    #!/usr/bin/python
    # Filename: context.py
    
    import cash
    
    class CashContext:
    	cs = cash.CashSuper()
    	def __init__(self, stype):
    		if stype == 'normal':
    			self.cs = cash.CashNormal()
    		elif stype == 'return money':
    			self.cs = cash.CashReturn('300','100')
    		elif stype == 'rebate':
    			self.cs = cash.CashRebate('0.8')
    	
    	def GetResult(self, money):
    		return self.cs.acceptCash(money)
    
    客户端:代码
    #!/usr/bin/python
    # Filename: console.py
    
    import context
    import string
    
    former_price = string.atoi(raw_input('enter the price:'))
    
    stype = raw_input('enter the mode:\n1.normal\n2.return money\n3.rebate\n')
    
    cash = context.CashContext(stype)
    
    payment = cash.GetResult(former_price)
    
    print 'money you should pay:', payment
    
    2011-04-19 14:59:59 回应
  • 第43页
    “单一职责原则”应该源于那句Unix经典名言:做一件事,并把它做好。
    这本书在讲“单一职责原则”的时候举了一个例子,比如要写一个手机上的俄罗斯方块,就应该让界面和游戏的逻辑分开,而不是都写在一个form.cs中。显示的逻辑完全可以用一个二维数组实现,而界面所做的事情无法就是把这张表映射到屏幕上。
    “开放-封闭原则”的全称应该是“对扩展开放,但对更改封闭的原则”。它的本质就是在编程一开始就保持警觉,也许那时我们之需要实现一个“加法”功能,这个时候我们应该问自己:“万一以后要有'减法'的功能怎么办?”这个时候就应该在“加法”上面抽象出一个“运算类”,这样新增其它的运算的话也只要新增对应的代码就行了(开放),而不需要改动之前的代码(封闭)。
    2011-04-19 15:19:49 回应
  • 第66页
    代理和实体(real subject)有着相同的接口,因此在任何可以使用实体的地方都可以用代理来代替。这样有什么好处呢?在打开网页的时候,图片打开的速度要比文字慢很多,总不能等待所有的图片都下载到本地然后再一起初始化,于是用Proxy来替代图片对象,先实例化成一个空的框和文字一起显示出来再说。
    a proxy in Python:
    代理类:
    #!/usr/bin/python
    # Filename: proxy.py
    # It is about a man using proxy to pursuit girl friend.
    
    class SchoolGirl:
    	name = ''
    
    class Pursuit:
    	mm = SchoolGirl()
    	def __init__(self, mm_name):
    		self.mm = mm_name
    	def GiveFlowers(self):
    		print self.mm.name, 'It is a flower for you'
    
    class Proxy:
    	gg = Pursuit('') #there's always a unlucky man behind a luck one
    	def __init__(self, mm):
    		self.gg = Pursuit(mm)  #create an instance in proxy
    	def GiveFlowers(self):
    		self.gg.GiveFlowers()  #call the method of gg
    
    控制台
    #!/usr/bin/python
    # Filename: console.py
    
    import proxy
    
    jiaojiao = proxy.SchoolGirl()
    jiaojiao.name = 'jiaojiao'
    
    third_one = proxy.Proxy(jiaojiao)
    
    third_one.GiveFlowers()
    # it looks like the third_one implements
    # the GiveFlowers(). But if you look inside
    # the proxy module, you will find out that he
    # didn't pay any money!
    
    2011-04-21 18:45:07 回应
  • 第86页
    顺便复习了c#值类型和引用类型的区别:
    当声明一个值类型变量以后,编译器会在栈上分配一个空间(大小和类型有关),变量的值(value)就保存在里面。
    栈上的变量不受gc控制,随着栈的伸缩自生自灭。
    栈的大小有个默认上界,一般比较小。
    而引用类型的实例(instance)分配在堆上,变量名是一个指向实例的指针,通过这个指针进行地址变换才可以取到实例中的值。
    堆上的东西被托管。
    堆很大。。。
    2011-04-24 22:41:35 回应
  • 第111页
    外观模式就是用一个接口(Facde)实现界面逻辑(Console)和业务逻辑(SubSystem)之间的交互,从而把耦合降到最低。Console模块可以对SubSystem模块一无所知。
    子系统类
    #!/usr/bin/python
    # Filename: subSystem
    class SubSystemOne:
    	def MethodOne(self):
    		print 'SubSystem Method 1'
    
    class SubSystemTwo:
    	def MethodTwo(self):
    		print 'SubSystem Method 2'
    
    class SubSystemThree:
    	def MethodThree(self):
    		print 'SubSystem Method 3'
    
    外观类
    #!/usr/bin/python
    # Filename: facade.py
    import subSystem as s
    
    class Facade:
    	def __init__(self):
    		self.one = s.SubSystemOne()
    		self.two = s.SubSystemTwo()
    		self.three = s.SubSystemThree()
    	def MethodA(self):
    		print 'Method A'
    		self.one.MethodOne()
    		self.two.MethodTwo()
    	def MethodB(self):
    		print 'Method B'
    		self.two.MethodTwo()
    		self.three.MethodThree()
    
    客户端类
    #!/usr/bin/python
    # Filename: console.py
    import facade
    #in this module, we know nothing about the subsystems
    f = facade.Facade()
    f.MethodA()
    f.MethodB()
    
    2011-05-04 19:49:12 回应
  • 第122页
    建造者模式(Builder)in Python
    1.产品类:用于实现产品的具体制造
    #!/usr/bin/python
    # Filename: product.py
    
    class Product:
    	def __init__(self):
    		self.parts = []
    	def Add(self, part):
    		self.parts.append(part)
    	def Show(self):
    		print self.parts
    
    class ConcreteBuilder1:
    	def __init__(self):
    		self.product = Product()
    	def BuildPartA(self):
    		self.product.Add("partP")
    	def BuildPartB(self):
    		self.product.Add("partQ")
    	def GetResult(self):
    		return self.product
    
    class ConcreteBuilder2:
    	def __init__(self):
    		self.product = Product()
    	def BuildPartA(self):
    		self.product.Add("PartX")
    	def BuildPartB(self):
    		self.product.Add("PartY")
    	def GetResult(self):
    		return self.product
    
    2.指挥者类:把产品具体的制造过程隔离开(仅在这个类中调用具体的制造方法)
    #!/usr/bin/python
    # Filename: director.py
    
    class Director:
    	def Construct(self, builder):
    		builder.BuildPartA()
    		builder.BuildPartB()
    
    3.客户端
    #!/usr/bin/python
    # Filename: console.py
    
    import director
    import product
    
    director1 = director.Director()
    
    b1 = product.ConcreteBuilder1()
    director1.Construct(b1)  #let direcctor call the BuildMethod of b1
    p1 = b1.GetResult()  #GetResult() returns a product
    p1.Show()
    
    b2 = product.ConcreteBuilder2()
    director1.Construct(b2)
    p2 = b2.GetResult()
    p2.Show()
    
    2011-05-05 17:37:11 回应
  • 第140页
    http://dev.yesky.com/436/7581936.shtml-详细解析Java中抽象类和接口的区别
    abstract与interface的本质区别:abstract class表示的是"is-a"关系,interface表示的是"like-a"关系
    2011-05-06 12:25:14 回应
  • 第170页
    状态模式(State)
    用来消除庞大的条件分支语句。把状态判断逻辑转移到类中!把状态之间的耦合降下来。
    本质:条件分支语句每次只有一个分支的代码会被执行到
    if(条件1) {A}
    else if(条件2) {B}
    else if(条件3) {C}
    else {D}
    可以先对A的代码进行实例化,然后对判断条件1是否满足,如果满足就没有必要生成其它代码,执行即可。如果不满足条件1,那么就去实例化B的代码……直到满足条件为止。
    ------------------------------------------------------------------------------------------------------
    Python状态模式
    1.状态由好几个类组成
    #!/usr/bin/python
    # Filename: state.py
    
    class ForenoonState:
    	def WriteProgram(self, w):
    		if w.Hour < 12:
    			print 'time:' + str(w.Hour) + ' Forenoon, hardwork!'
    		else:
    			w.SetState(NoonState())
    			w.WriteProgram()
    
    class NoonState:
    	def WriteProgram(self, w):
    		if w.Hour < 13:
    			print 'time:' + str(w.Hour) + ' Noon, tired!'
    		else:
    			w.SetState(AfternoonState())
    			w.WriteProgram()
    
    class AfternoonState:
    	def WriteProgram(self, w):
    		if w.Hour < 17:
    			print 'time:' + str(w.Hour) + ' Afternoon, Ok~'
    		else:
    			w.SetState(EveningState())
    			w.WriteProgram()
    
    class EveningState:
    	def WriteProgram(self, w):
    		if w.Hour < 21:
    			print 'time:' + str(w.Hour) + ' Evening, exhausted..'
    		else: 
    			w.SetState(SleepingState())
    			w.WriteProgram()
    
    class SleepingState:
    	def WriteProgram(self, w):
    		print 'time:' + str(w.Hour) + ' Sleeping zZZ...'
    
    2.消去了分支判断语句的工作类
    #!/usr/bin/python
    # Filename: work.py
    
    import state
    
    class Work:
    	def __init__(self):
    		self.current = state.ForenoonState()
    	def SetState(self, s):
    		self.current = s
    	def WriteProgram(self):
    		self.current.WriteProgram(self)
    
    3.控制台
    #!/usr/bin/python
    # Filename: console.py
    
    import work
    
    project = work.Work()
    
    project.Hour = 9
    project.WriteProgram()
    
    project.Hour = 10
    project.WriteProgram()
    
    project.Hour = 12
    project.WriteProgram()
    
    project.Hour = 13
    project.WriteProgram()
    
    project.Hour = 14
    project.WriteProgram()
    
    project.Hour = 17
    project.WriteProgram()
    
    project.Hour = 19
    project.WriteProgram()
    
    project.Hour = 22
    project.WriteProgram()
    
    2011-05-07 19:25:44 回应
  • 第179页
    适配器模式(Adapter)
    当两个接口无法对接时,可以用一个“适配器”东西作为中介,进行“翻译”。
    Python代码:
    1.球员类:
    #!/usr/bin/python
    # Filename: player.py
    class Player:
    	def __init__(self, name):
    		self.name = name
    
    class Forward(Player):
    	def __init__(self, name):
    		Player.__init__(self, name)
    	def Attack(self):
    		print 'forward:' + str(self.name) + ' attack!'
    	def Defense(self):
    		print 'forward:' + str(self.name) + ' defense!'
    
    class Guard(Player):
    	def __init__(self, name):
    		Player.__init__(self, name)
    	def Attack(self):
    		print 'forward:' + str(self.name) + ' attack!'
    	def Defense(self):
    		print 'forward:' + str(self.name) + ' defense!'
    
    #ForeignCenter hasn't the Attack/Defense method
    #he only has the JinGong/FangShou method
    #you can't direct him by calling Attack() or Defense()
    class ForeignCenter(): 
    	def __init__(self, name):
    		self.name = name
    	def JinGong(self):
    		print 'ForeignCenter:' + str(self.name) + ' attack!'
    	def FangShou(self):
    		print 'ForeignCenter:' + str(self.name) + ' defense!'
    
    2.翻译类
    #!/usr/bin/python
    # Filename: translator.py
    
    import player as p
    
    #now you can direct ForeignCenter to attack
    #by calling the tanslator's Attack()
    #then he will calling ForeignCenter's JinGong()
    class Translator():
    	def __init__(self, name):
    		self.center = p.ForeignCenter(name)
    	def Attack(self):
    		self.center.JinGong()
    	def Defense(self):
    		self.center.FangShou()
    
    3.教练(客户端)
    #!/usr/bin/python
    # Filename: console.py
    
    import player as player
    import translator as t
    
    b = player.Forward('Battier')
    b.Defense()
    
    m = player.Guard('McGrady')
    m.Attack()
    
    y = t.Translator('Yao Ming')
    y.Attack()
    y.Defense()
    
    2011-05-08 19:04:50 回应
<前页 1 2 后页>

[已注销]的其他笔记  · · · · · ·  ( 全部295条 )

The Design of Everyday Things
1
About Face 3
6
Engineering a Compiler
1
人有人的用处
8
Understanding the Linux Kernel
4
计算机程序设计艺术
1
公正
1
The Art of Doing Science and Engineering: Learning to Learn
1
科学革命的结构
7
罗素论教育
3
三十六大
1
娱乐至死
3
Real World Haskell
2
Writing Analytically
1
Is Parallel Programming Hard, And, If So, What Can You Do About It?
1
计算机与人脑
1
组合数学
2
菊与刀
1
Rework
5
翻译新究
4
计算机程序的构造和解释(原书第2版)
5
The Laws of Simplicity
4
计算机组成与设计硬件/软件接口
6
写给无神论者
2
放任自流的时光
3
哥德尔、艾舍尔、巴赫
2
树上的男爵
2
C++语言的设计与演化
1
Land of LISP
7
C陷阱与缺陷
2
CUDA by Example
3
C++沉思录
1
世界尽头与冷酷仙境
4
Head First C
2
刀锋
1
并行编程模式
2
The Ph.D. Grind
2
计算机系统结构
2
禅与摩托车维修艺术
14
流浪的面包树
2
翻译研究
18
An Introduction to Programming in Emacs Lisp
1
GNU Emacs Lisp 编程入门
1
计算机系统概论
1
编码
3
拖延心理学
1
古今数学思想(一)
1
挪威的森林
9
奇特的一生
7
GPU高性能运算之CUDA
5
那些年,我们一起追的女孩
8
十八岁给我一个姑娘
2
C++编程思想(第1卷)
9
多核计算与程序设计
8
少有人走的路
5
忧伤的情欲
3
Hackers & Painters
7
哲学的慰藉
9
男人来自火星 女人来自金星
8
旅行的艺术
14
活着活着就老了
1
如何阅读一本书
7
Data-intensive Text Processing With Mapreduce
1
学习GNU Emacs
1
给研究生的学术建议
3
C专家编程
2
Spring揭秘
2
Head First Java(第二版·中文版)
1
自私的基因
1
C程序设计语言
2
计算机网络
3
自由在高处
2
计算机网络
12