'분류 전체보기'에 해당되는 글 430건
- 2009.01.07 Database 종류에 따른 Parameter 지원
- 2009.01.07 Database Connection Strings
- 2009.01.07 알기 쉬운 Design Pattern
- 2009.01.07 알기 쉬운 Design Pattern
- 2009.01.07 0005. Jolly Jumper
- 2009.01.07 0004. Seven-Segment
- 2009.01.07 0003. The Trip
- 2009.01.07 0002. Minesweeper
- 2009.01.07 0001. Three plus one
- 2009.01.07 최소 지식 원칙
http://www.connectionstrings.com/?carrier=mysql
Microsoft Access
DSN이 없는 경우
Set Cnn = Server.CreateObject("ADODB.Connection")
Cnn.open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\mydatabase.mdb"
OLE DB
Set Cnn = Server.CreateObject("ADODB.Connection")
Cnn.open "PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=c:\mydatabase.mdb"
DSN과 사용자 ID/암호가 모두 있는 경우
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.open "DSNname","username","password"
Microsoft SQL Server
OLE DB
Set cnn = Server.CreateObject("ADODB.Connection")
cnn.open "PROVIDER=SQLOLEDB;DATA SOURCE=sqlservername;UID=username;PWD=password;DATABASE=mydatabase "
SN이 없는 경우
<%
Set Conn = Server.CreateObject("ADODB.Connection")
ConnStr= "Driver=Microsoft Visual Foxpro Driver; UID=userID;SourceType=DBC;SourceDB=C:\databases\mydatabase.dbc"
Conn.Open ConnStr
%>
1.
Facade Pattern
·
새로운 Class나
인터페이스의
정립
·
복잡한
시스템을
쉽게
사용한다.
·
시스템의
한
부분만을
이용하거나
특별한
방법으로
시스템을
이용하도록
한다.
·
보다
더
단순하고, 사용하기
쉬운
시스템
또는
요구에
맞는
최적화된
시스템을
갖게
된다.
Facade 패턴 : 핵심 특징
의도 : 기존에 존재하고
있던
시스템을
이용하는
방법을
단순화
하고
싶다.
-> 자신만의
인터페이스를
정의한다.
·
문제점 : 복잡한
시스템의
오직
부분만을
이용해야지
된다.
또는
특별한
방법으로
시스템과
상호작용
되어야
한다.
·
해결책 : 기존에
존재하고
있던
시스템을
이용하려고
하는
Client를
위한
새로운
인터페이스를
제시한다.
o
새로운 Class에서는
기존의
Class를
소유(has
- a)하게
된다.
o
새롭게
외부로
노출된
방법을
통해서,
기능을
구현하게
된다.
·
참여자와
협력자
: Client가
좀더
사용하기
쉽도록
특별한
인터페이스를
제시한다.
·
결과
o
필요한 Sub System의
이용을
단순화
한다.
: 부분만을
이용하고, 특별한
방법으로의
시스템과
상호작용되기
때문
o
모든
기능을
다
처리하지는
않는다.
·
구현
o
필요한
인터페이스를
갖는
새로운
Class를
정의한다.
o
새롭게
만들어진 Class에서
기존에
존재하던
시스템을
이용하게
된다.
2. Adapter Pattern
·
새로운 인터페이스를 만들자.
o 올바른 작업을 수행하지만, 잘못된 인터페이스를 가진 객체를 위해 새로운 인터페이스를 생성하기 위한 방법이 필요하다.
·
Client 객체가 상세한 사항을 알 필요가 없게 하자.
Adapter 패턴 : 핵심 특징
·
의도 : 통제 범위 이면에 있는 기존에 존재하고 있던 객체를 특별한 인터페이스와 조화시키자.
·
문제점 : 시스템은 올바른 데이터와 행위를 가지고 있지만, 잘못된 인터페이스를 가지고 있다. 일반적으로 정의하고 있거나 이미 정의된 추상 클래스의 파생 클래스를 만들기 위해 사용된다.
·
해결법 : Adapter 패턴은 원하는 인터페이스를 가진 래퍼를 제공한다.
·
참 여자와 협력자 : Adapter는 자신의 Target 클래스(Adapter 클래스는 이 Target 클래스로부터 파생)가 가진 인터페이스와 조화시키기 위해 Adaptee 클래스의 인터페이스를 적응시킨다. 이는 Client가 Adaptee를 마치 Target 나잎인것 처럼 사용할 수 있게 된다.
·
결과 : 이미 존재하는 객체들이 그들의 인터페이스에 의해 제한받지 않고 새로운 클래스 구조에 맞출수 있게 된다.
·
구현 : 또 다른 클래스에 기존에 존재하고 있던 클래스를 포함시킨다. 포함하는 클래스는 요구되는 인터페이스에 조화시키고 포함되는 클래스의 메소드를 호출한다.
3.
Bridge Pattern
·
Bridge 패턴에 통합된 Adapter 패턴을 보게 되는 것일 일반적
·
합성
디자인
패턴으로
구현되는
경우가
많다.
Bridge 패턴의 핵심 특징
·
의도 : 구현을
이용하는
객체의
집합으로부터
구현의
집합을
분리한다.
·
문제점 : 추상클래스의
파생
클래스가
폭발적으로
증가되는
것을
막는다.
·
해결법 : 이용하고자
하는
모든
구현에
대한
인터페이스를
정의하고, 이
구현을
이용하는
추상
클래스의
파생
클래스를
갖는다.
·
참
여자와
협력자
: 구현되고
있는
객체에
대해
인터페이스를
정의한다. Implementor는
특정한
구현
클래스에
대해
인터페이스를
정의한다. Abstraction으로부터
파생
클래스는
어떤
특정한
ConcreteImplementor가
이용되는지
알지
못하면서 Implementor로부터
파생
클래스를
이용한다.
·
결과 : 구현을
이용하는
객체로부터
그
구현을
분리하는
것은
확장성을
높여준다. 클라이언트
객체는
구현에
대한
사항을
알지
못한다.
·
구현
o
추상
클래스에
구현을
캡슐화
한다.
o
구현되고 있는 추상화 개념의 기본 클래스 안에 구현에 대한 처리를 포함한다.
4.
Abstract Factory
·
시스템이
항상
자기의
상황을
위해
정확한
객체를
얻도록
보증한다.
Abstract Factory 패턴 : 핵심 특징
·
의도 : 특정
클라이언트를
위한
객체
집합이나
군을
갖기를
원한다.
·
문제점 : 관련된
객체
군은
인스턴스화
되어야
한다.
·
참여자와
협력자
: AbstractFactory는
요구되는
객체
군의
각
맴버를
생성하는
방법을
위한
인터페이스를
정의한다. 일반적으로, 각각의
군은
자신의
유일한
ConcreteFactory를
가짐으로
객체로
생성된다.
·
결과 : 이
패턴은
객체를
이용하는
방법에
대한
로직으로부터
어떤
객체를
이용할것인가
하는
규칙을
분리한다.
·
구현 : 어떤
객체가
만들어지는지를
명시한
추상
Class를
정의하자. 그런
다음
객체들의
각
군을
위해
하나의
구체적인
클래스를
구현하자.
5.
Stratege Pattern
·
GOF에서 제시한 원칙에 의해서 만들어진다.
·
새로운
요구사항을
처리하는
방법으로
사용
o
객체의
재사용을
위해
상속을
최대한
피해서
사용하자.
o
상속이
아닌,
소유로서
구현한다. : 변화하는 개념을 캡슐화 한다.
Strategy 패턴 : 핵심 특징
·
의도 : 서로다른
비지니스
규칙
또는
알고리즘을
만들어
이들이
발생하는
전후
관계에
맞게
이용할
수
있게
해준다.
·
문제점 : 알고리즘의
선택은
클라이언트의
요청에
맞게
데이터의
행동에
맞게
적용되어야지
된다.
단순히
변경되지
않는
규칙만을
가지고
있다면
Strategy 패턴은
필요가
없다.
·
해결법 : 알고리즘의
구현과
선택을
분리하자. 전후
관계를
기반으로
선택을
하도록
하자
·
참여자와
협력자
o
Strategy는 다른 알고리즘이
어떻게
이용되는지
명시한다.
o
ConcreteStrategie들은 이런 다른 알고리즘을 구현한다.
o
Context는 Strategy 타잎의 레퍼런스로 구체적인 ConcreteStrategy를 이용한다.
·
결과
o
Strategy 패턴은 알고리즘의 한 군을 형성한다.
o
switch 문 if/else 조건문이 제거된다.
o
모든 알고리즘이 동일한 방법으로 호출되어야지 된다.
·
구현
o
알고리즘을
호출하는
방법을
명시하는
추상
메소드를
갖는
추상클래스를
포함하는
클래스를
갖는다.
: SerialPolling
o
각각의
파생
클래스는
필요에
따라
알고리즘을
구현한다. : StrignParser
Design Pattern의 방법
- 프로그램을 구현이 아닌 인터페이스를 통해 만든다.
- 클래스간의 상속보다는 객체간의 합성을 선호한다.
- 설계에서 무엇이 변할 수 있는것인지를 고려한다.
객체 지향 원리
- 객체는 자신에 대한 책임을 지닌다.
- 추상 클래스 : 개념을 나타내기 위한 Class. 개념을 묶기 위한 도구로서 이용
- 추상 클래스를 통한 캡슐화
- 하나의 규칙 하나의 장소 -> 전체 패턴에 대한 규약을 정해주게 된다.
require 'test/unit'
class JollyJumper
attr_reader :values
def initialize
@values = []
end
def insert_value(value)
@values << value
end
def print_values
@values.each{ |value| print value.to_s + ' ' }
end
def calculate
result = true
@values.each_index do |index|
first_value = (@values[index -1] - @values[index]).abs if @values[index-1] != nil
second_value = (@values[index +1] - @values[index]).abs if @values[index+1] != nil
result &= values.member?(first_value) if first_value != nil
result &= values.member?(second_value) if second_value != nil
end
result
end
endclass JollyJumperTest < Test::Unit::TestCase
def test_case1
jumper = JollyJumper.new
assert_not_equal(nil, jumper)
jumper.insert_value(4)
jumper.insert_value(1)
jumper.insert_value(4)
jumper.insert_value(2)
jumper.insert_value(3)
jumper.print_values()
assert_equal(true, jumper.calculate)
end
def test_case2
jumper = JollyJumper.new
assert_not_equal(nil, jumper)
jumper.insert_value(5)
jumper.insert_value(1)
jumper.insert_value(4)
jumper.insert_value(2)
jumper.insert_value(-1)
jumper.insert_value(6)
jumper.print_values()
assert_equal(false, jumper.calculate)
end
end
import unittest
import os
import mathsegment_enables = [
[True, True, True, False, True, True, True],
[False, False, True, False, False, True, False],
[True, False, True, True, True, False, True],
[True, False, True, True, False, True, True],
[False, True, True, True, False, True, False],
[True, True, False, True, False, True, True],
[False, True, False, True, True, True, True],
[True, True, True, False, False, True, True],
[True, True, True, True, True, True, True],
[True, True, True, True, False, True, True]
]
class SevenSegmentNumber:
def __init__(self, number, size):
self.size = size
self.number = number
self.max_line = size * 2 + 3
def printHorizontalLine(self, print_enable):
lines = ' '
for i in range(self.size):
if print_enable:
lines = lines + '-'
else:
lines = lines + ' '
lines = lines + ' '
return lines
def printVerticalLine(self, print_first, print_last):
lines = ''
vert_size = self.size + 2
if print_first:
lines = lines + '|'
else:
lines = lines + ' '
for i in range(vert_size - 2):
lines = lines + ' 'if print_last:
lines = lines + '|'
else:
lines = lines + ' '
return lines
def getLine(self, line):
total_line = self.size * 2 + 3
line_segment = (total_line - 3) / 2 + 1
line_end = total_line - 1
out_line = ''
if line == 0:
out_line = self.printHorizontalLine(segment_enables[self.number][0])
elif 0 < line and line < line_segment:
out_line = self.printVerticalLine(segment_enables[self.number][1], segment_enables[self.number][2])
elif line == line_segment:
out_line = self.printHorizontalLine(segment_enables[self.number][3])
elif line_segment < line and line < line_end:
out_line = self.printVerticalLine(segment_enables[self.number][4], segment_enables[self.number][5])
elif line == line_end:
out_line = self.printHorizontalLine(segment_enables[self.number][6])
return out_lineclass Numbers:
def __init__(self):
self.numbers = []
self.seven_segments = []def displayNumber(self, number, size):
decimal = int(math.log(number) / math.log(10)) + 1
self.numbers = []
self.seven_segments = []
for i in range(decimal):
self.numbers.append(int(str(number)[i]))
segment = SevenSegmentNumber(self.numbers[i], size)
self.seven_segments.append(segment)
max_line = self.seven_segments[0].max_line
for i in range(max_line):
line = ''
for s in range(decimal):
line = line + self.seven_segments[s].getLine(i) + ' '
print line
class SevenSegmentNumberTest(unittest.TestCase):
"""
def testDisplay(self):
print 'Start'
zero = SevenSegmentNumber(8, 3)
for i in range(zero.max_line):
print zero.getLine(i),
print ""
"""
def testNumber1(self):
number = SevenSegmentNumber(8, 2)
#print number.getLine(0)
#self.assertEqual(number.max_line, 3 + 2 * 2)
#self.assertEqual(' ', number.getLine(0))
#self.assertEqual(' |', number.getLine(1))
#for i in range(0, number.max_line):
# print number.getLine(i)
def testOutputNumber(self):
for i in range(10):
number = SevenSegmentNumber(i, 2)
for j in range(number.max_line):
print number.getLine(j)
if __name__ == '__main__':
#unittest.main()
n = Numbers()
n.displayNumber(1238, 3)
require 'test/unit'
class SevenSegment
attr_reader :number, :size, :height, :width
attr_writer :number, :size
@@segment_enables = [
[true, true, true, false, true, true, true],
[false, false, true, false, false, true, false],
[true, false, true, true, true, false, true],
[true, false, true, true, false, true, true],
[false, true, true, true, false, true, false],
[true, true, false, true, false, true, true],
[false, true, false, true, true, true, true],
[true, true, true, false, false, true, false],
[true, true, true, true, true, true, true],
[true, true, true, true, false, true, true] ]
def initialize(number, size)
@number = number
@size = size
@height = size * 2 + 3
@width = size + 2
end
def get_vertical_line(mark_first, mark_second)
line = ''
length = @size + 2
line = line + '|' if mark_first
line = line + ' ' if !mark_first@size.times { line = line + ' ' }
line = line + '|' if mark_second
line = line + ' ' if !mark_second
line
end
def get_horizontal_line(enable)
mark = ''
mark = '-' if enable
mark = ' ' if !enable
length = self.size + 2line = ' '
@size.times { line = line + mark }
line = line + ' '
line
end
def get_line(line_count)
if line_count == 0 then self.get_horizontal_line(@@segment_enables[@number][0])
elsif line_count > 0 and line_count < (@size+1) then self.get_vertical_line(@@segment_enables[@number][1], @@segment_enables[@number][2])
elsif line_count == (@size+1) then self.get_horizontal_line(@@segment_enables[@number][3])
elsif line_count > (@size+1) and line_count < (@size * 2 + 2) then self.get_vertical_line(@@segment_enables[@number][4], @@segment_enables[@number][5])
elsif line_count == (@size * 2 + 2) then self.get_horizontal_line(@@segment_enables[@number][6])
end
end
endclass SevenSegments
attr_reader :numbers, :size
attr_writer :numbers, :size
def initialize(size, number)
@size = size
self.set_number(number)
enddef set_number(number)
@numbers = []
string_numbers = number.to_s()
string_numbers.length.times { |index| @numbers << string_numbers[index] - 48 }
enddef display_number
puts ' '
seven_segments = []
@numbers.each { |n| seven_segments << SevenSegment.new(n, @size) }
line = @size * 2 + 3line.times do |line_count|
line = ''
seven_segments.each do |seven_segment|
line = line + seven_segment.get_line(line_count) + ' '
end
puts line
end
end
endclass SevenSegmentsTest < Test::Unit::TestCase
def test_numbers
s = SevenSegments.new(3, 987654321)
print s.numbers[0]
s.display_number
assert_equal(9, s.numbers[0])
end
endclass SevenSegmentTest < Test::Unit::TestCase
def test_number0
s = SevenSegment.new(0,2)
assert_equal(" -- ", s.get_line(0))
assert_equal("| |", s.get_line(1))
assert_equal("| |", s.get_line(2))
assert_equal(" ", s.get_line(3))
assert_equal("| |", s.get_line(4))
assert_equal("| |", s.get_line(5))
assert_equal(" -- ", s.get_line(6))
enddef test_number1
s = SevenSegment.new(1,2)
assert_equal(" ", s.get_line(0))
assert_equal(" |", s.get_line(1))
assert_equal(" |", s.get_line(2))
assert_equal(" ", s.get_line(3))
assert_equal(" |", s.get_line(4))
assert_equal(" |", s.get_line(5))
assert_equal(" ", s.get_line(6))
end
def test_number8
s = SevenSegment.new(8,2)
assert_equal(" -- ", s.get_line(0))
assert_equal("| |", s.get_line(1))
assert_equal("| |", s.get_line(2))
assert_equal(" -- ", s.get_line(3))
assert_equal("| |", s.get_line(4))
assert_equal("| |", s.get_line(5))
assert_equal(" -- ", s.get_line(6))
end
end
import unittest class TheTrip: def __init__(self, count): self.count = count self.costs = [] pass def inputCost(self, cost): self.costs.append( float(cost * 100) ) def calculateAverageCost(self): return float( sum(self.costs) / len(self.costs) ) / 100.00 def calculateMinCharge(self): average = self.calculateAverageCost() * 100.00 diff_values = [] for value in self.costs: differ = average - value diff_values.append(abs(differ)) return sum(diff_values) / 2.00 / 100.00 class TheTripTest(unittest.TestCase): def setUp(self): pass def testInsertValue(self): t = TheTrip(3) t.inputCost(10.00) t.inputCost(20.00) t.inputCost(30.00) self.assertEqual(20.00, t.calculateAverageCost()) self.assertEqual(10.00, t.calculateMinCharge()) def testInsertValue2(self): t = TheTrip(4) t.inputCost(15.00) t.inputCost(15.01) t.inputCost(3.00) t.inputCost(3.01) self.assertEqual(11.99, t.calculateMinCharge()) if __name__ == '__main__': unittest.main()
require 'test/unit' class TheTrip attr_reader :member, :costs, :average attr_writer :member, :costs def initialize(number) self.member = number self.costs = [] end def input_cost(cost) self.costs << cost @average = 0 self.costs.each {|value| @average += value } @average /= self.costs.length end def get_min_charge() charges = 0.00 self.costs.each { |value| charges += (value - self.average).abs } return charges / 2.00 end end class TheTripTest < Test::Unit::TestCase def test_case1 t = TheTrip.new(3) t.input_cost(10.00) t.input_cost(20.00) t.input_cost(30.00) assert_equal(20.00, t.average) assert_equal(10.00, t.get_min_charge()) end def test_case2 t = TheTrip.new(4) t.input_cost(15.00) t.input_cost(15.01) t.input_cost(3.00) t.input_cost(3.01) assert_equal(11.99, t.get_min_charge()) end end
import os
import unittest
class Minesweeper:
def __init__(self):
self.rows = []
pass
def clearRow(self):
self.rows = []
def insertRow(self, row):
self.rows.append(row)
def printArray2D(self, array_2d):
for row in array_2d:
for item in row:
print item,
def printMine(self):
self.printArray2D(self.rows)
def initLocation(self):
mine_locations = []
for row in self.rows:
row_locations = []
for item in row:
row_locations.append(0)
mine_locations.append(row_locations)
self.mine_locations = mine_locations
def isInRange(self, row_location, col_location):
if row_location >= 0 and col_location >= 0 and row_location < len(self.rows) and col_location < len(self.rows[0]):
return True
else:
return False
def getMineLocation(self):
self.initLocation()
row_location = 0
for row in self.rows:
col_location = 0
for item in row:
if item == '*':
self.mine_locations[row_location][col_location] = '*'
for row_index in [-1, 0, 1]:
for col_index in [-1, 0, 1]:
if self.isInRange(row_location + row_index, col_location + col_index) and self.mine_locations[row_location + row_index][col_location + col_index] != '*':
self.mine_locations[row_location + row_index][col_location + col_index] += 1
col_location += 1
row_location += 1
def printMineLocation(self):
self.printArray2D(self.mine_locations)
class MinesweeperTest(unittest.TestCase):
def setUp(self):
pass
def testCheckValue(self):
m = Minesweeper()
m.insertRow(['.','.','*','.'])
m.insertRow(['.','*','.','.'])
m.printMine()
self.assertEqual(m.isInRange(0,0), True)
self.assertEqual(m.isInRange(5,0), False)
self.assertEqual(m.isInRange(1,0), True)
self.assertEqual(m.isInRange(0,5), False)
m.getMineLocation()
m.printMineLocation()
def testCheckMine2(self):
m = Minesweeper()
m.insertRow(['*', '*', '.', '.', '.'])
m.insertRow(['.', '.','.','.','.'])
#m.insertRow(['.', '.','.','.','.'])
m.insertRow(['.', '*','.','.','.'])m.getMineLocation()
m.printMineLocation()
self.assertEqual(True, True)
#def tearDown(self):
# passif __name__ == '__main__':
unittest.main()
require 'test/unit'
class Minesweeper
attr_reader :rows, :calc_locations
attr_writer :rows, :calc_locations
def initialize
self.rows = []
self.calc_locations = []
end
def print_rows
@rows.length.times do |row_index|
@rows[row_index].length.times {|col_index| print @rows[row_index][col_index].to_s() + ' ' }
puts ' '
end
enddef calc_rows
self.calc_locations = []
rows.length.times do |row_index|
row = []
rows[row_index].length.times do |col_index|
if rows[row_index][col_index] != '*' : row.push(0)
else row.push('*')
end
end
@calc_locations.push(row)
end@rows.length.times do |row_index|
@rows[row_index].length.times do |col_index|
-1.upto(1) { |i| -1.upto(1) { |j| @calc_locations[i+row_index][j+col_index] += 1 if self.is_in_range(i+row_index,j+col_index) } } if @rows[row_index][col_index] == '*'
end
end
enddef is_in_range(row_index, col_index)
return false if row_index < 0
return false if col_index < 0
return false if row_index >= @calc_locations.length
return false if col_index >= @calc_locations[row_index].length
return false if @rows[row_index][col_index] == '*'
return true
enddef print_calc_rows
@calc_locations.length.times do |row_index|
@calc_locations[row_index].length.times {|col_index| print @calc_locations[row_index][col_index].to_s() + ' ' }
puts ' '
end
end
endclass MinesweeperTest < Test::Unit::TestCase
def test_case1
mine = Minesweeper.new()
mine.rows.push(['.', '*', '.', '.', '*'])
mine.rows.push(['.', '.', '*', '.', '.'])
mine.rows.push(['.', '.', '*', '.', '.'])
mine.rows.push(['.', '.', '*', '.', '.'])
mine.print_rows()
mine.calc_rows()
mine.print_calc_rows()
assert_equal(1, 1)assert_equal(true, mine.is_in_range(0,0))
assert_equal(false, mine.is_in_range(6, 0))
assert_equal(false, mine.is_in_range(0, 1))
assert_equal(1, mine.calc_locations[0][0])
assert_equal(2, mine.calc_locations[0][2])
end
end
Python
import sys import unittest class ThreePlusOne: def __init__(self): pass def getArray(self, number): return self.__calculateValues(number) def __calculateValues(self, number): current_value = number calculated_values = [] calculated_values.append(current_value) while current_value != 1: if (current_value % 2) == 0: current_value = current_value / 2 else: current_value = current_value * 3 + 1 calculated_values.append(current_value) return calculated_values def getLength(self, number): return len(self.__calculateValues(number)) def getMaxLengthWithRange(self, start_number, end_number): max_length = 0 for current_number in range(start_number, end_number): length = self.getLength(current_number) if length > max_length: max_length = length return max_length def displayResult(self, start_number, end_number): max_length = self.getMaxLengthWithRange(start_number, end_number) print '%d %d %d' % (start_number, end_number, max_length) class ThreePlusOneTest(unittest.TestCase): def setUp(self): pass def testCheckValue(self): correct_values = [22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1] t = ThreePlusOne() make_values = t.getArray(22) self.assertEqual(make_values, correct_values) def testCheckSize(self): correct_value = 16 t = ThreePlusOne() make_value = t.getLength(22) self.assertEqual(make_value, correct_value) def testCheckRange(self): t = ThreePlusOne() result = t.getMaxLengthWithRange(1, 10) self.assertEqual(result, 20) result = t.getMaxLengthWithRange(100, 200) self.assertEqual(result, 125) result = t.getMaxLengthWithRange(201, 210) self.assertEqual(result, 89) result = t.getMaxLengthWithRange(900, 1000) self.assertEqual(result, 174) def testDisplay(self): t = ThreePlusOne() t.displayResult(1, 10) t.displayResult(100, 200) t.displayResult(201, 210) t.displayResult(900, 1000) if __name__ == '__main__': unittest.main()
Ruby
require 'test/unit' class ThreePlusOne attr_reader :recent_results, :recent_number attr_writer :recent_results, :recent_number def getArray(number) self.calculate(number) return self.recent_results end def getLength(number) self.calculate(number) return self.recent_results.length end def getMaxLengthWithRange(start_number, end_number) max_length = 0 for i in start_number..end_number current_length = self.getLength(i) max_length = [max_length, current_length].max end return max_length end def calculate(number) @recent_number = number @recent_results = [] current_value = number @recent_results.push(current_value) while current_value != 1 if current_value % 2 == 0 : current_value = current_value / 2 else current_value = current_value * 3 + 1 end @recent_results.push(current_value) end return @recent_results end end class TestThreePlusOne < Test::Unit::TestCase def test_case t = ThreePlusOne.new() assert_equal(t.getArray(22), [22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]) assert_equal(t.getLength(22), 16) assert_equal(t.getMaxLengthWithRange(1, 10), 20) assert_equal(t.getMaxLengthWithRange(100, 200), 125) assert_equal(t.getMaxLengthWithRange(201, 210), 89) assert_equal(t.getMaxLengthWithRange(900, 1000), 174) end end
최소 지식 원칙에서의 가이드라인
1. 객체 자체만의 호출
2. 메소드에서 매개 변수로 전달된 객체
3. 그 메소드에서 생성하거나 인스턴스를 만든 객체
4. 그 객체에 속하는 구성 요소
public static double GetTemplrature()
{
// NOTE : 틀린 경우
Thermoeter thermometer = station.GetThermometer();
return thermometer.GetTemperature();
}
public static double GetTemperature()
{
//NOTE : 맞는 경우
return station.GetTemperature();
}