Сча будет жуткая ересь. Сторонникам чистого и правильного кода читать не рекомендуется :) С другой стороны, DRY (Don`t repeate youself) и KISS (Keep it simple stupid). Если DRY и KISS для вас важнее некой "чистоты", то читайте :)
Захотелось мне более лаконичного MXML кода. Ибо кое-где он бывает раздражительно избыточным. Например:
<s:HGroup id="contentGroup"
paddingTop="10" paddingBottom="10" paddingLeft="15" paddingRight="15"/>
Не хочу так, хочу эдак:
<HG id="contentGroup" padd="15,10,15,10"/>
Ну не проблема, нужно наследоваться от HGroup, добавить свойство padd и все дела:
package com.flashcoms.yzh.fext
{
import spark.components.VGroup;
public class VG extends VGroup
{
public function set padd(value : String) : void
{
var values : Array = value.split(",");
if(values.length == 1)
{
paddingLeft = paddingTop = paddingRight = paddingBottom = validatePadd(values[0]);
}
else
{
paddingLeft = validatePadd(values[0]);
paddingTop = validatePadd(values[1]);
paddingRight = validatePadd(values[2]);
paddingBottom = validatePadd(values[3]);
}
}
private function validatePadd(value : String) : int
{
if(!value) return 0;
var res : int = parseInt(value);
if(isNaN(res)) return 0;
return res < 0 ? 0 : res;
}
}
}
Ок, гуд, работает. Теперь нужно тоже самое для VGroup. Гм. Наследоваться от VGroup и скопипастить? Всунуть в оригинальный класс spark.components.Group? Наследовать еще один свой класс от spark.components.Group, засунуть методы в него, и уже от него наследовать VG и HG? При этом теряются VGroup и HGroup и уже их код надо дублировать. Все плохо.
В некоторых языках программирования есть такие штуки, которые позволяют примешивать дополнительную логику к разным классам. Одну и ту же логику. Что-то типа интерфейсов, но с частичной реализацией. В скала такие штуки называются трейтами, в руби называются примесями.
В AS тоже можно сделать подобное воспользовавшись конструкцией include.
Выносим общий код в отдельный файл padd.as
// mix to classes VG and HG
public function set padd(value : String) : void
{
var values : Array = value.split(",");
if(values.length == 1)
{
paddingLeft = paddingTop = paddingRight = paddingBottom = validatePadd(values[0]);
}
else
{
paddingLeft = validatePadd(values[0]);
paddingTop = validatePadd(values[1]);
paddingRight = validatePadd(values[2]);
paddingBottom = validatePadd(values[3]);
}
}
private function validatePadd(value : String) : int
{
if(!value) return 0;
var res : int = parseInt(value);
if(isNaN(res)) return 0;
return res < 0 ? 0 : res;
}
и потом определяем классы HG и VG так:
package com.flashcoms.yzh.fext
{
import spark.components.VGroup;
public class VG extends VGroup
{
include "padd.as";
}
}
package com.flashcoms.yzh.fext
{
import spark.components.HGroup;
public class HG extends HGroup
{
include "padd.as";
}
}
И все. Теперь можете сжечь меня на костре, но по-моему это мило :) И еще радует, что Intellij IDEA вполне поддерживает такой код.
Comments
yzh44yzh
Sun, 01/09/2011 - 18:36
Permalink
Ересь продолжается
Вместо
width="100%" height="100%"
пишем
fill="true"
соотвественно трейт:
public function set fill(value : Boolean)
{
if(value)
{
percentWidth = 100;
percentHeight = 100;
}
else
{
percentWidth = NaN;
percentHeight = NaN;
}
}
примешиваем
public class VG extends VGroup
{
include "padd.as";
include "fill.as";
}
и можно примешать еще в 100500 других компонентов
yzh44yzh
Sun, 01/09/2011 - 18:37
Permalink
Обсуждение в жуйке
http://juick.com/yzh44yzh/996131
http://juick.com/yzh44yzh/996199
Anonymous (not verified)
Sun, 01/09/2011 - 18:38
Permalink
В Objective-C это более
В Objective-C это более правильно сделано, но всё равно радует, что подобное можно реализовать в AS, хотя то ещё извращение. (:
yzh44yzh
Sun, 01/09/2011 - 18:38
Permalink
Нашел весомый аргумент чтобы не использовать include.
include подключается по относительному пути относительно того файла, куда он будет подключаться. Пока оно все в одном каталоге, это не беда. Но вот если захочется подключить его в класс в другом пакете -- все жопа. Орудовать относительными путями смерти подобно. А если они не только в разных пакетах, но и в разных модулях, то это вообще невозможно.
Исходя из этого польза от include невелика. До трейтов тут далеко :)
Anonymous (not verified)
Sun, 01/09/2011 - 18:39
Permalink
Вроде подход выглядит как
Вроде подход выглядит как mixin/примесь, но не понятно, неужели удобнее чем просто создать копию обычной группы(ExtendedGroup) и от неё унаследовать VExtendedGroup, HExtendedGroup и т.д. Всё равно созданы два новых класса.
yzh44yzh
Sun, 01/09/2011 - 18:39
Permalink
При этом мы теряем функционал
При этом мы теряем функционал, уже реализованный в классах HGroup и VGroup, и нужно повторно его реализовать в своих кастомных классах.
Add new comment