Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
obj.getProperty () и obj.setProperty ().array.length--, не только уменьшится значение поля length, но и «прозрачно» вызовется метод, который удалит последний элемент массива.An Object is an unordered collection of properties.Так что, здесь Вы правы.
obj.getProperty() и obj.setProperty(value); использовать свойства.class Person
{
private long _money;
public long money
{
get
{
/*
!!!!!!!!!!!!!
Метод для получения данных
*/
return (_money);
}
set
{
/*
!!!!!!!!!!!!!
Метод для записи данных
*/
_money = value;
}
}
}
/*
Вызов методов происходит прозрачно
*/
Person psnBillGates = new Person ();
lngOldRiches = psnBillGates.money; //Чтение
psnBillGates.money = lngNewRiches; //Запись
psnBillGates.money += 1000000000; //Инкрементация
Вы только представьте: У нас есть функция в 300 строк кода [2]. Где-нибудь на 200-й строке нам надо поменять две переменные местами. Для этого мы лезем на 200 сток выше в начало функции, объявляем переменную temp, которая не имеет никакого отношения ко всей функции, а используется только один раз в одном месте, потом опять возвращаемся к 200-й строке и меняем переменные местами… По-моему, это просто кошмар.
Вообще, надо стараться избегать длинных функций и методов. Одно из правил рефакторинга: «если текст метода не умещается на экране без прокрутки — это уже повод разбить его на несколько более коротких методов».
Однако, это далеко не всегда удается, например при генерации отчетов или при реализации сложных вычисления.
<?php
interface AB
{
public function getX();
}
class A
{
private $x = 1;
protected function getX()
{
return( $this->x );
}
}
class B extends A implements AB
{
public function getX()
{
return( parent::getX() );
}
}
$b = new B();
echo( $b->getX() );
?>
Пункт 3 [Отсутствие локальных функций], кстати, очевидно не относится к объектно-ориентированным языкам.В основном да, но не совсем: например в C++ нет полноценных локальных функций.
function main ()
{
//...
function sub1 ()
{
/*
Вот это локальная функция sub1, объявленная в теле функции main
*/
}
function sub2 ()
{
}
}Если же он делает какую-то дополнительную работу — можно и нередко нужно определить его как метод.
Человеку работающему со сторонним фреймворком зачастую полезно знать что он вызывает метод.
Person psnBillGates = new Person ();
lngOldRiches = psnBillGates.money; //Чтение
psnBillGates.money = lngNewRiches; //Запись
psnBillGates.money += 1000000000; //Инкрементацияint ai,bi;
float af,bf;
char *ap,*bp;
void swap_something(int what) {
int tmpi;
float tmpf;
char *tmpp;
switch(what) {
case 0:
tmpi=ai; ai=bi; bi=tmpi;
break;
case 1:
tmpf=af; af=bf; bf=tmpf;
break;
case 2:
tmpp=ap; ap=bp; bp=tmpp;
break;
}
}
void swap_something(int what) {
switch(what) {
case 0:
{ int tmpi=ai; ai=bi; bi=tmpi; }
break;
case 1:
{ float tmpf=af; af=bf; bf=tmpf; }
break;
case 2:
{ char* tmpp=ap; ap=bp; bp=tmpp; }
break;
}
}
В идеальном случае сразу объявляйте и определяйте каждую переменную непосредственно перед первым обращением к ней
Person psnBillGates = new Person ();
lngOldRiches = psnBillGates.money; //Чтение
psnBillGates.money = lngNewRiches; //Запись
psnBillGates.money += 1000000000; //ИнкрементацияНапример, на счет локальных функций — все зависит от конкретного случая. Иногда их использование скорее вредит, нежели наоборот.
// аналог полиморфной структуры (есть в стандартной библиотеке)
variant Option['a]
{
| Success { value : 'a }
| None
}
// подозрительная функция, как TryParse
def SuspiciousFunction (data : string) : Option[double] { ... }
//использование
match(SuspiciousFunction("qwerty"))
{
| Success(result) => ... // все хорошо
| None => ... // плохой аргумент
}
Отсутствие именованных параметров функции
Тоже не так однозначно. У нас(в примере) прямоугольник. Он ОБЯЗАН иметь 4 угла. И createPoligon(point1,point2,point3,point4) как-то гарантирует, что при его создании у нас они будут.
Math.pow (2, 5)Math.summ (3, 7, 18, -2, 11, 2.3)RotationInterpolator rotator = new RotationInterpolator (
new Alpha (-1, Alpha.DECREASING_ENABLE, 0, 0, 8000, 0, 0, 0, 0, 0),
xformGroup, axis, 0.0f, (float)Math.PI*2.0f);
int a = [self age];
[self setAge:20];
int a = [self valueForKey:@«age»];
[self setValue:10 forKey:@«age»];
Ну и не стоит забывать, что отсутствие в коде приведенных «уродских приемов» — лишь идеальная ситуация, к которой надо стремиться, но приходится жертвовать в определенных ситуациях (например, в целях производительности).
int someshit() {
int theData;
...
int doFoo() {
# делаем что-то c theData
...
}
...
int doBar() {
# делаем еще что-то с theData
...
}
...
doFoo();
...
doBar();
...
return theData;
}
int a=0;
void incA(void) {
a++
}
incA();
int bar = 0;
class Foo {
void doBar() {
bar++; // ZOMG mutable variables!!11
}
}
int someshit(params) {
int theData;
... #
int doFoo() {
# делаем что-то c theData и/или с params
...
}
return doFoo;
}
if (foo.bar == 1)
foo.bar = 1;Helper.ext(obj, foo, bar)
obj.ext(foo, bar)
foo = map (**2) $ filter odd
public static IEnumerable<int> Foo(IEnumerable<int> sequence)
{
return sequence.Where(x => x % 2 == 1).Select(x => x * x);
}
def foo(sequence):
return map(lambda x: x * x, filter(lambda x: x % 2 == 1, sequence))
def foo(sequence):
return [x*x for x in sequence if x%2]
return Enumerable.Where(Enumerable.Select(sequence, x => x * x), x => x % 2 == 1);
def y: ... y = f(y)
@f def y: ...
К сожалению, лишь немногие языки поддерживают именованные параметры функций (я могу вспомнить только динамические Perl, Python и Ruby, может быть есть еще).Фортран поддерживает, как это ни странно :)
People *leaders [7] =
{
new People ("Ленин", "Владимир", "Ильич"),
new People ("Сталин", "Иосиф", "Виссарионович"),
new People ("Хрущев", "Никита", "Сергеевич"),
new People ("Брежнев", "Леонид", "Ильич"),
new People ("Андропов", "Юрий", "Владимирович"),
new People ("Черненко", "Константин", "Устинович"),
new People ("Горбачев", "Михаил", "Сергеевич")
};
function quadraticEquation (numA, numb, numC)
{
//...
return ({
count: intRootsCount,
x1: intX1,
x2: intX2
});
}
#include <iostream>
int main(char** argv) {
struct {
void hello() {
std::cout << "Hello, world!" << std::endl;
}
} x;
x.hello();
return 0;
}
for (long numBugNumber = 0; numBugNumber < objWinVista.bugsCount; numBugNumber++)
{
println (objWinVista.bugs [numBugNumber]);
}
<pre>
На самом деле этот код хочет быть таким
<pre>
for (var bug in winVista.bugs)
{
print(bug)
}
for (long i = 0; i < WinVista.bugsCount; i++)
{
println (objWinVista.bugs [i]);
}
<pre>
Что конкретное делает i понятно благодяря этому соглашению и тому что цикл маленький.
А про венгерскую нотацию читайте programmer's stone
std::pair<bool, int> some_complex_calculation() {
//......
return std::make_pair(true, 1234);
}
....
std::pair<bool, int> result = some_complex_calculation();
if (result.first) {
// do something useful
}
10 приемов, разрушающих хрупкую красоту кода